Mailinglist Archive: opensuse-buildservice (273 mails)

< Previous Next >
[opensuse-buildservice] support for unified diffs
  • From: Marcus Hüwe <suse-tux@xxxxxx>
  • Date: Sun, 11 Jan 2009 23:15:46 +0100
  • Message-id: <20090111221546.GC3145@xxxxxxxxxxxxxxxxxxx>
Hi,

I wrote a small patch which adds support for unified diffs to the backend. At
the moment the diff between two revisions has an "unusual" format (at least I'm
not familiar with it). So it would like to add the option to get an unified,
svn-like diff. Here's a small example output:

marcus@linux:~> curl -0 -u Admin:opensuse -X POST
'http://127.0.42.2/source/home:Admin/foo?opackage=foo&oproject=home%3AAdmin&cmd=diff&rev=16&orev=15&expand=1&unified=1'
-d ''
Index: test.spec
===================================================================
--- test.spec (revision 15)
--- test.spec (revision 16)
@@ -41,4 +41,6 @@
%defattr(-, root, root)
# something
# added here
+%dir %{_datadir}/bar
%dir %{_datadir}/foo
+
Index: foo-bar.tar.bz2
===================================================================
Binary file foo-bar.tar.bz2 added
marcus@linux:~>

If there are no objections I would like to commit this change in the
next days.


Marcus
Index: BSSrcdiff.pm
===================================================================
--- BSSrcdiff.pm (Revision 6003)
+++ BSSrcdiff.pm (Arbeitskopie)
@@ -116,7 +116,7 @@
}

sub filediff {
- my ($f1, $f2, $p1, $p2, $max, $arg, $lcntp) = @_;
+ my ($f1, $f2, $p1, $p2, $max, $arg, $lcntp, $noarchive) = @_;
$arg ||= '-u';

return unless defined($f1) || defined($f2);
@@ -143,13 +143,14 @@
$lcnt = $$lcntp if $lcntp;
return '' if $f =~ /\.(?:zip|tar|jar|zoo)(?:\.gz|\.bz2)?$/;
local *F;
- if ($f =~ /\.gz$/i) {
- open(F, "-|", 'gunzip', '-dc', $f) || die("open $f: $!\n");
- } elsif ($f =~ /\.bz2$/i) {
- open(F, "-|", 'bzip2', '-dc', $f) || die("open $f: $!\n");
- } else {
- open(F, '<', $f) || die("open $f: $!\n");
+ if (!$noarchive) {
+ if ($f =~ /\.gz$/i) {
+ open(F, "-|", 'gunzip', '-dc', $f) || die("open $f: $!\n");
+ } elsif ($f =~ /\.bz2$/i) {
+ open(F, "-|", 'bzip2', '-dc', $f) || die("open $f: $!\n");
+ }
}
+ open(F, '<', $f) || die("open $f: $!\n") if !defined(fileno(F));
my $d = '';
$d .= "--- $p1\n";
$d .= "+++ $p2\n";
@@ -188,20 +189,20 @@
if (!$pid) {
local *F1;
local *F2;
- if ($f1 =~ /\.gz$/i) {
- open(F1, "-|", 'gunzip', '-dc', $f1) || die("open $f1: $!\n");
- } elsif ($f1 =~ /\.bz2$/i) {
- open(F1, "-|", 'bzip2', '-dc', $f1) || die("open $f1: $!\n");
- } else {
- open(F1, '<', $f1) || die("open $f1: $!\n");
+ if (!$noarchive) {
+ if ($f1 =~ /\.gz$/i) {
+ open(F1, "-|", 'gunzip', '-dc', $f1) || die("open $f1: $!\n");
+ } elsif ($f1 =~ /\.bz2$/i) {
+ open(F1, "-|", 'bzip2', '-dc', $f1) || die("open $f1: $!\n");
+ }
+ if ($f2 =~ /\.gz$/i) {
+ open(F2, "-|", 'gunzip', '-dc', $f2) || die("open $f2: $!\n");
+ } elsif ($f2 =~ /\.bz2$/i) {
+ open(F2, "-|", 'bzip2', '-dc', $f2) || die("open $f2: $!\n");
+ }
}
- if ($f2 =~ /\.gz$/i) {
- open(F2, "-|", 'gunzip', '-dc', $f2) || die("open $f2: $!\n");
- } elsif ($f2 =~ /\.bz2$/i) {
- open(F2, "-|", 'bzip2', '-dc', $f2) || die("open $f2: $!\n");
- } else {
- open(F2, '<', $f2) || die("open $f2: $!\n");
- }
+ open(F1, '<', $f1) || die("open $f1: $!\n") if !defined(fileno(F1));
+ open(F2, '<', $f2) || die("open $f2: $!\n") if !defined(fileno(F2));
fcntl(F1, F_SETFD, 0);
fcntl(F2, F_SETFD, 0);
exec 'diff', $arg, '/dev/fd/'.fileno(F1), '/dev/fd/'.fileno(F2);
@@ -532,4 +533,60 @@
return $d;
}

+sub ubeautify {
+ my ($d, $f, $orev, $rev) = @_;
+ $d =~ s/(--- \Q$f\E)$/$1 (revision \Q$orev\E)/m;
+ $d =~ s/((\+\+\+|---) \Q$f\E)$/$1 (revision \Q$rev\E)/m;
+ return $d;
+}
+
+sub udiff {
+ my ($pold, $old, $orev, $pnew, $new, $rev, $fmax) = @_;
+ my @changed;
+ my @added;
+ my @deleted;
+ my $d = '';
+ for (keys %$new) {
+ if (defined($old->{$_})) {
+ push @changed, $_ if $old->{$_} ne $new->{$_};
+ } else {
+ push @added, $_;
+ }
+ }
+ @deleted = grep { !defined($new->{$_}) } keys %$old;
+
+ my $hdr = "Index: %s\n" . "=" x 67 . "\n";
+ for my $f (@changed) {
+ $d .= sprintf($hdr, $f);
+ my $r .= filediff("$pold/$old->{$f}-$f", "$pnew/$new->{$f}-$f", $f, $f,
$fmax, undef, undef, 1);
+ $d .= ubeautify($r, $f, $orev, $rev);
+ }
+ for my $f (@added) {
+ $d .= sprintf($hdr, $f);
+ my $lcnt = -2;
+ my $r = filediff(undef, "$pnew/$new->{$f}-$f", $f, $f, $fmax, undef,
\$lcnt, 1);
+ $r =~ s/(\Q+++ $f\E)$/$1\n@@ -0,0 +1,\Q$lcnt\E @@/m;
+ $r = ubeautify($r, $f, 0, $rev);
+ $d .= $r eq '' ? "Binary file $f added\n" : $r;
+ }
+ for my $f (@deleted) {
+ $d .= sprintf($hdr, $f);
+ my $lcnt = -2;
+ my $r = filediff("$pold/$old->{$f}-$f", undef, $f, $f, $fmax, undef,
\$lcnt, 1);
+ $r =~ s/(\Q+++ $f\E)$/$1\n@@ -1,\Q$lcnt\E \+0,0 @@/m;
+ $r = ubeautify($r, $f, $orev, $rev);
+ $d .= $r eq '' ? "Binary file $f deleted\n" : $r if $lcnt;
+ }
+ return $d;
+}
+
+sub diff {
+ my ($pold, $old, $orev, $pnew, $new, $rev, $fmax, $tmax, $edir, $unified) =
@_;
+ if ($unified) {
+ return udiff($pold, $old, $orev, $pnew, $new, $rev, $fmax)
+ } else {
+ return srcdiff($pold, $old, $pnew, $new, $fmax, $tmax, $edir);
+ }
+}
+
1;
Index: bs_srcserver
===================================================================
--- bs_srcserver (Revision 6003)
+++ bs_srcserver (Arbeitskopie)
@@ -1752,7 +1752,7 @@
}
}
my $tmpdir = "$srcrep/:upload/srcdiff$$";
- my $d = BSSrcdiff::srcdiff("$srcrep/$opackid", $ofiles, "$srcrep/$packid",
$files, 200, 16000, $tmpdir);
+ my $d = BSSrcdiff::diff("$srcrep/$opackid", $ofiles, $orev->{'rev'},
"$srcrep/$packid", $files, $rev->{'rev'}, 200, 16000, $tmpdir,
$cgi->{'unified'});
return ($d, 'Content-Type: text/plain');
}

@@ -3295,7 +3295,7 @@
'DELETE:/source/$project/_pubkey' => \&deletekey,
'/source/$project/_config' => \&getprojectconfig,
'PUT:/source/$project/_config' => \&putprojectconfig,
- 'POST:/source/$project/$package cmd: rev? user:? comment:? orev:rev?
oproject:project? opackage:package? expand:bool? keeplink:bool?' => \&sourcecmd,
+ 'POST:/source/$project/$package cmd: rev? user:? comment:? orev:rev?
oproject:project? opackage:package? expand:bool? keeplink:bool? unified:bool?'
=> \&sourcecmd,
'PUT:/source/$project/$package cmd: rev? user:? comment:?' =>
\&sourcecommitfilelist,
'/source/$project/$package:package_pattern rev? expand:bool? view:?
extension:?' => \&getfilelist,
'/source/$project/$package:package_pattern/_history' => \&getpackagehistory,
< Previous Next >
This Thread
  • No further messages