e75ce933f4ff8a7f981f5e4ee6defa7c493e802f
[gentoolkit.git] / trunk / src / ekeyword / ekeyword
1 #!/usr/bin/perl -w
2 #
3 # Copyright 2003-2004, Gentoo Foundation
4 # Distributed under the terms of the GNU General Public License v2
5 # Written by Aron Griffis <agriffis@gentoo.org>
6 #
7 # ekeyword: Update the KEYWORDS in an ebuild.  For example:
8 #
9 #   $ ekeyword ~alpha oaf-0.6.8-r1.ebuild
10 #   12c12
11 #   < KEYWORDS="x86 ppc sparc"
12 #   ---
13 #   > KEYWORDS="x86 ppc sparc ~alpha"
14
15
16 my ($kw_re) = '^(?:([-~^]?)(\w[\w-]*)|([-^]\*))$';
17 my (@kw);
18
19 # make sure the cmdline consists of keywords and ebuilds
20 unless (@ARGV > 0) {
21     die "syntax: ekeyword { arch | ~[arch] | -[arch] } ebuild...\n" 
22 }
23 for my $a (@ARGV) {
24     $a = '~all' if $a eq '~' or $a eq $ENV{'HOME'};     # for vapier
25     next if $a =~ /$kw_re/o;                            # keyword
26     next if $a =~ /^\S+\.ebuild$/;                      # ebuild
27     die "I don't understand $a\n";
28 }
29
30 for my $f (@ARGV) {
31     if ($f =~ /$kw_re/o) {
32         push @kw, $f;
33         next;
34     }
35
36     print "$f\n";
37
38     open I, "<$f"       or die "Can't read $f: $!\n";
39     open O, ">$f.new"   or die "Can't create $f.new: $!\n";
40     select O;
41
42     while (<I>) {
43         /^KEYWORDS/ or print, next;
44
45         # extract the quoted section from KEYWORDS
46         (my $quoted = $_) =~ s/^.*?["'](.*?)["'].*/$1/s;
47
48         # replace -* with -STAR for our convenience below
49         $quoted =~ s/-\*/-STAR/;
50
51         for my $k (@kw) {
52             my ($leader, $arch, $star) = ($k =~ /$kw_re/o);
53
54             # handle -* and ^*
55             if (defined $star) {
56                 $leader = substr $star,0,1;
57                 $arch = 'STAR';
58             }
59
60             # remove keywords
61             if ($leader eq '^') {
62                 if ($arch eq 'all') {
63                     $quoted = '';
64                 } else {
65                     $quoted =~ s/[-~]?\Q$arch\E\b//;
66                 }
67             }
68
69             # add or modify keywords
70             else {
71                 if ($arch eq 'all') {
72                     # modify all non-masked keywords in the list
73                     $quoted =~ s/(^|\s)~?(?=\w)/$1$leader/g;
74                 } else {
75                     # modify or add keyword
76                     unless ($quoted =~ s/[-~]?\Q$arch\E(\s|$)/$leader$arch$1/) {
77                         # modification failed, need to add
78                         if ($arch eq 'STAR') {
79                             $quoted = "$leader$arch $quoted";
80                         } else {
81                             $quoted .= " $leader$arch";
82                         }
83                     }
84                 }
85             }
86         }
87
88         # replace -STAR with -*
89         $quoted =~ s/-STAR\b/-*/;
90
91         # sort keywords and fix spacing
92         $quoted = join " ", sort {
93             (my $sa = $a) =~ s/^\W//;
94             (my $sb = $b) =~ s/^\W//;
95             return -1 if $sa eq '*';
96             return +1 if $sb eq '*';
97             $sa cmp $sb;
98         } split " ", $quoted;
99
100         # re-insert quoted to KEYWORDS
101         s/(["']).*?["']/$1$quoted$1/;
102
103         print $_, <I> or die "Can't write $f.new: $!\n";
104     }
105
106     close I;
107     close O;
108     select STDOUT;
109
110     system "diff $f $f.new | grep -v '^[0-1]'";
111     rename "$f.new", "$f"       or die "Can't rename: $!\n";
112 }
113
114 # vim:ts=8 sw=4