Commit | Line | Data |
---|---|---|
f83b5b07 MB |
1 | #!/pro/bin/perl |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use Cwd; | |
7 | use File::Find; | |
8 | ||
9 | my ($pfx, $pwd, $pc) = ("", (getcwd) x 2); | |
10 | $pwd =~ m/CPAN/ and ($pc, $pfx) = ("/pro/3gl/CPAN/perl-current", "perl/"); | |
11 | ||
12 | use Getopt::Long; | |
13 | my $opt_v = 1; # Verbosity | |
14 | my $opt_r = 0; # Revert instead of edit | |
15 | my $opt_p = -1; # Stript ## elements from path in patch | |
16 | GetOptions ( | |
17 | "v:1" => \$opt_v, | |
18 | "r" => \$opt_r, | |
19 | "p:1" => \$opt_p, | |
20 | ) or die "usage: patch2p4 [-r] patch [...]\n"; | |
21 | ||
22 | my %fqfn = ( null => "/dev/null" ); | |
23 | my $nfqfn = 0; | |
24 | find (sub { | |
25 | -f or return; # Only files | |
26 | my $f = $File::Find::name; | |
27 | $f =~ s{^$pc/}{$pfx}o; | |
28 | $opt_v > 4 and print STDERR "$f\n"; | |
29 | $fqfn{$f} = $f; | |
30 | ||
31 | $nfqfn++; | |
32 | my $x = $f; | |
33 | while ($x =~ s{^[^/]+/}{}) { | |
34 | if (exists $fqfn{$x} && !ref $fqfn{$x}) { | |
35 | $opt_v > 2 and warn "$f already in top-level. skipped\n"; | |
36 | next; | |
37 | } | |
38 | push @{$fqfn{$x}}, $f; | |
39 | } | |
40 | }, $pc); | |
41 | $opt_v and print STDERR "Tagged $nfqfn files\n"; | |
42 | ||
43 | my @p4f; | |
44 | my %chunk; | |
45 | my $old_file; | |
46 | while (<>) { | |
47 | m/^diff\b/ and next; | |
48 | m/$(=====================|Index: )/ and next; | |
49 | ||
50 | if (s{^--- }{}) { | |
51 | m{^(\S+).*1970\b.*00:00} and print STDERR "File $1 will be added!\n"; | |
52 | m{^/dev/null} and print STDERR "A new file will be added\n"; | |
53 | m{^([^/]\w\S+)} and $old_file = $1; | |
54 | next; | |
55 | } | |
56 | ||
57 | unless (m/^(?:\+\+\+|\*\*\*)\s+(\S+)/) { | |
58 | @p4f and push @{$chunk{$p4f[-1]}}, $_; | |
59 | next; | |
60 | } | |
61 | ||
62 | $1 eq "/dev/null" and print "\n\e[33;41;1m*** File $old_file is planned to be removed ***\e[0m\n\n"; | |
63 | ||
64 | @p4f && $p4f[-1] eq "${pfx}MANIFEST" and | |
65 | print STDERR +(grep m/^[-+]/, @{$chunk{$p4f[-1]}}), "\n"; | |
66 | ||
67 | # now check if the file exists | |
68 | my $f = $1; | |
69 | $f =~ m/^\d+,\d+$/ and next; # Grr, diff not -u | |
70 | ||
71 | if ($opt_p < 0) { | |
72 | my $ff = $f; | |
73 | do { | |
74 | $opt_p++; | |
75 | -f "$pfx$ff" and $ff = ""; | |
76 | } while $ff =~ s{^[^/]+/}{}; | |
77 | $opt_v > 1 and print STDERR "\$opt_p set to $opt_p\n"; | |
78 | } | |
79 | ||
80 | $f =~ s{^[^/]+/}{} for 1 .. $opt_p; | |
81 | -f "$pfx$f" and $f = "$pfx$f"; | |
82 | ||
83 | unless (exists $fqfn{$f}) { | |
84 | $opt_v and print STDERR "finding FQFN for $f ...\n"; | |
85 | while ($f =~ m{/} && !exists $fqfn{$f}) { | |
86 | $f =~ s{^[^/]*/}{}; | |
87 | } | |
88 | $f or die "No match for $f\n"; | |
89 | } | |
90 | ||
91 | my $x = $fqfn{$f}; | |
92 | #print STDERR "FQFN for '$f' = '", $x//"--undef--", "'\n"; | |
93 | if (ref $x) { | |
94 | my @f = @$x; | |
95 | @f == 0 and next; # Hmmm | |
96 | @f > 1 and die "$f matches (@f)\n"; | |
97 | $x = $f[0]; | |
98 | } | |
99 | $x eq "${pfx}MANIFEST" and print "\n\e[33;41;1m*** MANIFEST will be changed ***\e[0m\n\n"; | |
100 | $x eq "${pfx}embed.fnc" and print "\n\e[33;41;1m*** regen needed ***\e[0m\n\n"; | |
101 | push @p4f, $x; | |
102 | } | |
103 | ||
104 | if (@p4f) { | |
105 | $" = " "; | |
106 | my $action = $opt_r ? "revert" : "sedit"; | |
107 | s{^/dev/null$}{} for @p4f; | |
108 | print "p4 $action @p4f\n"; | |
109 | } |