head 1.3; access; symbols; locks; strict; comment @# @; 1.3 date 2006.10.25.15.35.51; author rse; state Exp; branches; next 1.2; commitid idg4kKjte0rwY4Sr; 1.2 date 2006.10.25.14.55.55; author rse; state Exp; branches; next 1.1; commitid KlcQ2srFVT1PK4Sr; 1.1 date 2006.10.25.14.45.54; author rse; state Exp; branches; next ; commitid rDf5vIr9EKsnH4Sr; desc @@ 1.3 log @fix dependencies and option parsing @ text @#!/usr/opkg/bin/perl ## ## editpkg.pl -- OpenPKG Tool Chain ## Copyright (c) 2000-2006 OpenPKG Foundation e.V. ## Copyright (c) 2000-2006 Ralf S. Engelschall ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## # System requirements: # - diff(1) # from OpenPKG "diffutils" # - less(1) # from OpenPKG "less" # Perl requirements: require 5.008; use File::Temp qw(tempdir tempfile); # from OpenPKG "perl" use Getopt::Long; # from OpenPKG "perl" use IO::All; # from OpenPKG "perl-sys" use Term::Prompt; # from OpenPKG "perl-term" use Date::Format; # from OpenPKG "perl-time" use Term::ANSIColor; # from OpenPKG "perl" # command line parsing my $opt = { -quiet => 0, -batch => 0, -force => 0, }; my $p = new Getopt::Long::Parser; $p->configure("bundling"); $p->configure("require_order"); my $result = $p->getoptions( 'q|quiet' => \$opt->{-quiet}, 'b|batch' => \$opt->{-batch}, 'm|manual' => \$opt->{-manual}, 'f|force' => \$opt->{-force}, ); if (@@ARGV == 0) { print(STDERR "Usage: $0 [-q|--quiet] [-b|--batch] [-f|--force] [-m|--manual] [ ...] [-- [ ...]]\n"); exit(1); } # determine commands and packages my @@cmd = (); my @@pkg = (); my $iscmd = 1; foreach my $arg (@@ARGV) { if ($iscmd and $arg eq '--') { $iscmd = 0; next; } if ($iscmd) { push(@@cmd, $arg); } else { push(@@pkg, $arg); } } if (@@pkg == 0) { foreach my $pkg (glob("*")) { next if (not -d $pkg or not -f "$pkg/$pkg.spec"); push(@@pkg, $pkg); } } # prepare a temporary directory my $tmpdir = tempdir(CLEANUP => 1); # helper function for colorizing "unified diff" output sub colorize_diff { my ($diff) = @@_; # expand tabs 1 while ($diff =~ s/\t/" " x (8 - ((length($`)-1) % 8))/se); # fix headers $diff =~ s/^---(\s+\S+\s+)/Index: $1\n---$1/omg; $diff =~ s/^(---)(\s+\S+\s+)([^\n]+\n)(\+\+\+)\s+\S+\s+/$1$2$3$4$2/omg; # colorize header $diff =~ s/^Index:\s+(\S+).*$/("_" x 78)."\n".color("bold white on_black")." $1 ".color("reset")/eomg; # colorize "unified diff" content $diff =~ s/^(@@@@.*$)/color("bold").$1.color("reset")/omge; $diff =~ s/^(\+.*)$/color("blue").$1.color("reset")/omge; $diff =~ s/^(\-.*)$/color("red").$1.color("reset")/omge; return $diff; } # iterate over all packages my $all = 0; foreach my $pkg (@@pkg) { printf("%s++ package $pkg%s\n", color('bold'), color('reset')) if (not $opt->{-quiet}); next if (not -d $pkg or not -f "$pkg/$pkg.spec"); # apply the content manipulation commands onto # the content of all packaging files my $content = {}; my $content_changed = 0; foreach my $file (sort grep { -f $_ } glob("$pkg/*")) { next if ($file =~ m/\.(bak|orig)$/); my $data < io($file); if (not defined($data)) { printf(STDERR "$0:WARNING: unable to read file \"$file\""); next; } $_ = $data; foreach $cmd (@@cmd) { eval $cmd; } $content->{$file} = { -old => $data, -new => $_ }; $content_changed = 1 if ($_ ne $data); } # in case the content was changed... if ($content_changed > 0 or $opt->{-force}) { # ...further adjust the Release header if (not $opt->{-manual}) { $content->{"$pkg/$pkg.spec"}->{-new} =~ s/(\nRelease:\s+)(\S+)/$1 . &update_release($2)/se; sub update_release { my ($release) = @@_; if ($release =~ m/^([A-Z]?)\d{8}(\S*)$/) { $release = sprintf("%s%s%s", $1, time2str("%Y%m%d", time()), $3); } elsif ($release =~ m/^([A-Z]?)(\d+)\.\d{8}(\S*)$/) { $release = sprintf("%s%s.%s%s", $1, $2, time2str("%Y%m%d", time()), $3); } elsif ($release =~ m/^([A-Z]?)(\d+\.\d+)\.(\d+)(\S*)$/) { $release = sprintf("%s%s.%d%s", $1, $2, $3 + 1, $4); } return $release; } } # show the resulting total difference if (not $opt->{-batch}) { my ($fh, $tmpfile1) = tempfile(DIR => $tmpdir); foreach my $file (sort keys %{$content}) { if ($content->{$file}->{-old} ne $content->{$file}->{-new}) { my ($fh, $tmpfile2) = tempfile(DIR => $tmpdir); $fh->print($content->{$file}->{-new}); $fh->close(); system("diff -u3 $file $tmpfile2 >>$tmpfile1"); } } my $diff < io($tmpfile1); $diff = colorize_diff($diff); if ($all) { print STDOUT $diff; } else { $diff > io("|less -E -r"); } } # ask for change confirmation if (not $opt->{-batch}) { if (not $opt->{-quiet}) { foreach my $file (sort keys %{$content}) { if ($content->{$file}->{-old} ne $content->{$file}->{-new}) { print(STDOUT "-- edit file $file (details see above)\n"); } } } my $query = $all ? "y" : undef; if (not defined $query) { $query = prompt("s", "-- apply editing permanently?", "a=all y=yes n=no q=quit", "n", sub { my ($query) = @@_; return ($query =~ m/[aynq]/s); }); } if ($query eq 'q') { printf(STDOUT "-- ".color("bold red")."CANCELLED".color("reset").", quit immediately.\n"); exit(0); } elsif ($query eq 'a') { $all = 1; $query = 'y'; } if ($query eq 'n') { printf(STDOUT "-- ".color("bold red")."SKIPPED".color("reset").", changes not applied.\n"); next; } } # apply the changes permanently foreach my $file (sort keys %{$content}) { if ($content->{$file}->{-old} ne $content->{$file}->{-new}) { print(STDOUT "-- save file $file\n") if (not $opt->{-quiet}); system("cp -p $file $file.orig"); $content->{$file}->{-new} > io($file); } } printf(STDOUT "-- ".color("bold blue")."OK".color("reset").", changes applied.\n") if (not $opt->{-quiet}); } } @ 1.2 log @allow us to disable the automatic changing of release header @ text @d27 2 a28 2 # - diff(1) # OpenPKG "diffutils" # - less(1) # OpenPKG "less" d32 6 a37 6 use File::Temp; # OpenPKG "perl" use Getopt::Long; # OpenPKG "perl" use IO::All; # OpenPKG "perl-sys" use Term::Prompt; # OpenPKG "perl-term" use Date::Format; # OpenPKG "perl-time" use Term::ANSIColor; # OpenPKG "perl" d47 1 @ 1.1 log @remember my hack of this afternoon: a new editpkg script which is an enhanced version of the old editspec script @ text @d50 1 d54 1 a54 1 print(STDERR "Usage: $0 [-q|--quiet] [-b|--batch] [-f|--force] [ ...] [-- [ ...]]\n"); d130 14 a143 11 $content->{"$pkg/$pkg.spec"}->{-new} =~ s/(\nRelease:\s+)(\S+)/$1 . &update_release($2)/se; sub update_release { my ($release) = @@_; if ($release =~ m/^([A-Z]?)\d{8}(\S*)$/) { $release = sprintf("%s%s%s", $1, time2str("%Y%m%d", time()), $3); } elsif ($release =~ m/^([A-Z]?)(\d+)\.\d{8}(\S*)$/) { $release = sprintf("%s%s.%s%s", $1, $2, time2str("%Y%m%d", time()), $3); } elsif ($release =~ m/^([A-Z]?)(\d+\.\d+)\.(\d+)(\S*)$/) { $release = sprintf("%s%s.%d%s", $1, $2, $3 + 1, $4); a144 1 return $release; @