need to recursively chown TOPDIR
[opensuse:build.git] / spec_add_patch
1 #!/usr/bin/perl -w
2 # vim:sw=4:et
3 # Author: Dirk Mueller
4
5 use strict;
6
7 my $diffname = $ARGV[0];
8 my $specname = $ARGV[1];
9
10 if (!defined($diffname) || ! -f $diffname) {
11
12     print "$0: <diffname>\n";
13     exit 1;
14 }
15
16 sub find_specfile()
17 {
18     opendir(D, ".");
19     my @specs = grep { /\.spec$/ } readdir(D);
20     closedir(D);
21
22     # choose the one with the shortest name (heuristic)
23     $specname = ( sort { length($a) - length($b) } @specs)[0];
24
25 }
26
27 if (!defined($specname) || ! -f $specname) {
28     &find_specfile();
29 }
30
31
32 open(S, "<$specname") or die;
33
34 my $ifdef_level = 0;
35 my $in_prep = 0;
36 my $in_global = 1;
37 my $last_patch_in_prep_index = 0;
38 my $last_patch_in_global_index = 0;
39 my $already_found_patch = 0;
40 my @c = ();
41 my $index = 0;
42
43 # first read the specfile, parse useful information
44 while(<S>)
45 {
46
47     if(/^\s*%\s*endif/) {
48         $ifdef_level--;
49         $last_patch_in_prep_index = $index if ($in_prep && $ifdef_level == 0);
50     }
51     die if ($ifdef_level < 0);
52     $ifdef_level++ if(/^\s*%\s*if/);
53
54     if ($ifdef_level == 0 && !$in_prep && $in_global
55         && /^\%(?:prep|build|install|package|description|doc)/) {
56         $in_global = 0;
57     }
58
59     if (!$in_prep && /^%prep/i) {
60         $in_prep = 1;
61         die if ($in_global);
62     }
63
64     if ($in_prep
65         && /^%setup\b/) {
66         $last_patch_in_prep_index = $index;
67     }
68
69     if ($in_prep
70         && /^\%(?:build|install|package|description|doc)/) {
71         $in_prep = 0;
72     }
73
74     die if (($in_prep + $in_global) > 1);
75
76     if ($in_global && /^Patch(?:\d+)?:/) {
77         $last_patch_in_global_index = $index;
78     }
79
80     if ($in_global && $ifdef_level == 0 && /^Source(?:\d+)?:/) {
81         $last_patch_in_global_index = $index;
82     }
83
84     if ($in_global && /^Patch.*?:\s+$diffname/) {
85         $already_found_patch = 1;
86     }
87
88     if ($in_prep && $ifdef_level == 0 && /^\%patch/) {
89         $last_patch_in_prep_index = $index;
90     }
91     push(@c, $_);
92     $index++;
93 }
94 close(S);
95
96 exit 0 if ($already_found_patch);
97
98 print "Adding patch $diffname to $specname\n";
99
100 die if ($ifdef_level > 0);
101 die if ($in_global || $in_prep);
102 die if ($last_patch_in_prep_index == 0);
103 die if ($last_patch_in_global_index == 0);
104
105 #print "adding Patch: $diffname to line $last_patch_in_global_index\n";
106 #print "adding %patch to line $last_patch_in_prep_index\n";
107
108 # determine patch number
109 my $patchnum = 0;
110 $patchnum = $1+1 if ($c[$last_patch_in_global_index] =~ /Patch(\d+):/);
111 $patchnum = 1 if ($c[$last_patch_in_global_index] =~ /Patch:/);
112
113 # determine strip level
114 my $striplevel = "";
115 open(P, "<$diffname") or die;
116 while(<P>) {
117     $striplevel = " -p1" if (m/^--- a/ or m/^--- [^\/]+-\d+\./);
118     last if (/^--- /);
119
120 }
121 close(P);
122
123
124 splice @c, $last_patch_in_prep_index+1, 0, ("\%patch$patchnum$striplevel\n");
125 splice @c, $last_patch_in_global_index+1, 0,
126     (sprintf "Patch%s:%s%s\n", $patchnum, ' ' x (10-length($patchnum)), $diffname);
127
128 open(O, ">$specname.new") or die;
129 print O @c;
130 close(O);
131
132 system("diff", "-u", $specname, "$specname.new");
133 rename("$specname.new", $specname);