Author: sparky                       Date: Thu Aug  3 22:45:16 2006 GMT
Module: SPECS                         Tag: HEAD
---- Log message:
- NEW, helper for patch creation and updates

---- Files affected:
SPECS:
   patchtool.pl (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SPECS/patchtool.pl
diff -u /dev/null SPECS/patchtool.pl:1.1
--- /dev/null   Fri Aug  4 00:45:16 2006
+++ SPECS/patchtool.pl  Fri Aug  4 00:45:10 2006
@@ -0,0 +1,276 @@
+#!/usr/bin/perl
+#
+# Licensed under GPL
+# (c) 2006 PLD Linux Distribution
+#
+use strict;
+use warnings;
+
+my $spec = shift @ARGV or die "No spec file specified\n";
+my $patch_name = shift @ARGV || "";
+(my $pkgname = $spec) =~ s/\.spec$//;
+
+
+sub dml {
+       my $out;
+       $out .= "Work on existing patch:<br>\n";
+       $out .= "<menu id=existing_patch>\n";
+       foreach my $pn (sort keys %{$_[0]}) {
+               (my $patch = $_[0]->{$pn}) =~ s/_/__/g;
+               $out .= "<item id=$pn> $patch\n";
+       }
+       $out .= "</menu>\n";
+
+       $out .= "Create new: <br>\n";
+       $out .= "<input id=new_patch><br>\n";
+       $out .= "<button>";
+       
+       my $ret = undef;
+       open DML_IN, "-|", "dml", "-t", "sed to patch", "$out";
+       while (<DML_IN>) {
+               $ret = $1
+                       if not defined $ret and /existing_patch="([0-9]+)"/;
+               $ret = $1 if /new_patch="(.+)"/;
+       }
+       close DML_IN || die "child died\n";
+       return $ret;
+}
+
+my %patches = ();
+my $last_patch_num = -1;
+{
+       open F_IN, $spec or die "Can't open $spec: $!\n";
+       while (<F_IN>) {
+               chop;
+               last if $_ eq "\%description";
+               if ( /Patch([0-9]+):\s*(.*)/ ) {
+                       my $n = $1;
+                       ($patches{$n} = $2) =~ s/\%{name}/$pkgname/;
+                       $last_patch_num = $n if $n > $last_patch_num;
+               }
+       }
+       close F_IN;
+}
+
+my $patch = undef;
+my $patch_file = undef;
+my $patch_num = undef;
+do {
+       $patch = dml(\%patches);
+} until (defined $patch);
+
+
+print "D: patch '$patch'\n";
+if ($patch =~ /^([0-9]+)$/) {
+       print "D: existing patch\n";
+       $patch_num = $patch;
+       $patch_file = $patches{$patch_num};
+       ($patch = $patch_file) =~ s/\.(diff|patch)$//;
+       $patch =~ s/^$pkgname([-_]?)//;
+       die "Can't find $patch_file file.\n"
+               unless -r "../SOURCES/$patch_file";
+} else {
+       print "D: new patch\n";
+       $patch =~ s/\.(diff|patch)$//;
+       $patch =~ s/^$pkgname([-_])//;
+       $patch_file = "$pkgname-$patch.patch";
+       warn "File $patch_file already exists, using it.\n"
+               if -r "../SOURCES/$patch_file";
+       $patch_num = $last_patch_num + 1;
+}
+
+
+my $patch_opts = "";
+{      # create new spec file and temporary spec
+       open F_IN, $spec;
+       open F_OUT_TEMP, ">", "patchtool.spec";
+       open F_OUT_NEW, ">", "$spec.new";
+       sub print2($) {
+               print F_OUT_TEMP $_[0];
+               print F_OUT_NEW $_[0];
+       }
+       while (<F_IN>) {
+               last if /^Patch$patch_num:/;
+               if 
(/^(URL:|BuildRequires:|Requires|Provides:|Obsoletes:|BuildRoot:)/) {
+                       print F_OUT_NEW "Patch$patch_num:\t";
+                       print F_OUT_NEW "\t" if $patch_num < 10;
+                       print F_OUT_NEW "\%{name}-$patch.patch\n";
+                       last;
+               }
+               print2($_);
+       }
+       print2($_);
+
+       while (<F_IN>) {
+               print2($_);
+               last if /\%prep/;
+       }
+       my @buf = ();
+       sub flush_buf() {
+               while (my $l = shift @buf) {
+                       print2($l);
+               }
+       }
+       while (<F_IN>) {
+               flush_buf() if /^(#?\s*%?\%patch|\%setup)/;
+               push @buf, $_;
+
+               if (/^#?\s*%?\%patch$patch_num\s+(.*)/ or /^\%build/) {
+                       $patch_opts = $1 || "-p1";
+                       if (/^\%build/) {
+                               # print first buffer line, as it's %setup or 
%patch
+                               print2(shift @buf);
+                       } else {
+                               # avoid printing %patch twice
+                               shift @buf;
+                               flush_buf();
+                       }
+                       print F_OUT_TEMP "echo \$PWD > 
$ENV{PWD}/patchtool.srcdir\nexit 1\n";
+                       print F_OUT_NEW "\%patch$patch_num -p1\n";
+                       last;
+               }
+
+       }
+       flush_buf();
+       while (<F_IN>) {
+               print2($_);
+       }
+
+       close F_OUT_TEMP;
+       close F_OUT_NEW;
+       close F_IN;
+}
+
+unlink "patchtool.srcdir";
+system( qw(./builder -nn -bp patchtool.spec) );
+print "=============================================================\n";
+open F_IN, "patchtool.srcdir" or die;
+my $builddir = <F_IN>;
+close F_IN;
+die unless length $builddir;
+chomp $builddir;
+
+my $rpmSPECS = $ENV{PWD};
+(my $rpmBUILD = $builddir) =~ s#/BUILD/.*#/BUILD#;
+(my $srcdir = $builddir) =~ s#.*/BUILD/+##;
+$srcdir =~ s#/.*##;
+
+chdir $rpmBUILD;
+system("find '$srcdir' -name *.orig -or -name *~ -print0 | xargs -0 -r -l512 
rm -f");
+
+my $srcorig = $srcdir.".orig";
+my $srcpatch = $srcdir.".".$patch;
+system(qw(rm -rf), $srcorig);
+rename($srcdir, $srcorig);
+system(qw(rm -rf), $srcpatch);
+my @cp = (qw(cp -a), $srcorig, $srcpatch);
+system(@cp);
+die "Can't copy from $srcorig to $srcpatch: $!\n" if $?;
+
+quotemeta $srcdir;
+$builddir =~ s#$srcdir#$srcpatch#;
+chdir $builddir;
+
+if (-r "$rpmSPECS/../SOURCES/$patch_file") {
+       unless (length $patch_opts) {
+               print "trying to guess -pN option\n";
+               $patch_opts = "-p1";
+       }
+       system("patch $patch_opts < '$rpmSPECS/../SOURCES/$patch_file'");
+}
+
+sub diffcol {
+       $_ = $_[0];
+       chomp;
+       s//^[/g;
+       s//^G/g;
+       s/^(Index:|diff|---|\+\+\+) /$1 /;
+       s/^@@ /@@ /;
+       s/^-/-/;
+       s/^\+/+/;
+       s/
/^M/g;
+       #s/     /    /g;
+       s/(\S)(\s+)$/$1$2/;
+       s/$//;
+       print $_."\n";
+}
+
+sub make_patch() {
+       chdir $builddir;
+       system("find -name *.orig -or -name *~ -print0 | xargs -0 -r -l512 rm 
-f");
+       chdir $rpmBUILD;
+       system("diff -Nur '$srcorig' '$srcpatch' > 
'$rpmSPECS/../SOURCES/$patch_file'");
+}
+
+sub show_patch() {
+       open F_IN, "$rpmSPECS/../SOURCES/$patch_file";
+       while (<F_IN>) {
+               diffcol($_);
+       }
+       close F_IN;
+}
+
+sub compile() {
+       chdir $rpmSPECS;
+       system( qw(./builder -nn -bb), $spec.".new" );
+}
+
+sub finish() {
+       chdir $rpmSPECS;
+       rename $spec, $spec.".orig";
+       rename $spec.".new", $spec;
+}
+
+{      # prepare bashrc file
+       open F_OUT, ">", "$ENV{HOME}/.bash_patchtool"
+               or die "Can't create rc file: $!\n";
+       print F_OUT <<'EOF';
+if [ -f ~/.bash_profile ]; then
+       . ~/.bash_profile
+elif [ -f ~/.bashrc ]; then
+       . ~/.bashrc
+fi
+
+PS1='\[\033[1m\][\[\033[31m\]patchtool \[\033[34m\]\W\[\033[37m\]]$\[\033[0m\] 
'
+export PS1
+
+# allways return 0 on exit
+alias exit=":; exit"
+alias show="exit 133"
+alias compile="exit 134"
+alias finish="exit 135"
+alias quit="exit 136"
+cat << 'EOF'
+
+Commands:
+quit   - exit without applying changes
+finish - apply changes and exit
+compile        - apply changes and try to compile, don't exit
+show   - show resulting patch
+EOF
+       close F_OUT;
+}
+
+
+my $ret = 0;
+for (;;) {
+       chdir $builddir;
+       system(qw(bash --rcfile), $ENV{HOME}."/.bash_patchtool");
+       $ret = $?>>8;
+       redo if $ret == 0;
+       if ($ret == 133) { # show
+               make_patch();
+               show_patch();
+       } elsif ($ret == 134) { # compile
+               make_patch();
+               compile();
+       } elsif ($ret == 135) { # finish
+               make_patch();
+               finish();
+               exit 0;
+       } elsif ($ret == 136) { # quit
+               exit 0;
+       } else {
+               print "unrecognized return code: $ret\n";
+       }
+}
================================================================
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to