aboutsummaryrefslogtreecommitdiff
blob: 2e49ac0bbfe1954a2a7728c0747e432d50667992 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/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
#   12c12
#   < KEYWORDS="x86 ppc sparc"
#   ---
#   > KEYWORDS="x86 ppc sparc ~alpha"


my ($kw_re) = '^(?:([-~^]?)(\w[\w-]*)|([-^]\*))$';
my (@kw);

# make sure the cmdline consists of keywords and ebuilds
unless (@ARGV > 0) {
	die "syntax: ekeyword { arch | ~[arch] | -[arch] } ebuild...\n" 
}
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;

	while (<I>) {
		if (/^\s*KEYWORDS=/) {

			# extract the quoted section from KEYWORDS
			while (not /^KEYWORDS=["'].*?["']/) {
				chomp;
				my $next = <I>;
				$_ = join " ", $_, $next;
			}
			(my $quoted = $_) =~ s/^.*?["'](.*?)["'].*/$1/s;

			# 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 cmp $sb;
			} split " ", $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;

	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