Date: 7 Oct 1997
From: Jim Kingdon
Notes regarding this patch:
* The "log" link doesn't yet work. The intention is that it will show
the log entry for the particular revision being annotated. Right now
it just shows the entire log.
* The "ann" link for the 1.1 revision is not functional; it points to
a nonexistent revision 1.0 but it should be just omitting the link or
some such.
* The script requires that your history file be writable by "nobody"
(or whoever your web CGI scripts run as). This is probably not such a
great idea for production use on the internet. A real fix would
probably be to make CVS allow some readonly commands like annotate to
run without such write access.
* The rcsbinaries variable in the cvsweb script now may need to
contain a path to CVS too.
* The script uses
inside
which causes spurious blank lines,
at least in my browser, and should not be necessary.
* The script creates temporary directories such as /tmp/cvsweb1842
(where 1842 is the process ID of the script) and does not clean them
up. I suspect that one way to fix this and also make the whole
process much cleaner is to invoke "cvs server" and get the annotations
that way. I gather that Henner Zenner's hencvs (as of Oct 1998) does
this.
*** cvswebex 1997/09/28 14:40:53 1.1
--- cvswebex 1997/10/02 00:54:36
***************
*** 222,227 ****
--- 222,313 ----
close(RCS);
exit;
}
+ elsif (/ann=([\d\.]+)/) {
+ $rev = $1;
+ # Checking out the file just to annotate it is gross.
+ # Probably the clean way to handle
+ # it would be a "cvs rannotate" command or some such.
+ chdir "/tmp" or &fatal("500 Internal Error",
+ "Can't chdir to /tmp: $!");
+ mkdir "cvsweb$$",0700 or &fatal("500 Internal Error",
+ "Can't mkdir: $!");
+ chdir "cvsweb$$" or &fatal("500 Internal Error",
+ "Can't chdir: $!");
+ # FIXME: needs error checking
+ `cvs -d $cvsroot co $where`;
+ open(ANN, "cvs -q -d $cvsroot annotate -r$rev $where 2>&1 |") or
+ &fail("500 Internal Error", "Couldn't annotate: $!");
+ $_ = ;
+ if (/^Annotations for $where$/) {
+ # As expected
+ } else {
+ print "Status: 500 Internal Error\n";
+ print "Content-type: text/html\n";
+ print "\n";
+ print "Error \n";
+ print "Error: Unexpected output from annotate:";
+ print "
\n";
+ print "$_\n";
+ print ;
+ print "
\n";
+ exit(1);
+ }
+ $_ = ;
+ if (/^\*+$/) {
+ # As expected
+ } else {
+ &fatal("500 Internal Error",
+ "Unexpected output from annotate: $_");
+ }
+ print "Content-type: text/html\n\n";
+ print "CVS annotations for $where\n";
+ print "revision $rev \n";
+ print "\n";
+ print "\n";
+ print "CVS annotations for $where revision $rev
\n";
+ print "";
+ while () {
+ print "\n
";
+ if (m/^([\d\.]+) +\([^ ]+ +\d\d-[A-Z][a-z][a-z]-\d\d\): (.*)$/) {
+ $arev = $1;
+ $atext = $2;
+
+ for (1..8 - length ($arev)) { print " "; }
+ print "";
+ print "$arev ";
+
+ # "log" should be pointing to that specific log
+ # entry, I guess via adding "?log=1.46".
+ # The idea is that log can get you the author, the
+ # date, and other needed info, so you shouldn't
+ # need to see author and date here as with
+ # "cvs annotate". It is useful to get diffs, but
+ # they are a short way away with "log", so maybe it
+ # is OK.
+ print "log ";
+
+ # Now, the "ann" link, to show older annotations.
+ # So if arev is 1.44, we want 1.43.
+ $last = $arev;
+ $last =~ s/([\d\.]+\.)(\d+)/$2/;
+ $nonlast = $1;
+ $last -= 1;
+ $prev = $nonlast . $last;
+ print "ann:";
+ print &htmlify($atext);
+ print "\n";
+ } else {
+ # Output the error message instead of the text
+ # itself. That seems like the most friendly way.
+ print "cannot parse ";
+ print &htmlify($_);
+ print "\n";
+ }
+ }
+ print "\n";
+ close(ANN);
+ exit;
+ }
if (/r1=([^&:]+)(:([^&]+))?/) {
$rev1 = $1;
$sym1 = $3;
***************
*** 461,466 ****
--- 547,553 ----
# print "" . $author{$_} . "
\n";
print " " . &ctime($date{$_}) . " by ";
print "" . $author{$_} . "\n";
+ print "ann\n";
if ($revsym{$_}) {
# print "CVS Tags: $revsym{$_}
\n";
print "
CVS Tags: $revsym{$_}";