X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FViewVCS.pm;h=5fd466106f96ae432038c4279bc6c00292c94456;hb=HEAD;hp=eae5b7f416cf88f8c35823dc5647ef01b0c415ca;hpb=d967c043322e636fd6ff810d54b70d8cd9fe91df;p=public-inbox.git diff --git a/lib/PublicInbox/ViewVCS.pm b/lib/PublicInbox/ViewVCS.pm index eae5b7f4..5fd46610 100644 --- a/lib/PublicInbox/ViewVCS.pm +++ b/lib/PublicInbox/ViewVCS.pm @@ -62,8 +62,11 @@ sub dbg_log ($) { return '
debug log seek error
'; } $log = do { local $/; <$log> } // do { - warn "readline(log): $!"; - return '
debug log read error
'; + if (!eof($log)) { + warn "readline(log): $!"; + return '
debug log read error
'; + } + ''; }; return '' if $log eq ''; $ctx->{-linkify} //= PublicInbox::Linkify->new; @@ -126,9 +129,9 @@ sub cmt_title { # git->cat_async callback } sub do_cat_async { - my ($ctx, $cb, @oids) = @_; + my ($ctx, $cb, @req) = @_; # favor git(1) over Gcf2 (libgit2) for SHA-256 support - $ctx->{git}->cat_async($_, $cb, $ctx) for @oids; + $ctx->{git}->cat_async($_, $cb, $ctx) for @req; if ($ctx->{env}->{'pi-httpd.async'}) { PublicInbox::GitAsyncCat::watch_cat($ctx->{git}); } else { # synchronous, generic PSGI @@ -136,6 +139,16 @@ sub do_cat_async { } } +sub do_check_async { + my ($ctx, $cb, @req) = @_; + if ($ctx->{env}->{'pi-httpd.async'}) { + async_check($ctx, $_, $cb, $ctx) for @req; + } else { # synchronous, generic PSGI + $ctx->{git}->check_async($_, $cb, $ctx) for @req; + $ctx->{git}->check_async_wait; + } +} + sub show_commit_start { # ->psgi_qx callback my ($bref, $ctx) = @_; if (my $qsp_err = delete $ctx->{-qsp_err}) { @@ -198,13 +211,15 @@ sub cmt_finalize { $au =~ s/>/>$x/; } $_ = ascii_html($_) for ($au, $co); + my $ibx_url = ibx_url_for($ctx) // $upfx; $au =~ s!(> +)([0-9]{4,}-\S+ \S+)! my ($gt, $t) = ($1, $2); $t =~ tr/ :-//d; qq($gt$2) !e; + $ctx->{-title_html} = $s = $ctx->{-linkify}->to_html($s); my ($P, $p, $pt) = delete @$ctx{qw(-cmt_P -cmt_p -cmt_pt)}; $_ = qq().shift(@$p).' '.shift(@$pt) for @$P; @@ -394,7 +409,7 @@ EOM $pfx = ''; $$bref .= qq[ (path unknown)\n]; } - my ($x, $m, $t, $oid, $sz, $f, $n); + my ($x, $m, $t, $oid, $sz, $f, $n, $gitlink); $$bref .= "\n size name"; for (@ent) { ($x, $f) = split(/\t/, $_, 2); @@ -405,6 +420,7 @@ EOM $n = ascii_html($f); if ($m eq 'g') { # gitlink submodule commit $$bref .= "\ng\t\t$n @ commit$oid"; + $gitlink = 1; next; } my $q = 'b='.ascii_html(uri_escape_path($pfx.$f)); @@ -415,17 +431,20 @@ EOM } $$bref .= dbg_log($ctx); $$bref .= <glossary +
glossary
 --------
 Tree objects belong to commits or other tree objects.  Trees may
-reference blobs, sub-trees, or commits of submodules.
+reference blobs, sub-trees, or (rarely) commits of submodules.
 
 Path names are stored in tree objects, but trees do not know
 their own path name.  A tree's path name comes from their parent tree,
 or it is the root tree referenced by a commit object.  Thus, this web UI
 relies on the `b=' URI parameter as a hint to display the path name.
+EOM
+
+	$$bref .= <Commit objects may be stored in trees to reference submodules.
@@ -482,18 +501,36 @@ sub show_tag ($$) { sub solve_result { my ($res, $ctx) = @_; my $hints = delete $ctx->{hints}; - $res or return html_page($ctx, 404, dbg_log($ctx)); - ref($res) eq 'ARRAY' or return html_page($ctx, 500, dbg_log($ctx)); + $res or return html_page($ctx, 404, 'Not found', dbg_log($ctx)); + ref($res) eq 'ARRAY' or + return html_page($ctx, 500, 'Internal error', dbg_log($ctx)); my ($git, $oid, $type, $size, $di) = @$res; return show_commit($ctx, $res) if $type eq 'commit'; return show_tree($ctx, $res) if $type eq 'tree'; return show_tag($ctx, $res) if $type eq 'tag'; return show_other($ctx, $res) if $type ne 'blob'; + my $fn = $di->{path_b} // $hints->{path_b}; my $paths = $ctx->{-paths} //= do { - my $path = to_filename($di->{path_b}//$hints->{path_b}//'blob'); + my $path = to_filename($fn // 'blob'); my $raw_more = qq[(raw)]; - [ $path, $raw_more ]; + my @def; + + # XXX not sure if this is the correct wording + if (defined($fn)) { + $raw_more .= qq( +name: ${\ascii_html($fn)} \t # note: path name is non-authoritative(*)); + $def[0] = "
" . +'(*) Git path names are given by the tree(s) the blob belongs to. + Blobs themselves have no identifier aside from the hash of its contents.'. +qq(^); + } + [ $path, $raw_more, @def ]; + }; + $ctx->{-q_value_html} //= do { + my $s = defined($fn) ? 'dfn:'.ascii_html($fn).' ' : ''; + $s.'dfpost:'.substr($oid, 0, 7); }; if ($size > $MAX_SIZE) { @@ -523,7 +560,7 @@ sub show_blob { # git->cat_async callback return delete($ctx->{-wcb})->([200, $h, [ $$blob ]]); } - my ($path, $raw_more) = @{delete $ctx->{-paths}}; + my ($path, $raw_more, @def) = @{delete $ctx->{-paths}}; $bin and return html_page($ctx, 200, "
blob $oid $size bytes (binary)" .
 				" $raw_more
".dbg_log($ctx)); @@ -550,7 +587,7 @@ sub show_blob { # git->cat_async callback $x .= '
 
'. # pad for non-CSS users ""; html_page($ctx, 200, $x, $ctx->{-linkify}->linkify_2($$blob), - ''.dbg_log($ctx)); + ''.dbg_log($ctx), @def); } # GET /$INBOX/$GIT_OBJECT_ID/s/ @@ -565,7 +602,10 @@ sub show ($$;$) { } $ctx->{fn} = $fn; $ctx->{-tmp} = File::Temp->newdir("solver.$oid_b-XXXX", TMPDIR => 1); - open $ctx->{lh}, '+>>', "$ctx->{-tmp}/solve.log" or die "open: $!"; + unless ($ctx->{lh}) { + open $ctx->{lh}, '+>>', "$ctx->{-tmp}/solve.log" or + die "open: $!"; + } my $solver = PublicInbox::SolverGit->new($ctx->{ibx}, \&solve_result, $ctx); $solver->{gits} //= [ $ctx->{git} ];