Commit | Line | Data |
---|---|---|
33e80a47 | 1 | #!/usr/bin/env perl |
418f4069 | 2 | |
c5e3e317 JL |
3 | =head1 NAME |
4 | ||
f703fc96 | 5 | Porting/sync-with-cpan - Synchronize with CPAN distributions |
c5e3e317 JL |
6 | |
7 | =head1 SYNOPSIS | |
8 | ||
9 | perl Porting/sync-with-cpan <module> | |
10 | ||
11 | where <module> is the name it appears in the C<%Modules> hash | |
12 | of F<Porting/Maintainers.pl> | |
13 | ||
14 | =head1 DESCRIPTION | |
15 | ||
16 | Script to help out with syncing cpan distros. | |
17 | ||
18 | Does the following: | |
19 | ||
20 | =over 4 | |
21 | ||
22 | =item * | |
23 | ||
24 | Fetches the package list from CPAN. Finds the current version of the given | |
25 | package. [1] | |
26 | ||
27 | =item * | |
28 | ||
29 | Downloads the relevant tarball; unpacks the tarball. [1] | |
30 | ||
31 | =item * | |
32 | ||
33 | Clean out the old directory (C<git clean -dfx>) | |
34 | ||
35 | =item * | |
36 | ||
37 | Moves the old directory out of the way, moves the new directory in place. | |
38 | ||
39 | =item * | |
40 | ||
41 | Restores any F<.gitignore> file. | |
42 | ||
43 | =item * | |
44 | ||
45 | Removes files from C<@IGNORE> and C<EXCLUDED> | |
46 | ||
47 | =item * | |
48 | ||
49 | C<git add> any new files. | |
50 | ||
51 | =item * | |
52 | ||
53 | C<git rm> any files that are gone. | |
54 | ||
55 | =item * | |
56 | ||
57 | Remove the +x bit on files in F<t/> | |
58 | ||
59 | =item * | |
60 | ||
61 | Remove the +x bit on files that don't have it enabled in the current dir | |
62 | ||
63 | =item * | |
64 | ||
65 | Restore files mentioned in C<CUSTOMIZED> | |
66 | ||
67 | =item * | |
68 | ||
190c1b3b | 69 | Updates the contents of F<MANIFEST> |
c5e3e317 JL |
70 | |
71 | =item * | |
72 | ||
73 | Runs a C<make> (assumes a configure has been run) | |
74 | ||
75 | =item * | |
76 | ||
77 | Cleans up | |
78 | ||
79 | =item * | |
80 | ||
81 | Runs tests for the package | |
82 | ||
83 | =item * | |
84 | ||
85 | Runs the porting tests | |
86 | ||
87 | =back | |
88 | ||
89 | [1] If the C<--tarball> option is given, then CPAN is not consulted. | |
90 | C<--tarball> should be the path to the tarball; the version is extracted | |
91 | from the filename -- but can be overwritten by the C<--version> option. | |
92 | ||
b7078f1e AC |
93 | =head1 OPTIONS |
94 | ||
95 | =over 4 | |
96 | ||
97 | =item C<--jobs> I<N> | |
98 | ||
99 | When running C<make>, pass a C<< -jI<N> >> option to it. | |
100 | ||
101 | =back | |
102 | ||
c5e3e317 JL |
103 | =head1 TODO |
104 | ||
105 | =over 4 | |
106 | ||
107 | =item * | |
108 | ||
c5e3e317 JL |
109 | Update F<Porting/Maintainers.pl> |
110 | ||
111 | =item * | |
112 | ||
113 | Optional, run a full test suite | |
114 | ||
115 | =item * | |
116 | ||
117 | Handle complicated C<FILES> | |
118 | ||
119 | =back | |
120 | ||
121 | This is an initial version; no attempt has been made yet to make this | |
122 | portable. It shells out instead of trying to find a Perl solution. | |
cd9a1714 | 123 | In particular, it assumes git, perl, and make |
c5e3e317 JL |
124 | to be available. |
125 | ||
126 | =cut | |
127 | ||
418f4069 | 128 | |
4d18e0a2 A |
129 | package Maintainers; |
130 | ||
418f4069 A |
131 | use 5.010; |
132 | ||
133 | use strict; | |
134 | use warnings; | |
4d18e0a2 | 135 | use Getopt::Long; |
a1450e8b | 136 | use Archive::Tar; |
192f56b0 | 137 | use File::Path qw( remove_tree ); |
fc134225 | 138 | use File::Find; |
af8c53c3 | 139 | use File::Spec::Functions qw( tmpdir ); |
160daab8 | 140 | use Config qw( %Config ); |
418f4069 A |
141 | |
142 | $| = 1; | |
143 | ||
215d9c65 AC |
144 | use constant WIN32 => $^O eq 'MSWin32'; |
145 | ||
07a826df | 146 | die "This does not look like a top level directory" |
418f4069 A |
147 | unless -d "cpan" && -d "Porting"; |
148 | ||
4b760246 AC |
149 | # Check that there's a Makefile, if needed; otherwise, we'll do most of our |
150 | # work only to fail when we try to run make, and the user will have to | |
151 | # either unpick everything we've done, or do the rest manually. | |
152 | die "Please run Configure before using $0\n" | |
153 | if !WIN32 && !-f "Makefile"; | |
154 | ||
418f4069 A |
155 | our @IGNORABLE; |
156 | our %Modules; | |
157 | ||
158 | use autodie; | |
159 | ||
160 | require "Porting/Maintainers.pl"; | |
161 | ||
e6e4cae9 AC |
162 | my $MAKE_LOG = 'make.log'; |
163 | ||
418f4069 A |
164 | my %IGNORABLE = map {$_ => 1} @IGNORABLE; |
165 | ||
af8c53c3 | 166 | my $tmpdir = tmpdir(); |
fc134225 | 167 | |
418f4069 A |
168 | my $package = "02packages.details.txt"; |
169 | my $package_url = "http://www.cpan.org/modules/$package"; | |
fc134225 | 170 | my $package_file = "$tmpdir/$package"; # this is a cache |
418f4069 | 171 | |
b7e2b692 JL |
172 | my @problematic = ( |
173 | 'podlators', # weird CUSTOMIZED section due to .PL files | |
174 | ); | |
175 | ||
418f4069 | 176 | |
311454c0 MB |
177 | sub usage |
178 | { | |
179 | my $err = shift and select STDERR; | |
180 | print "Usage: $0 module [args] [cpan package]\n"; | |
181 | exit $err; | |
182 | } | |
183 | ||
4d18e0a2 | 184 | GetOptions ('tarball=s' => \my $tarball, |
b5bf278a | 185 | 'version=s' => \my $version, |
b7078f1e | 186 | 'jobs=i' => \my $make_jobs, |
311454c0 MB |
187 | force => \my $force, |
188 | help => sub { usage 0; }, | |
189 | ) or die "Failed to parse arguments"; | |
4d18e0a2 | 190 | |
311454c0 | 191 | usage 1 unless @ARGV == 1 || @ARGV == 2; |
418f4069 | 192 | |
fc134225 MM |
193 | sub find_type_f { |
194 | my @res; | |
195 | find( { no_chdir => 1, wanted => sub { | |
196 | my $file= $File::Find::name; | |
197 | return unless -f $file; | |
198 | push @res, $file | |
199 | }}, @_ ); | |
200 | @res | |
201 | }; | |
202 | ||
cd9a1714 MM |
203 | # Equivalent of `chmod a-x` |
204 | sub de_exec { | |
205 | for my $filename ( @_ ) { | |
206 | my $mode= (stat $filename)[2] & 0777; | |
207 | if( $mode & 0111 ) { # exec-bit set | |
208 | chmod $mode & 0666, $filename; | |
209 | }; | |
210 | } | |
211 | } | |
212 | ||
213 | sub make { | |
160daab8 | 214 | my @args= @_; |
b7078f1e | 215 | unshift @args, "-j$make_jobs" if defined $make_jobs; |
215d9c65 | 216 | if (WIN32) { |
160daab8 | 217 | chdir "Win32"; |
e6e4cae9 AC |
218 | system "$Config{make} @args> ..\\$MAKE_LOG 2>&1" |
219 | and die "Running make failed, see $MAKE_LOG"; | |
160daab8 MM |
220 | chdir '..'; |
221 | } else { | |
e6e4cae9 AC |
222 | system "$Config{make} @args> $MAKE_LOG 2>&1" |
223 | and die "Running make failed, see $MAKE_LOG"; | |
160daab8 MM |
224 | }; |
225 | }; | |
226 | ||
5b73aae5 | 227 | my ($module) = shift; |
418f4069 | 228 | |
24c7e242 AC |
229 | my $info = $Modules{$module}; |
230 | if (!$info) { | |
231 | # Maybe the user said "Test-Simple" instead of "Test::Simple". See if we | |
232 | # can fix it up. | |
233 | (my $guess = $module) =~ s/-/::/g; | |
234 | $info = $Modules{$guess} | |
235 | or die "Cannot find module $module"; | |
236 | say "Guessing you meant $guess instead of $module"; | |
237 | $module = $guess; | |
238 | } | |
239 | ||
240 | my $cpan_mod = @ARGV ? shift : $module; | |
4d18e0a2 | 241 | |
418f4069 | 242 | my $distribution = $$info {DISTRIBUTION}; |
b5bf278a A |
243 | |
244 | my @files = glob $$info {FILES}; | |
b7e2b692 | 245 | if (!-d $files [0] || grep { $_ eq $module } @problematic) { |
b5bf278a A |
246 | say "This looks like a setup $0 cannot handle (yet)"; |
247 | unless ($force) { | |
248 | say "Will not continue without a --force option"; | |
249 | exit 1; | |
250 | } | |
251 | say "--force is in effect, so we'll soldier on. Wish me luck!"; | |
252 | } | |
253 | ||
254 | ||
255 | chdir "cpan"; | |
256 | ||
83d3dd1d | 257 | my $pkg_dir = $files[0]; |
418f4069 A |
258 | $pkg_dir =~ s!.*/!!; |
259 | ||
87a7cbad | 260 | my ($old_version) = $distribution =~ /-([0-9.]+(?:-TRIAL[0-9]*)?)\.tar\.gz/; |
418f4069 A |
261 | |
262 | my $o_module = $module; | |
5b73aae5 A |
263 | if ($cpan_mod =~ /-/ && $cpan_mod !~ /::/) { |
264 | $cpan_mod =~ s/-/::/g; | |
418f4069 A |
265 | } |
266 | ||
267 | # | |
268 | # Find the information from CPAN. | |
269 | # | |
4d18e0a2 A |
270 | my $new_file; |
271 | my $new_version; | |
272 | unless ($tarball) { | |
273 | # | |
274 | # Poor man's cache | |
275 | # | |
276 | unless (-f $package_file && -M $package_file < 1) { | |
132246f2 MM |
277 | eval { |
278 | require HTTP::Tiny; | |
279 | my $http= HTTP::Tiny->new(); | |
280 | $http->mirror( $package_url => $package_file ); | |
281 | 1 | |
282 | } or system wget => $package_url, '-qO', $package_file; | |
4d18e0a2 A |
283 | } |
284 | ||
cefd15c2 MM |
285 | open my $fh, '<', $package_file; |
286 | (my $new_line) = grep {/^$cpan_mod/} <$fh> # Yes, this needs a lot of memory | |
4d18e0a2 | 287 | or die "Cannot find $cpan_mod on CPAN\n"; |
4d18e0a2 | 288 | (undef, $new_version, my $new_path) = split ' ', $new_line; |
3a4316cc JL |
289 | if (defined $version) { |
290 | $new_path =~ s/-$new_version\./-$version\./; | |
291 | $new_version = $version; | |
292 | } | |
4d18e0a2 A |
293 | $new_file = (split '/', $new_path) [-1]; |
294 | ||
295 | my $url = "http://search.cpan.org/CPAN/authors/id/$new_path"; | |
296 | say "Fetching $url"; | |
297 | # | |
298 | # Fetch the new distro | |
299 | # | |
132246f2 MM |
300 | eval { |
301 | require HTTP::Tiny; | |
302 | my $http= HTTP::Tiny->new(); | |
303 | $http->mirror( $url => $new_file ); | |
304 | 1 | |
305 | } or system wget => $url, '-qO', $new_file; | |
4d18e0a2 A |
306 | } |
307 | else { | |
308 | $new_file = $tarball; | |
87a7cbad | 309 | $new_version = $version // ($new_file =~ /-([0-9._]+(?:-TRIAL[0-9]*)?)\.tar\.gz/) [0]; |
4d18e0a2 | 310 | } |
418f4069 A |
311 | |
312 | my $old_dir = "$pkg_dir-$old_version"; | |
418f4069 A |
313 | |
314 | say "Cleaning out old directory"; | |
315 | system git => 'clean', '-dfxq', $pkg_dir; | |
316 | ||
418f4069 | 317 | say "Unpacking $new_file"; |
5fb91d48 | 318 | Archive::Tar->extract_archive( $new_file ); |
418f4069 | 319 | |
618ac2f6 | 320 | (my $new_dir = $new_file) =~ s/\.tar\.gz//; |
3f7808eb | 321 | # ensure 'make' will update all files |
fc134225 MM |
322 | my $t= time; |
323 | for my $file (find_type_f($new_dir)) { | |
1ae6ead9 | 324 | open(my $fh,'>>',$file) || die "Cannot write $file:$!"; |
fc134225 MM |
325 | close($fh); |
326 | utime($t,$t,$file); | |
327 | }; | |
418f4069 A |
328 | |
329 | say "Renaming directories"; | |
330 | rename $pkg_dir => $old_dir; | |
418f4069 | 331 | |
83d3dd1d JL |
332 | say "Creating new package directory"; |
333 | mkdir $pkg_dir; | |
334 | ||
335 | say "Populating new package directory"; | |
336 | my $map = $$info {MAP}; | |
337 | my @EXCLUDED_QR; | |
338 | my %EXCLUDED_QQ; | |
339 | if ($$info {EXCLUDED}) { | |
340 | foreach my $entry (@{$$info {EXCLUDED}}) { | |
341 | if (ref $entry) {push @EXCLUDED_QR => $entry} | |
342 | else {$EXCLUDED_QQ {$entry} = 1} | |
343 | } | |
344 | } | |
345 | ||
fc134225 | 346 | FILE: for my $file ( find_type_f( $new_dir )) { |
83d3dd1d JL |
347 | my $old_file = $file; |
348 | $file =~ s{^$new_dir/}{}; | |
349 | ||
350 | next if $EXCLUDED_QQ{$file}; | |
351 | for my $qr (@EXCLUDED_QR) { | |
352 | next FILE if $file =~ $qr; | |
353 | } | |
354 | ||
355 | if ( $map ) { | |
356 | for my $key ( sort { length $b <=> length $a } keys %$map ) { | |
357 | my $val = $map->{$key}; | |
358 | last if $file =~ s/^$key/$val/; | |
359 | } | |
360 | } | |
7bbb137d JL |
361 | else { |
362 | $file = $files[0] . '/' . $file; | |
363 | } | |
83d3dd1d JL |
364 | |
365 | if ( $file =~ m{^cpan/} ) { | |
366 | $file =~ s{^cpan/}{}; | |
367 | } | |
368 | else { | |
369 | $file = '../' . $file; | |
370 | } | |
371 | ||
372 | my $prefix = ''; | |
373 | my @parts = split '/', $file; | |
374 | pop @parts; | |
375 | for my $part (@parts) { | |
376 | $prefix .= '/' if $prefix; | |
377 | $prefix .= $part; | |
378 | mkdir $prefix unless -d $prefix; | |
379 | } | |
380 | ||
381 | rename $old_file => $file; | |
382 | } | |
192f56b0 | 383 | remove_tree( $new_dir ); |
418f4069 A |
384 | |
385 | if (-f "$old_dir/.gitignore") { | |
386 | say "Restoring .gitignore"; | |
387 | system git => 'checkout', "$pkg_dir/.gitignore"; | |
388 | } | |
389 | ||
fc134225 | 390 | my @new_files = find_type_f( $pkg_dir ); |
418f4069 A |
391 | @new_files = grep {$_ ne $pkg_dir} @new_files; |
392 | s!^[^/]+/!! for @new_files; | |
393 | my %new_files = map {$_ => 1} @new_files; | |
394 | ||
fc134225 | 395 | my @old_files = find_type_f( $old_dir ); |
418f4069 A |
396 | @old_files = grep {$_ ne $old_dir} @old_files; |
397 | s!^[^/]+/!! for @old_files; | |
398 | my %old_files = map {$_ => 1} @old_files; | |
399 | ||
418f4069 A |
400 | my @delete; |
401 | my @commit; | |
402 | my @gone; | |
418f4069 A |
403 | FILE: |
404 | foreach my $file (@new_files) { | |
405 | next if -d "$pkg_dir/$file"; # Ignore directories. | |
406 | next if $old_files {$file}; # It's already there. | |
407 | if ($IGNORABLE {$file}) { | |
408 | push @delete => $file; | |
409 | next; | |
410 | } | |
418f4069 A |
411 | push @commit => $file; |
412 | } | |
413 | foreach my $file (@old_files) { | |
414 | next if -d "$old_dir/$file"; | |
415 | next if $new_files {$file}; | |
416 | push @gone => $file; | |
417 | } | |
ad9b4e6f A |
418 | |
419 | # | |
420 | # Find all files with an exec bit | |
421 | # | |
fc134225 | 422 | my @exec = find_type_f( $pkg_dir ); |
ad9b4e6f A |
423 | my @de_exec; |
424 | foreach my $file (@exec) { | |
425 | # Remove leading dir | |
426 | $file =~ s!^[^/]+/!!; | |
427 | if ($file =~ m!^t/!) { | |
428 | push @de_exec => $file; | |
429 | next; | |
430 | } | |
431 | # Check to see if the file exists; if it doesn't and doesn't have | |
432 | # the exec bit, remove it. | |
433 | if ($old_files {$file}) { | |
434 | unless (-x "$old_dir/$file") { | |
435 | push @de_exec => $file; | |
436 | } | |
437 | } | |
438 | } | |
418f4069 A |
439 | |
440 | # | |
441 | # No need to change the +x bit on files that will be deleted. | |
442 | # | |
ad9b4e6f | 443 | if (@de_exec && @delete) { |
a9f5d1d4 | 444 | my %delete = map {+"$pkg_dir/$_" => 1} @delete; |
ad9b4e6f | 445 | @de_exec = grep {!$delete {$_}} @de_exec; |
418f4069 A |
446 | } |
447 | ||
448 | say "unlink $pkg_dir/$_" for @delete; | |
449 | say "git add $pkg_dir/$_" for @commit; | |
450 | say "git rm -f $pkg_dir/$_" for @gone; | |
ad9b4e6f | 451 | say "chmod a-x $pkg_dir/$_" for @de_exec; |
418f4069 A |
452 | |
453 | print "Hit return to continue; ^C to abort "; <STDIN>; | |
454 | ||
455 | unlink "$pkg_dir/$_" for @delete; | |
456 | system git => 'add', "$pkg_dir/$_" for @commit; | |
457 | system git => 'rm', '-f', "$pkg_dir/$_" for @gone; | |
cd9a1714 | 458 | de_exec( "$pkg_dir/$_" ) for @de_exec; |
418f4069 | 459 | |
9c259538 A |
460 | # |
461 | # Restore anything that is customized. | |
462 | # We don't really care whether we've deleted the file - since we | |
463 | # do a git restore, it's going to be resurrected if necessary. | |
464 | # | |
465 | if ($$info {CUSTOMIZED}) { | |
466 | say "Restoring customized files"; | |
467 | foreach my $file (@{$$info {CUSTOMIZED}}) { | |
468 | system git => "checkout", "$pkg_dir/$file"; | |
469 | } | |
470 | } | |
471 | ||
a8121781 | 472 | chdir ".."; |
190c1b3b | 473 | if (@commit || @gone) { |
418f4069 | 474 | say "Fixing MANIFEST"; |
190c1b3b AC |
475 | my $MANIFEST = "MANIFEST"; |
476 | my $MANIFEST_NEW = "$MANIFEST.new"; | |
477 | ||
478 | open my $orig, "<", $MANIFEST | |
479 | or die "Failed to open $MANIFEST for reading: $!\n"; | |
480 | open my $new, ">", $MANIFEST_NEW | |
481 | or die "Failed to open $MANIFEST_NEW for writing: $!\n"; | |
482 | my %gone = map +("cpan/$pkg_dir/$_" => 1), @gone; | |
483 | while (my $line = <$orig>) { | |
484 | my ($file) = $line =~ /^(\S+)/ | |
485 | or die "Can't parse MANIFEST line: $line"; | |
486 | print $new $line if !$gone{$file}; | |
487 | } | |
488 | ||
489 | say $new "cpan/$pkg_dir/$_" for @commit; | |
490 | ||
491 | close $new or die "Can't close $MANIFEST: $!\n"; | |
492 | ||
493 | system $^X => "Porting/manisort", '--quiet', "--output=$MANIFEST", $MANIFEST_NEW; | |
494 | unlink $MANIFEST_NEW | |
495 | or die "Can't delete temporary $MANIFEST_NEW: $!\n"; | |
418f4069 A |
496 | } |
497 | ||
498 | ||
e6e4cae9 | 499 | print "Running a make and saving its output to $MAKE_LOG ... "; |
160daab8 MM |
500 | # Prepare for running (selected) tests |
501 | make 'test-prep'; | |
418f4069 A |
502 | print "done\n"; |
503 | ||
d8a823f4 AC |
504 | # The build system installs code from CPAN dists into the lib/ directory, |
505 | # creating directories as needed. This means that the cleaning-related rules | |
506 | # in the Makefile need to know which directories to clean up. The Makefile | |
507 | # is generated by Configure from Makefile.SH, so *that* file needs the list | |
508 | # of directories. regen/lib_cleanup.pl is capable of automatically updating | |
509 | # the contents of Makefile.SH (and win32/Makefile, which needs similar but | |
510 | # not identical lists of directories), so we can just run that (using the | |
511 | # newly-built Perl, as is done with the regen programs run by "make regen"). | |
512 | # | |
513 | # We do this if any files at all have been added or deleted, regardless of | |
514 | # whether those changes result in any directories being added or deleted, | |
515 | # because the alternative would be to replicate the regen/lib_cleanup.pl | |
516 | # logic here. That's fine, because regen/lib_cleanup.pl is idempotent if run | |
517 | # repeatedly. | |
518 | if (@commit || @gone) { | |
519 | say "Running regen/lib_cleanup.pl to handle potential added/deleted dirs"; | |
215d9c65 | 520 | my $exe_dir = WIN32 ? ".\\" : './'; |
d8a823f4 AC |
521 | system "${exe_dir}perl$Config{_exe}", "-Ilib", "regen/lib_cleanup.pl" |
522 | and die "regen/lib_cleanup.pl failed\n"; | |
523 | } | |
524 | ||
418f4069 A |
525 | # |
526 | # Must clean up, or else t/porting/FindExt.t will fail. | |
730ad6b9 | 527 | # Note that we can always retrieve the original directory with a git checkout. |
418f4069 A |
528 | # |
529 | print "About to clean up; hit return or abort (^C) "; <STDIN>; | |
530 | ||
192f56b0 MM |
531 | remove_tree( "cpan/$old_dir" ); |
532 | unlink "cpan/$new_file" unless $tarball; | |
418f4069 | 533 | |
ad9b4e6f A |
534 | # |
535 | # Run the tests. First the test belonging to the module, followed by the | |
536 | # the tests in t/porting | |
537 | # | |
192f56b0 | 538 | chdir "t"; |
ad9b4e6f | 539 | say "Running module tests"; |
57b5d6e1 | 540 | my @test_files = grep { /\.t$/ } find_type_f( "../cpan/$pkg_dir" ); |
215d9c65 | 541 | my $exe_dir = WIN32 ? "..\\" : './'; |
06998c55 AC |
542 | $ENV{TEST_JOBS} = $_ for grep defined, $make_jobs; |
543 | my $output = `${exe_dir}perl$Config{_exe} -I../lib harness @test_files`; | |
ad9b4e6f A |
544 | unless ($output =~ /All tests successful/) { |
545 | say $output; | |
546 | exit 1; | |
547 | } | |
548 | ||
418f4069 | 549 | print "Running tests in t/porting "; |
fc134225 | 550 | my @tests = glob 'porting/*.t'; |
418f4069 A |
551 | chomp @tests; |
552 | my @failed; | |
553 | foreach my $t (@tests) { | |
cefd15c2 MM |
554 | my @not = grep {!/# TODO/ } |
555 | grep { /^not/ } | |
556 | `${exe_dir}perl -I../lib -I.. $t`; | |
418f4069 A |
557 | print @not ? '!' : '.'; |
558 | push @failed => $t if @not; | |
559 | } | |
560 | print "\n"; | |
561 | say "Failed tests: @failed" if @failed; | |
562 | ||
563 | ||
9807c17b JL |
564 | chdir '..'; |
565 | ||
566 | open my $Maintainers_pl, '<', 'Porting/Maintainers.pl'; | |
567 | open my $new_Maintainers_pl, '>', 'Maintainers.pl'; | |
568 | ||
569 | my $found; | |
570 | my $in_mod_section; | |
571 | while (<$Maintainers_pl>) { | |
572 | if (!$found) { | |
573 | if ($in_mod_section) { | |
574 | if (/DISTRIBUTION/) { | |
33c6567b | 575 | if (s/\Q$old_version/$new_version/) { |
9807c17b JL |
576 | $found = 1; |
577 | } | |
578 | } | |
579 | ||
580 | if (/^ }/) { | |
581 | $in_mod_section = 0; | |
582 | } | |
583 | } | |
584 | ||
585 | if (/\Q$cpan_mod/) { | |
586 | $in_mod_section = 1; | |
587 | } | |
588 | } | |
589 | ||
590 | print $new_Maintainers_pl $_; | |
591 | } | |
592 | ||
593 | if ($found) { | |
d9d83ea5 | 594 | say "Successfully updated Maintainers.pl"; |
9807c17b JL |
595 | unlink 'Porting/Maintainers.pl'; |
596 | rename 'Maintainers.pl' => 'Porting/Maintainers.pl'; | |
cd9a1714 | 597 | chmod 0755 => 'Porting/Maintainers.pl'; |
9807c17b JL |
598 | } |
599 | else { | |
600 | say "Could not update Porting/Maintainers.pl."; | |
601 | say "Make sure you update this by hand before committing."; | |
602 | } | |
418f4069 | 603 | |
592f3827 | 604 | print <<"EOF"; |
418f4069 | 605 | |
592f3827 AC |
606 | ======================================================================= |
607 | ||
608 | $o_module is now at version $new_version | |
609 | Next, you should run a "make test". | |
610 | ||
611 | Hopefully that will complete successfully, but if not, you can make any | |
612 | changes you need to get the tests to pass. Don't forget that you'll need | |
613 | a "CUSTOMIZED" entry in Porting/Maintainers.pl if you change any of the | |
614 | files under cpan/$pkg_dir. | |
615 | ||
616 | Once all tests pass, you can "git add -u" and "git commit" the changes. | |
617 | ||
618 | EOF | |
418f4069 A |
619 | |
620 | __END__ |