From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 591781F463; Sat, 28 Dec 2019 09:17:18 +0000 (UTC) Date: Sat, 28 Dec 2019 09:17:18 +0000 From: Eric Wong To: meta@public-inbox.org Subject: Re: [PATCH 29/30] solvergit: allow passing arg to user-supplied callback Message-ID: <20191228091718.GA25646@dcvr> References: <20191225075104.22184-1-e@80x24.org> <20191225075104.22184-30-e@80x24.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20191225075104.22184-30-e@80x24.org> List-Id: Eric Wong wrote: > +++ b/lib/PublicInbox/SolverGit.pm > @@ -524,7 +527,7 @@ sub resolve_patch ($$) { > join("\n", $found_git->pub_urls($self->{psgi_env}))); > > if ($cur_want eq $self->{oid_want} || $type ne 'blob') { > - eval { delete($self->{user_cb})->($existing) }; > + eval { done_err($self, $existing) }; > die "E: $@" if $@; > return; > } > @@ -569,11 +572,12 @@ sub resolve_patch ($$) { > # this API is designed to avoid creating self-referential structures; > # so user_cb never references the SolverGit object I missed this in resolve_patch: eval { delete($self->{user_cb})->(undef) }; # not found! :< The following fixes it and adds a regression test: We need to test the non-'0'x40 error path explicitly, since I forgot to convert the {user_cb} invocation in resolve_patch() to handle {uarg} :x. diff --git a/lib/PublicInbox/SolverGit.pm b/lib/PublicInbox/SolverGit.pm index 117040a0..17a43060 100644 --- a/lib/PublicInbox/SolverGit.pm +++ b/lib/PublicInbox/SolverGit.pm @@ -55,16 +55,16 @@ sub dbg ($$) { print { $_[0]->{out} } $_[1], "\n" or ERR($_[0], "print(dbg): $!"); } -sub done_err ($$) { - my ($self, $err) = @_; +sub done ($$) { + my ($self, $res) = @_; my $ucb = delete($self->{user_cb}) or return; - $ucb->($err, $self->{uarg}); + $ucb->($res, $self->{uarg}); } sub ERR ($$) { my ($self, $err) = @_; print { $self->{out} } $err, "\n"; - eval { done_err($self, $err) }; + eval { done($self, $err) }; die $err; } @@ -316,23 +316,23 @@ sub extract_old_mode ($) { '100644'; } -sub do_finish ($$) { - my ($self, $user_cb) = @_; - my ($found, $oid_want, $uarg) = @$self{qw(found oid_want uarg)}; +sub do_finish ($) { + my ($self) = @_; + my ($found, $oid_want) = @$self{qw(found oid_want)}; if (my $exists = $found->{$oid_want}) { - return $user_cb->($exists, $uarg); + return done($self, $exists); } # let git disambiguate if oid_want was too short, # but long enough to be unambiguous: my $tmp_git = $self->{tmp_git}; if (my @res = $tmp_git->check($oid_want)) { - return $user_cb->($found->{$res[0]}, $uarg); + return done($self, $found->{$res[0]}); } if (my $err = $tmp_git->last_check_err) { dbg($self, $err); } - $user_cb->(undef, $uarg); + done($self, undef); } sub event_step ($) { @@ -356,8 +356,8 @@ sub event_step ($) { # our result: (which may be undef) # Other steps may call user_cb to terminate prematurely # on error - } elsif (my $user_cb = delete($self->{user_cb})) { - do_finish($self, $user_cb); + } elsif (exists $self->{user_cb}) { + do_finish($self); } else { die 'about to call user_cb twice'; # Oops :x } @@ -366,7 +366,7 @@ sub event_step ($) { if ($err) { $err =~ s/^\s*Exception:\s*//; # bad word to show users :P dbg($self, "E: $err"); - eval { done_err($self, $err) }; + eval { done($self, $err) }; } } @@ -527,7 +527,7 @@ sub resolve_patch ($$) { join("\n", $found_git->pub_urls($self->{psgi_env}))); if ($cur_want eq $self->{oid_want} || $type ne 'blob') { - eval { done_err($self, $existing) }; + eval { done($self, $existing) }; die "E: $@" if $@; return; } @@ -565,7 +565,7 @@ sub resolve_patch ($$) { } dbg($self, "could not find $cur_want"); - eval { delete($self->{user_cb})->(undef) }; # not found! :< + eval { done($self, undef) }; die "E: $@" if $@; } @@ -595,7 +595,7 @@ sub solve ($$$$$) { # should we even get here? Probably not, but somebody # could be manually typing URLs: - return done_err($self, undef) if $oid_want =~ /\A0+\z/; + return done($self, undef) if $oid_want =~ /\A0+\z/; $self->{oid_want} = $oid_want; $self->{out} = $out; diff --git a/t/solver_git.t b/t/solver_git.t index af5bf7bc..0c272d77 100644 --- a/t/solver_git.t +++ b/t/solver_git.t @@ -157,6 +157,7 @@ EOF close $cfgfh or die; my $cfg = PublicInbox::Config->new($cfgpath); my $www = PublicInbox::WWW->new($cfg); + my $non_existent = 'ee5e32211bf62ab6531bdf39b84b6920d0b6775a'; my $client = sub { my ($cb) = @_; my $res = $cb->(GET("/$name/3435775/s/")); @@ -165,6 +166,9 @@ EOF $res = $cb->(GET("/$name/".('0'x40).'/s/')); is($res->code, 404, 'failure with null OID'); + $res = $cb->(GET("/$name/$non_existent/s/")); + is($res->code, 404, 'failure with null OID'); + $res = $cb->(GET("/$name/$v1_0_0_tag/s/")); is($res->code, 200, 'shows commit'); while (my ($label, $size) = each %bin) {