Patch to cvsweb?

Bryce W Nesbitt bryce1 at obviously.com
Fri Nov 14 20:05:19 PST 2003


Ville Skyttä wrote:

>On Wed, 2003-11-12 at 20:48, Bryce Nesbitt (spam account) wrote:
>  
>
>>I am working with CVS HEAD.
>>My modified version is at:
>>    http://www.obviously.com/test/cvsweb.cgi/MassGIS/
>>
>>I implemented an external diff utility.  In this case, it
>>compares binary application files stored inside a .zip archive.
>>    
>>
>
>Whoo, looks cool.  Could you post the source code (or prefreably a
>unified diff against CVS HEAD) somewhere?
>  
>

This version, patched against CVS HEAD, can diff the
contents of a .zip archive.

You can also specify which "diff" utility to use for
which mime type:

     %DIFF_COMMANDS = (
         "application/arcview"      => "shpdiff",
         "application/vnd.ms-excel" => "excel_diff",
     );

There's more to do, but I hope this patch is a good start.

              -Bryce Nesbitt

-------------- next part --------------
? cvsroot_test
Index: cvsweb.cgi
===================================================================
RCS file: /home/ncvs/projects/cvsweb/cvsweb.cgi,v
retrieving revision 1.215
diff -u -r1.215 cvsweb.cgi
--- cvsweb.cgi	25 Oct 2003 19:16:32 -0000	1.215
+++ cvsweb.cgi	14 Nov 2003 22:41:10 -0000
@@ -62,7 +62,7 @@
   $VERSION
   $config $allow_version_select
   @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr
-  %MIRRORS %DEFAULTVALUE %ICONS %MTYPES
+  %MIRRORS %DEFAULTVALUE %ICONS %MTYPES %DIFF_COMMANDS %DIFF_OPTIONS
   @DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS
   %alltags %fileinfo %tags @branchnames %nameprinted
   %symrev %revsym @allrevisions %date %author @revdisplayorder
@@ -100,7 +100,7 @@
 use File::Spec::Functions qw(catdir catfile curdir devnull rootdir tmpdir
                              updir);
 use File::Temp            qw(tempdir);
-use IPC::Run              qw(finish timeout);
+#use IPC::Run              qw(finish timeout);  # Not on RedHat 7.3...
 use Time::Local           qw(timegm);
 use URI::Escape           qw(uri_escape uri_unescape);
 
@@ -2232,7 +2232,72 @@
   my @difftype       = @{$difftype->{'opts'}};
   my $human_readable = $difftype->{'colored'};
 
-  # apply special options
+
+  #######################################################################
+  # First, check if we need to uncompress a .zip archive
+  #
+  my $mimetype  = getMimeType($fullname);
+  my $cvsname   =  $where;
+
+  if( $mimetype eq "application/zip" ) {
+    http_header("text/plain");
+
+    # Create two temporary directories
+    my $tmpexportdir1 = tempdir('cvsweb1.XXXXXXXX', TMPDIR => 1);
+    my $tmpexportdir2 = tempdir('cvsweb2.XXXXXXXX', TMPDIR => 1);
+
+    # Check out and uncompress rev1
+    $cvsname =~ s/\.diff$//;
+    chdir($tmpexportdir1) or exit -1;
+    system ($CMD{cvs}, @cvs_options, '-Qd', $cvsroot, 'co', "-r$rev1", $cvsname);
+    system ($CMD{unzip}, $cvsname);
+
+    # Check out and uncompress rev2
+    $cvsname =~ s/\.diff$//;
+    chdir($tmpexportdir2) or exit -1;
+    system ($CMD{cvs}, @cvs_options, '-Qd', $cvsroot, 'co', "-r$rev2", $cvsname);
+    system ($CMD{unzip}, $cvsname);
+
+    # Examine each file, check if a special diffing command is defined in %DIFF_COMMANDS
+    # This is useful for comparing binary files (spreadsheets, images, etc) that
+    # don't work with standard text diff.
+    my $processed_something = 0;
+    my $fname;
+    my $diffutil;
+    opendir(DIR, $tmpexportdir1) or die "can't opendir $tmpexportdir1: $!";
+    while (defined($fname = readdir(DIR))) {
+        $mimetype  = getMimeType($fname);
+        #print "Saw file $fname | $mimetype\n";
+        if( $diffutil = $DIFF_COMMANDS{$mimetype} ) {
+            if( !defined $CMD{$diffutil} ) {
+               print "Error: can't find utility '$diffutil' to handle mimetype '$mimetype'\n";
+            }
+            if( $DIFF_OPTIONS{$mimetype} ne "" ) {
+                system($CMD{$diffutil}, $DIFF_OPTIONS{$mimetype}, 
+                       "$tmpexportdir1/$fname", "$tmpexportdir2/$fname");
+                $processed_something = 1;
+            } else {
+                system($CMD{$diffutil}, "$tmpexportdir1/$fname", "$tmpexportdir2/$fname");
+                $processed_something = 1;
+            }
+        }
+    }
+    closedir(DIR);
+
+    # If we did not diff anything above, then just do a standard "diff -r"
+    if( !$processed_something ) {
+        system ($CMD{diff}, "-r", "$tmpexportdir1", "$tmpexportdir2");
+    }
+    
+    # Delete temporary directories
+    system ($CMD{rm}, "-r", "$tmpexportdir1");
+    system ($CMD{rm}, "-r", "$tmpexportdir2");
+    exit;
+    }
+
+
+  #######################################################################
+  # regular diff: apply special options
   if ($showfunc) {
     push @difftype, '-p' if $f ne 's';
 
@@ -2322,7 +2387,7 @@
   # - Add "no differences found" if the diff command supplied no output.
   #
   #*** src/sys/netinet/tcp_output.c     1995/11/03 22:08:08     1.16
-  #--- src/sys/netinet/tcp_output.c     1995/12/05 17:46:35     1.17 RELENG_2_1_0
+  #--- src/sys/netinet/tcp_output.c     1995/12/05 17:46:35     1.17 REL_2_1_0
   # (bogus example, but...)
   #
   my ($f1, $f2);
@@ -2355,6 +2420,7 @@
 }
 
 
+
 ###############################
 # Show Logs ..
 ###############################
@@ -3106,8 +3172,8 @@
   print "<p>\n ";
   print &link($backicon, "$backurl#$filename"), " <b>Up to ",
     &clickablePath($upwhere, 1), "</b>\n</p>\n";
-  print "<p>\n ";
-  print &link('Request diff between arbitrary revisions', '#diff');
+  #print "<p>\n ";
+  #print &link('Request diff between arbitrary revisions', '#diff');
   if ($allow_cvsgraph) {
     print ' / ', &graph_link('', 'Display revisions graphically');
   }
Index: cvsweb.conf
===================================================================
RCS file: /home/ncvs/projects/cvsweb/cvsweb.conf,v
retrieving revision 1.64
diff -u -r1.64 cvsweb.conf
--- cvsweb.conf	30 Oct 2003 20:09:18 -0000	1.64
+++ cvsweb.conf	14 Nov 2003 22:41:11 -0000
@@ -24,7 +24,7 @@
 
 # Search the above directories for each command (prefer gtar over tar).
 #
-for (qw(cvs rlog rcsdiff gzip gtar zip cvsgraph enscript)) {
+for (qw(cvs rlog rcsdiff gzip gtar zip cvsgraph enscript unzip diff rm shpdiff)) {
 	$CMD{$_} = search_path($_);
 }
 $CMD{tar}   = delete($CMD{gtar}) if $CMD{gtar};
@@ -42,7 +42,7 @@
 # 'symbolic_name' => ['Name to display',  '/path/to/cvsroot']
 #
 @CVSrepositories = (
-        'local'   => ['Local Repository', '/home/cvs'],
+        'local'   => ['Local Repository', '/var/www/html/cvsweb/cvsroot_test'],
 #       'freebsd' => ['FreeBSD',          '/home/ncvs'],
 #       'openbsd' => ['OpenBSD',          '/home/ncvs'],
 #       'netbsd'  => ['NetBSD',           '/home/ncvs'],
@@ -318,6 +318,19 @@
 #
 $inputTextSize = 12;
 
+###########################################################################
+#   Custom diff type based on mime type
+#   (used for comparing binary files such as spreadhseets, images)
+#
+%DIFF_COMMANDS = (
+        "application/vnd.arcview"   => "shpdiff",
+        "application/vnd.ms-excel"  => "excel_diff",
+);
+%DIFF_OPTIONS = (
+        "application/vnd.arcview"   => "",
+        "application/vnd.ms-excel"  => "-vvv",
+);
+
 ##############
 # Mime Types
 ##############
@@ -343,8 +356,12 @@
 	"jpg"   => "image/jpeg",
 	"png"   => "image/png",
 	"xpm"   => "image/xpm",
+	"zip"   => "application/zip",
+	"shp"   => "application/vnd.arcview",
+	"xls"   => "application/vnd.ms-excel",
 #	"*"     => "text/plain",
 );
+
 
 # The traditional mime.types file, eg. the one from Apache is fine.
 # See above where this gets used.


More information about the freebsd-cvsweb mailing list