diff options
Diffstat (limited to 'gentoolkit-dev/src/ekeyword/ekeyword')
-rwxr-xr-x | gentoolkit-dev/src/ekeyword/ekeyword | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/gentoolkit-dev/src/ekeyword/ekeyword b/gentoolkit-dev/src/ekeyword/ekeyword new file mode 100755 index 0000000..e38801d --- /dev/null +++ b/gentoolkit-dev/src/ekeyword/ekeyword @@ -0,0 +1,147 @@ +#!/usr/bin/perl -w +# +# Copyright 2003-2009, Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# Written by Aron Griffis <agriffis@gentoo.org> +# +# ekeyword: Update the KEYWORDS in an ebuild. For example: +# +# $ ekeyword ~alpha oaf-0.6.8-r1.ebuild +# - ppc sparc x86 +# + ~alpha ppc sparc x86 + +my ($kw_re) = '^(?:([-~^]?)(\w[\w-]*)|([-^]\*))$'; +my (@kw); + +# make sure the cmdline consists of keywords and ebuilds +unless (@ARGV > 0) { + # NOTE: ~all will ignore all -arch keywords + print STDERR "syntax: ekeyword { arch | ~[arch] | -[arch] } ebuild...\n"; + print STDERR "instead of 'arch' you can also use 'all' which covers all existing keywords...\n"; + exit(1); +} +for my $a (@ARGV) { + $a = '~all' if $a eq '~' or $a eq $ENV{'HOME'}; # for vapier + next if $a =~ /$kw_re/o; # keyword + next if $a =~ /^\S+\.ebuild$/; # ebuild + die "I don't understand $a\n"; +} + +my $files = 0; +for my $f (@ARGV) { + if ($f =~ /$kw_re/o) { + push @kw, $f; + next; + } + + print "$f\n"; + + open I, "<$f" or die "Can't read $f: $!\n"; + open O, ">$f.new" or die "Can't create $f.new: $!\n"; + select O; + + my $keys_before; + my $keys_after; + while (<I>) { + if (/^\s*KEYWORDS=/) { + + # extract the quoted section from KEYWORDS + while (not /^\s*KEYWORDS=["'].*?["']/) { + chomp; + my $next = <I>; + $_ = join " ", $_, $next; + } + (my $quoted = $_) =~ s/^.*?["'](.*?)["'].*/$1/s; + $keys_before = $quoted; + + # replace -* with -STAR for our convenience below + $quoted =~ s/-\*/-STAR/; + + for my $k (@kw) { + my ($leader, $arch, $star) = ($k =~ /$kw_re/o); + + # handle -* and ^* + if (defined $star) { + $leader = substr $star,0,1; + $arch = 'STAR'; + } + + # remove keywords + if ($leader eq '^') { + if ($arch eq 'all') { + $quoted = ''; + } else { + $quoted =~ s/[-~]?\Q$arch\E\b//; + } + + # add or modify keywords + } else { + if ($arch eq 'all') { + # modify all non-masked keywords in the list + $quoted =~ s/(^|\s)~?(?=\w)/$1$leader/g; + } else { + # modify or add keyword + unless ($quoted =~ s/[-~]?\Q$arch\E(\s|$)/$leader$arch$1/) { + # modification failed, need to add + if ($arch eq 'STAR') { + $quoted = "$leader$arch $quoted"; + } else { + $quoted .= " $leader$arch"; + } + } + } + } + } + + # replace -STAR with -* + $quoted =~ s/-STAR\b/-*/; + + # sort keywords and fix spacing + $quoted = join " ", sort { + (my $sa = $a) =~ s/^\W//; + (my $sb = $b) =~ s/^\W//; + return -1 if $sa eq '*'; + return +1 if $sb eq '*'; + $sa .= "-"; + $sb .= "-"; + $sa =~ s/([a-z0-9]+)-([a-z0-9]*)/$2-$1/g; + $sb =~ s/([a-z0-9]+)-([a-z0-9]*)/$2-$1/g; + $sa cmp $sb; + } split " ", $quoted; + + $keys_after = $quoted; + + # re-insert quoted to KEYWORDS + s/(["']).*?["']/$1$quoted$1/; + + print $_ or die "Can't write $f.new: $!\n"; + } else { + print, next; + } + } + + close I; + close O; + select STDOUT; + + if ($keys_before ne $keys_after) { + # This gives uniform output, but actually seems to make + # it harder to pick out differences, and doesn't work so + # well when adding/removing keywords + #$keys_before =~ s/(^| )/ /g; + #$keys_before =~ s/ ([-~])/$1/g; + #$keys_after =~ s/(^| )/ /g; + #$keys_after =~ s/ ([-~])/$1/g; + print " - $keys_before\n + $keys_after\n"; + #system "diff -U 0 $f $f.new | sed -n -r 's:^(.)[[:space:]]*KEYWORDS=\"(.*)\": \\1 \\2:p'"; + #system "diff -U 0 $f $f.new | sed -n '/KEYWORDS=/s:^: :p'"; + } + rename "$f.new", "$f" or die "Can't rename: $!\n"; + $files++; +} + +if ($files == 0) { + die "No ebuilds processed!"; +} + +# vim:ts=4 sw=4 |