scripts/stableup: better reference handling
[opensuse:kernel-source.git] / scripts / stableup
1 #!/usr/bin/perl -w
2 use strict;
3 use File::Basename qq(basename);
4 use File::Copy qq(move);
5
6 my $tmpdir = $ENV{TMPDIR} || "/tmp";
7
8 die "Has to be run from the kernel-source GIT dir" if (! -d ".git");
9
10 if ($#ARGV != 1) {
11         print "Usage: $0 patch ids_file\n";
12         exit 1;
13 }
14
15 open(SERIES, "+<series.conf") || die "cannot open series.conf";
16 my $series;
17 my $series_changed = 0;
18 {
19         local $/;
20         $series = <SERIES>;
21 }
22
23 my $patch = $ARGV[0];
24 my $idsfile = $ARGV[1];
25 my $destdir = "patches.kernel.org/";
26 my $dest = $destdir . basename $patch;
27 mkdir $destdir if (! -d $destdir);
28
29 if (-f $patch && ! -f $dest) {
30         move $patch, $dest || die "cannot move $patch to $dest";
31         print "Moved $patch to $dest\n";
32         system("git add $dest");
33         print "Added $dest to GIT\n";
34         unless ($series =~ s/(latest standard kernel patches(?:\n[^\n]+)+\n)\n/$1\t$dest\n\n/) {
35                 die "cannot find a place in series.conf to add the patch";
36         }
37         $series_changed = 1;
38 }
39
40 open IDS, "<$idsfile" || die "cannot open $idsfile";
41 my $regexp = join "|", map { chomp; $_ } <IDS>;
42 close IDS;
43
44 my @references = ();
45 my %files;
46
47 if ($regexp eq "") {
48         print STDERR "empty regexp computed? Skipping patches removal...\n";
49 } else {
50
51         open GIT, "git grep -E '$regexp' patches.*|" ||
52                 die "cannot execute git";
53
54         my $tags = qr/(?:Git-commit: |Patch-mainline: |From )([0-9a-f]{40})/;
55
56         while (<GIT>) {
57                 chomp;
58                 next if (/patches\.kernel\.org\/patch-[0-9]/);
59                 /^([^:]+):($tags)?/;
60                 my $file = $1;
61                 # file may be deleted already
62                 if (defined $2 && -f $file) {
63                         open(PATCH, "<$file") || die "cannot open $file";
64                         my %shas = ();
65                         my @refs = ();
66                         while (my $line = <PATCH>) {
67                                 chomp $line;
68                                 $shas{$1} = 1 if ($line =~ /^$tags/);
69                                 if ($line =~ /^References: (.*)$/) {
70                                         push @refs, (split /[\s,]+/, $1);
71                                 }
72                         }
73                         close PATCH;
74                         if (scalar(keys %shas) == 1) {
75                                 push @references, @refs;
76                                 system("git rm $file");
77                                 $series =~ s/\t$file\n//;
78                                 $series_changed = 1;
79                         }
80                 }
81                 $files{$file} = 1;
82         }
83
84         close GIT;
85 }
86
87 if ($series_changed) {
88         seek(SERIES, 0, 0) || die "cannot seek series.conf";
89         truncate(SERIES, 0) || die "cannot truncate series.conf";
90         print SERIES $series;
91 }
92 close SERIES;
93
94 sub output_refs($@) {
95         my ($fh, @refs) = @_;
96         my %uniq = map { $_, 1 } @refs;
97         print $fh "References: ", join(' ', sort keys %uniq), "\n";
98 }
99
100 if (scalar @references) {
101         open DEST, "<$dest";
102         my @dest = <DEST>;
103         close DEST;
104         open DEST, ">$dest";
105         my $had_git_commit = 0;
106         foreach my $line (@dest) {
107                 if (!$had_git_commit && $line =~ /^Git-commit: /) {
108                         output_refs(\*DEST, @references);
109                         $had_git_commit = 1;
110                 } elsif ($line =~ /^References: (.*)$/) {
111                         chomp $1;
112                         push @references, (split /[\s,]+/, $1);
113                         output_refs(\*DEST, @references);
114                         next;
115                 }
116                 print DEST $line;
117         }
118         undef @dest;
119         close DEST;
120 }
121
122 foreach my $file (keys %files) {
123         if (-e $file) {
124                 system("git grep -E '$regexp' $file");
125         }
126 }
127
128 0;