From 3a849c8523decb0f477a7dbe237ade2ab53e948c Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 3 Jul 2004 21:20:11 +0000 Subject: [PATCH] Transformed shell script into perl script and improved it to allow diffs to depend on other diffs. Diffs are made locally now (not using cvs) which makes them faster as well as making the date header compatible with patch's -Z option (which we now use to avoid useless changes to the diff headers). Automatically exclude generated files from the diff (such as proto.h). --- verify-patches | 277 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 182 insertions(+), 95 deletions(-) diff --git a/verify-patches b/verify-patches index 6cc2c17..661f8a8 100755 --- a/verify-patches +++ b/verify-patches @@ -1,95 +1,182 @@ -#!/bin/sh - -[ -d patches ] && cd patches - -if [ ! -f verify-patches ]; then - echo "Please run this script from the root of the rsync dir" - echo "or from inside the patches subdir." - exit 1 -fi - -root=`cat ../CVS/Root` -tmpdir=,tmp-for-patch-tests - -[ -d $tmpdir ] || mkdir $tmpdir -cd $tmpdir || exit 1 - -[ -d workdir ] || mkdir workdir -echo "Using CVS to update the $tmpdir/cvsdir copy of the source." -cvs -d "$root" co -d cvsdir rsync - -cd workdir || exit 1 - -if [ -z "$1" ]; then - set -- ../../*.diff -fi - -for xx in "${@}"; do - case "$xx" in - *gzip-rsyncable.diff) continue ;; - patches/*) xx=`echo $xx | sed 's:patches:../..:'` ;; - */*.diff) ;; - *.diff) xx=../../$xx ;; - *) continue ;; - esac - apply=y - while : ; do - echo -e "\n----------- $xx ------------" - if [ $apply = y ]; then - rsync -a --delete ../cvsdir/ . - patch -p0 <$xx | tee ,patch.output - new='' - for nn in `sed -n 's/^patching file //p' ,patch.output`; do - [ -f ../cvsdir/$nn ] || new="$new $nn" - done - if grep "^Hunk #[0-9]* FAILED" ,patch.output >/dev/null; then - default=F - elif grep "^Hunk #[0-9]* succeeded" ,patch.output >/dev/null; then - default=E - else - default=N - fi - apply=n - fi - echo -e "\nFix rejects, Edit both diffs, Update patch," - echo -n "Apply patch again, Next, Quit: [$default] " - read ans - [ -z "$ans" ] && ans=$default - case "$ans" in - [Ee]*) - [ ! -z "$new" ] && cvs add $new - new='' - rm -f *.rej *.orig */*.rej */*.orig - sed '/^--- /,$ d' $xx >,new.patch - cvs diff -N | - egrep -v '^(diff -|===============|RCS file: |retrieving revision |Index: )' | - sed -e 's:^--- a/:--- :' -e 's:^+++ b/:+++ :' >>,new.patch - vim -d $xx ,new.patch - default=U - ;; - [Ff]*) - vim `sed -ne 's/.* saving rejects to file //p' ,patch.output` - default=E - ;; - [Uu]*) - if [ -f ,new.patch ]; then - cp -p ,new.patch $xx - echo -e "\nCopied ,new.patch to $xx" - default=A - else - echo -e "\n*** Edit the diffs first. ***" - default=E - fi - ;; - [Aa]*) - apply=y - ;; - [Nn]*) - break - ;; - [Qq]*) - exit 0 - ;; - esac - done -done +#!/usr/bin/perl + +use strict; + +chdir('patches') if -d 'patches'; + +if (!-f 'verify-patches') { + die <); +close IN; + +my $tmpdir = ',tmp-for-patch-tests'; + +mkdir($tmpdir, 0777) unless -d $tmpdir; +chdir($tmpdir) or die "Unable to chdir to $tmpdir"; + +mkdir('workdir') unless -d 'workdir'; +open(OUT, '>exclude') or die $!; +print OUT <) { + last if /^--- /; + if (/^Depends-On-Patch: (\S+.diff)$/) { + my $dep = $1; + $has_dependencies = 1; + print "\nApplying dependency patch $dep\n"; + if (system("patch -d cvsdir -p0 -b -Vt -Z <../$dep") != 0) { + print "Unable to cleanly apply depenency patch -- skipping $diff\n"; + &restore_cvsdir; + next DIFF; + } + } + } + close IN; + + my $apply = 1; + my(@rejects, $default); + while (1) { + print "\n----------- $diff ------------\n"; + if ($apply) { + undef @new; + $default = 'N'; + system "rsync -a --delete cvsdir/ workdir"; + open(IN, "patch -d workdir -p0 --no-backup-if-mismatch -Z <../$diff |") or die $!; + while () { + print $_; + chomp; + if (s/^patching file //) { + push(@new, $_) unless -f "cvsdir/$_"; + } elsif (s/.* saving rejects to file //) { + push(@rejects, $_); + } elsif (/^Hunk #\d+ FAILED/) { + $default = 'F'; + } elsif (/^Hunk #\d+ succeeded/) { + $default = 'E' unless $default eq 'F'; + } + } + close IN; + if ($default eq 'N') { + generate_new_patch($diff); + if (system("diff ../$diff new.patch >/dev/null") == 0) { + print "\n(New patch is identical to old.)\n"; + } + } + $apply = 0; + } + print "\nFix rejects, Edit both diffs, Update patch,\n", + "Apply patch again, Next, Quit: [$default] "; + my $ans = ; + chomp $ans; + $ans = $default unless $ans =~ s/^(\w)/$1/; + if ($ans =~ /E/i) { + generate_new_patch($diff); + chdir('workdir') or die $!; + system "vim -d ../../$diff ../new.patch"; + chdir('..') or die $!; + $default = 'U'; + } elsif ($ans =~ /F/i) { + chdir('workdir') or die $!; + system "vim @rejects"; + chdir('..') or die $!; + $default = 'E'; + } elsif ($ans =~ /U/i) { + system "cp -p new.patch ../$diff"; + print "\nUpdated $diff from new.patch\n"; + $default = 'A'; + } elsif ($ans =~ /A/i) { + $apply = 1; + } elsif ($ans =~ /N/i) { + last; + } elsif ($ans =~ /Q/i) { + exit; + } + } + + &restore_cvsdir; +} + +exit; + + +sub generate_new_patch +{ + my($diff) = @_; + + foreach (@new) { + system "touch -r workdir/$_ cvsdir/$_"; + } + open(IN, "../$diff") or die $!; + open(OUT, '>new.patch') or die $!; + while () { + last if /^--- /; + print OUT $_; + } + close IN; + open(IN, 'diff --exclude-from=exclude -upr cvsdir workdir |') or die $!; + while () { + next if /^(diff -|Index: |Only in )/; + s#^\Q--- cvsdir/\E#--- orig/#; + s#^\Q+++ workdir/\E#+++ #; + s#(\.000000000)? \+0000$##; + print OUT $_; + } + close IN; + close OUT; + foreach (@new) { + unlink("cvsdir/$_"); + } +} + +sub restore_cvsdir +{ + return unless $has_dependencies; + $has_dependencies = 0; + + foreach (glob('*.~[1-9]~'), glob('*/*.~[1-9]~')) { + my $fn; + ($fn = $_) =~ s/\.~1~$//; + if ($fn eq $_) { + unlink($_); + } elsif (-r $fn) { + rename($_, $fn); + } else { + unlink($_); + unlink($fn); + } + } +} -- 2.34.1