1898184e3Ssthen#!/usr/bin/env perl 2898184e3Ssthen 391f110e0Safresh1=head1 NAME 491f110e0Safresh1 591f110e0Safresh1Porting/sync-with-cpan - Synchronize with CPAN distributions 691f110e0Safresh1 791f110e0Safresh1=head1 SYNOPSIS 891f110e0Safresh1 9b46d8ef2Safresh1 sh ./Configure 1091f110e0Safresh1 perl Porting/sync-with-cpan <module> 1191f110e0Safresh1 12eac174f2Safresh1where C<module> is the name it appears in the C<%Modules> hash 1391f110e0Safresh1of F<Porting/Maintainers.pl> 1491f110e0Safresh1 1591f110e0Safresh1=head1 DESCRIPTION 1691f110e0Safresh1 1791f110e0Safresh1Script to help out with syncing cpan distros. 1891f110e0Safresh1 1991f110e0Safresh1Does the following: 2091f110e0Safresh1 2191f110e0Safresh1=over 4 2291f110e0Safresh1 2391f110e0Safresh1=item * 2491f110e0Safresh1 2591f110e0Safresh1Fetches the package list from CPAN. Finds the current version of the given 2691f110e0Safresh1package. [1] 2791f110e0Safresh1 2891f110e0Safresh1=item * 2991f110e0Safresh1 3091f110e0Safresh1Downloads the relevant tarball; unpacks the tarball. [1] 3191f110e0Safresh1 3291f110e0Safresh1=item * 3391f110e0Safresh1 3491f110e0Safresh1Clean out the old directory (C<git clean -dfx>) 3591f110e0Safresh1 3691f110e0Safresh1=item * 3791f110e0Safresh1 3891f110e0Safresh1Moves the old directory out of the way, moves the new directory in place. 3991f110e0Safresh1 4091f110e0Safresh1=item * 4191f110e0Safresh1 4291f110e0Safresh1Restores any F<.gitignore> file. 4391f110e0Safresh1 4491f110e0Safresh1=item * 4591f110e0Safresh1 4691f110e0Safresh1Removes files from C<@IGNORE> and C<EXCLUDED> 4791f110e0Safresh1 4891f110e0Safresh1=item * 4991f110e0Safresh1 5091f110e0Safresh1C<git add> any new files. 5191f110e0Safresh1 5291f110e0Safresh1=item * 5391f110e0Safresh1 5491f110e0Safresh1C<git rm> any files that are gone. 5591f110e0Safresh1 5691f110e0Safresh1=item * 5791f110e0Safresh1 5891f110e0Safresh1Remove the +x bit on files in F<t/> 5991f110e0Safresh1 6091f110e0Safresh1=item * 6191f110e0Safresh1 6291f110e0Safresh1Remove the +x bit on files that don't have it enabled in the current dir 6391f110e0Safresh1 6491f110e0Safresh1=item * 6591f110e0Safresh1 6691f110e0Safresh1Restore files mentioned in C<CUSTOMIZED> 6791f110e0Safresh1 6891f110e0Safresh1=item * 6991f110e0Safresh1 709f11ffb7Safresh1Updates the contents of F<MANIFEST> 7191f110e0Safresh1 7291f110e0Safresh1=item * 7391f110e0Safresh1 7491f110e0Safresh1Runs a C<make> (assumes a configure has been run) 7591f110e0Safresh1 7691f110e0Safresh1=item * 7791f110e0Safresh1 7891f110e0Safresh1Cleans up 7991f110e0Safresh1 8091f110e0Safresh1=item * 8191f110e0Safresh1 8291f110e0Safresh1Runs tests for the package 8391f110e0Safresh1 8491f110e0Safresh1=item * 8591f110e0Safresh1 8691f110e0Safresh1Runs the porting tests 8791f110e0Safresh1 8891f110e0Safresh1=back 8991f110e0Safresh1 9091f110e0Safresh1[1] If the C<--tarball> option is given, then CPAN is not consulted. 9191f110e0Safresh1C<--tarball> should be the path to the tarball; the version is extracted 9291f110e0Safresh1from the filename -- but can be overwritten by the C<--version> option. 9391f110e0Safresh1 949f11ffb7Safresh1=head1 OPTIONS 9591f110e0Safresh1 9691f110e0Safresh1=over 4 9791f110e0Safresh1 989f11ffb7Safresh1=item C<--jobs> I<N> 9991f110e0Safresh1 100e0680481Safresh1When running C<make>, pass a C<< -jI<N> >> option to it to enable 101e0680481Safresh1parallel building. 102e0680481Safresh1 103e0680481Safresh1Note that you can also set C<< TEST_JOBS=I<N> >> in the environment 104e0680481Safresh1to enable parallel *testing* on top of parallel *building*. 105e0680481Safresh1 106e0680481Safresh1=item C<--yes> 107e0680481Safresh1 108e0680481Safresh1Just continue at all places where we would normally ask for the user 109e0680481Safresh1to hit enter or hit CTL-C, with the exception of cases related to 110e0680481Safresh1CUSTOMIZED distributions, where this option will cause the update to 111e0680481Safresh1exit immediately unless the C<--force> option has also been used. 112e0680481Safresh1 113e0680481Safresh1=item C<--force> 114e0680481Safresh1 115e0680481Safresh1Do things we normally would refuse to do. 116e0680481Safresh1 117e0680481Safresh1=item C<--tarball> 118e0680481Safresh1 119*3d61058aSafresh1Use a predownloaded tarball and not one from CPAN. Example: 120*3d61058aSafresh1 121*3d61058aSafresh1 perl Porting/sync-with-cpan Text-Tabs+Wrap \ 122*3d61058aSafresh1 --tarball /tmp/Text-Tabs+Wrap-2024.001.tar.gz \ 123*3d61058aSafresh1 --yes 124e0680481Safresh1 125e0680481Safresh1=item C<--version> 126e0680481Safresh1 127e0680481Safresh1Sync with a specific version, not the latest on CPAN. 128e0680481Safresh1 129e0680481Safresh1=item C<--no-test> 130e0680481Safresh1 131e0680481Safresh1=item C<--nt> 132e0680481Safresh1 133e0680481Safresh1Do not run tests. This is helpful for bulk updates. 134e0680481Safresh1 135e0680481Safresh1=item C<--help> 136e0680481Safresh1 137e0680481Safresh1Show help. 1389f11ffb7Safresh1 1399f11ffb7Safresh1=back 1409f11ffb7Safresh1 1419f11ffb7Safresh1=head1 TODO 1429f11ffb7Safresh1 1439f11ffb7Safresh1=over 4 14491f110e0Safresh1 14591f110e0Safresh1=item * 14691f110e0Safresh1 14791f110e0Safresh1Update F<Porting/Maintainers.pl> 14891f110e0Safresh1 14991f110e0Safresh1=item * 15091f110e0Safresh1 15191f110e0Safresh1Optional, run a full test suite 15291f110e0Safresh1 15391f110e0Safresh1=item * 15491f110e0Safresh1 15591f110e0Safresh1Handle complicated C<FILES> 15691f110e0Safresh1 15791f110e0Safresh1=back 15891f110e0Safresh1 15991f110e0Safresh1This is an initial version; no attempt has been made yet to make this 16091f110e0Safresh1portable. It shells out instead of trying to find a Perl solution. 1616fb12b70Safresh1In particular, it assumes git, perl, and make 16291f110e0Safresh1to be available. 16391f110e0Safresh1 16491f110e0Safresh1=cut 16591f110e0Safresh1 166898184e3Ssthen 167898184e3Ssthenpackage Maintainers; 168898184e3Ssthen 169898184e3Ssthenuse 5.010; 170898184e3Ssthen 171898184e3Ssthenuse strict; 172898184e3Ssthenuse warnings; 173898184e3Ssthenuse Getopt::Long; 1746fb12b70Safresh1use Archive::Tar; 1759f11ffb7Safresh1use File::Basename qw( basename ); 1766fb12b70Safresh1use File::Path qw( remove_tree ); 1776fb12b70Safresh1use File::Find; 1789f11ffb7Safresh1use File::Spec::Functions qw( tmpdir rel2abs ); 1796fb12b70Safresh1use Config qw( %Config ); 180898184e3Ssthen 181898184e3Ssthen$| = 1; 182898184e3Ssthen 1839f11ffb7Safresh1use constant WIN32 => $^O eq 'MSWin32'; 1849f11ffb7Safresh1 18591f110e0Safresh1die "This does not look like a top level directory" 186898184e3Ssthen unless -d "cpan" && -d "Porting"; 187898184e3Ssthen 1889f11ffb7Safresh1# Check that there's a Makefile, if needed; otherwise, we'll do most of our 1899f11ffb7Safresh1# work only to fail when we try to run make, and the user will have to 1909f11ffb7Safresh1# either unpick everything we've done, or do the rest manually. 1919f11ffb7Safresh1die "Please run Configure before using $0\n" 1929f11ffb7Safresh1 if !WIN32 && !-f "Makefile"; 1939f11ffb7Safresh1 194e0680481Safresh1#these are populated by Porting/Maintainers.pl 195898184e3Ssthenour @IGNORABLE; 196898184e3Ssthenour %Modules; 197e0680481Safresh1our %DistName; 198898184e3Ssthen 199898184e3Ssthenuse autodie; 200898184e3Ssthen 2019f11ffb7Safresh1require "./Porting/Maintainers.pl"; 2029f11ffb7Safresh1 2039f11ffb7Safresh1my $MAKE_LOG = 'make.log'; 204e0680481Safresh1unlink $MAKE_LOG if -e $MAKE_LOG; 205898184e3Ssthen 206898184e3Ssthenmy %IGNORABLE = map {$_ => 1} @IGNORABLE; 207898184e3Ssthen 2089f11ffb7Safresh1my $tmpdir = tmpdir(); 2096fb12b70Safresh1 210898184e3Ssthenmy $package = "02packages.details.txt"; 211898184e3Ssthenmy $package_url = "http://www.cpan.org/modules/$package"; 2126fb12b70Safresh1my $package_file = "$tmpdir/$package"; # this is a cache 213e0680481Safresh1my $type_dir = "cpan"; 214898184e3Ssthen 21591f110e0Safresh1my @problematic = ( 216*3d61058aSafresh1 # no current entries as of perl-5.40.1 (Jan 2025) 21791f110e0Safresh1); 21891f110e0Safresh1 219898184e3Ssthen 220b8851fccSafresh1sub usage 221b8851fccSafresh1{ 222b8851fccSafresh1 my $err = shift and select STDERR; 223eac174f2Safresh1 print "Usage: $0 <module-or-dist> [args]\n"; 224b8851fccSafresh1 exit $err; 225b8851fccSafresh1} 226b8851fccSafresh1 227898184e3SsthenGetOptions ('tarball=s' => \my $tarball, 228898184e3Ssthen 'version=s' => \my $version, 2299f11ffb7Safresh1 'jobs=i' => \my $make_jobs, 230e0680481Safresh1 'yes' => \my $yes_to_all, 231e0680481Safresh1 'force' => \my $force, 232e0680481Safresh1 'no-test|nt' => \my $no_test, 233e0680481Safresh1 'help' => sub { usage 0; }, 234e0680481Safresh1 'type=s' => \$type_dir, 235b8851fccSafresh1 ) or die "Failed to parse arguments"; 236898184e3Ssthen 237e0680481Safresh1usage 1 unless @ARGV == 1; 238898184e3Ssthen 2396fb12b70Safresh1sub find_type_f { 2406fb12b70Safresh1 my @res; 2416fb12b70Safresh1 find( { no_chdir => 1, wanted => sub { 2426fb12b70Safresh1 my $file= $File::Find::name; 2436fb12b70Safresh1 return unless -f $file; 2446fb12b70Safresh1 push @res, $file 2456fb12b70Safresh1 }}, @_ ); 2466fb12b70Safresh1 @res 2476fb12b70Safresh1}; 2486fb12b70Safresh1 2496fb12b70Safresh1# Equivalent of `chmod a-x` 2506fb12b70Safresh1sub de_exec { 2519f11ffb7Safresh1 my ($filename) = @_; 2526fb12b70Safresh1 my $mode = (stat $filename)[2] & 0777; 2536fb12b70Safresh1 if ($mode & 0111) { # exec-bit set 2546fb12b70Safresh1 chmod $mode & 0666, $filename; 2559f11ffb7Safresh1 } 2569f11ffb7Safresh1} 2579f11ffb7Safresh1 2589f11ffb7Safresh1# Equivalent of `chmod +w` 2599f11ffb7Safresh1sub make_writable { 2609f11ffb7Safresh1 my ($filename) = @_; 2619f11ffb7Safresh1 my $mode = (stat $filename)[2] & 0777; 2629f11ffb7Safresh1 if (!($mode & 0222)) { # not writable 2639f11ffb7Safresh1 chmod $mode | (0222 & ~umask), $filename; 2646fb12b70Safresh1 } 2656fb12b70Safresh1} 2666fb12b70Safresh1 267e0680481Safresh1my $SEP_LINE = ("-" x 79) . "\n"; 268e0680481Safresh1 269e0680481Safresh1sub cat_make_log { 270e0680481Safresh1 my ($message) = @_; 271e0680481Safresh1 print $message, $message=~/Starting/ 272e0680481Safresh1 ? " and saving its output to '$MAKE_LOG' ...\n" 273e0680481Safresh1 : "\n"; 274e0680481Safresh1 275e0680481Safresh1 open my $ofh, ">>", $MAKE_LOG 276e0680481Safresh1 or die "Failed to open '$MAKE_LOG' for append\n"; 277e0680481Safresh1 print $ofh $SEP_LINE,"$message at ", 278e0680481Safresh1 scalar(localtime),"\n",$SEP_LINE; 279e0680481Safresh1 close $ofh; 280e0680481Safresh1} 281e0680481Safresh1 282e0680481Safresh1sub run_make { 2836fb12b70Safresh1 my @args = @_; 2849f11ffb7Safresh1 unshift @args, "-j$make_jobs" if defined $make_jobs; 285e0680481Safresh1 cat_make_log("Starting `make @args`"); 286e0680481Safresh1 my $errored; 2879f11ffb7Safresh1 if (WIN32) { 2886fb12b70Safresh1 chdir "Win32"; 289e0680481Safresh1 $errored = system "$Config{make} @args >> ..\\$MAKE_LOG 2>&1"; 2906fb12b70Safresh1 chdir '..'; 2916fb12b70Safresh1 } else { 292e0680481Safresh1 $errored = system "$Config{make} @args >> $MAKE_LOG 2>&1"; 2936fb12b70Safresh1 }; 294e0680481Safresh1 cat_make_log("Finished `make @args`"); 295e0680481Safresh1 if ($errored) { 296e0680481Safresh1 if ($args[0] ne "test-prep") { 297e0680481Safresh1 # see if we can extract the last Test Summary Report from 298e0680481Safresh1 # the $MAKE_LOG file, 299e0680481Safresh1 if (open my $ifh, "<", $MAKE_LOG) { 300e0680481Safresh1 my @report; 301e0680481Safresh1 my $in_summary; 302e0680481Safresh1 while (<$ifh>) { 303e0680481Safresh1 if (/^Test Summary Report/) { 304e0680481Safresh1 @report = (); 305e0680481Safresh1 $in_summary = 1; 306e0680481Safresh1 } elsif ($_ eq $SEP_LINE) { 307e0680481Safresh1 $in_summary = 0; 308e0680481Safresh1 } 309e0680481Safresh1 push @report, $_ if $in_summary; 310e0680481Safresh1 } 311e0680481Safresh1 print for @report; 312e0680481Safresh1 } else { 313e0680481Safresh1 warn "Failed to open $MAKE_LOG for reading: $!"; 314e0680481Safresh1 } 315e0680481Safresh1 } 316e0680481Safresh1 die "Running `make` failed, see '$MAKE_LOG' for more details\n"; 317e0680481Safresh1 } 318e0680481Safresh1} 3196fb12b70Safresh1 320e0680481Safresh1sub pause_for_input { 321e0680481Safresh1 my ($after_message) = @_; 322e0680481Safresh1 print "Hit <return> to continue; ^C to abort "; 323e0680481Safresh1 if ($yes_to_all) { 324e0680481Safresh1 print "\n--yes was used on command line, continuing.\n"; 325e0680481Safresh1 } else { 326e0680481Safresh1 my $noop = <STDIN>; 327e0680481Safresh1 } 328e0680481Safresh1 print $after_message if $after_message; 329e0680481Safresh1} 3309f11ffb7Safresh1 331e0680481Safresh1my ($module) = shift @ARGV; 332e0680481Safresh1if (my $mod_name = $DistName{$module}) { 333e0680481Safresh1 $module = $mod_name; 334e0680481Safresh1} 3359f11ffb7Safresh1my $info = $Modules{$module}; 3369f11ffb7Safresh1if (!$info) { 3379f11ffb7Safresh1 # Maybe the user said "Test-Simple" instead of "Test::Simple", or 3389f11ffb7Safresh1 # "IO::Compress" instead of "IO-Compress". See if we can fix it up. 3399f11ffb7Safresh1 my $guess = $module; 3409f11ffb7Safresh1 s/-/::/g or s/::/-/g for $guess; 3419f11ffb7Safresh1 $info = $Modules{$guess} or die <<"EOF"; 3429f11ffb7Safresh1Cannot find module $module. 3439f11ffb7Safresh1The available options are listed in the %Modules hash in Porting/Maintainers.pl 3449f11ffb7Safresh1EOF 3459f11ffb7Safresh1 say "Guessing you meant $guess instead of $module"; 3469f11ffb7Safresh1 $module = $guess; 3479f11ffb7Safresh1} 3489f11ffb7Safresh1 3499f11ffb7Safresh1if ($info->{CUSTOMIZED}) { 3509f11ffb7Safresh1 print <<"EOF"; 3519f11ffb7Safresh1$module has a CUSTOMIZED entry in Porting/Maintainers.pl. 3529f11ffb7Safresh1 3539f11ffb7Safresh1This program's behaviour is to copy every CUSTOMIZED file into the version 3549f11ffb7Safresh1of the module being imported. But that might not be the right thing: in some 3559f11ffb7Safresh1cases, the new CPAN version will supersede whatever changes had previously 3569f11ffb7Safresh1been made in blead, so it would be better to import the new CPAN files. 3579f11ffb7Safresh1 3589f11ffb7Safresh1If you've checked that the CUSTOMIZED versions are still correct, you can 3599f11ffb7Safresh1proceed now. Otherwise, you should abort and investigate the situation. If 3609f11ffb7Safresh1the blead customizations are no longer needed, delete the CUSTOMIZED entry 3619f11ffb7Safresh1for $module in Porting/Maintainers.pl (and you'll also need to regenerate 3629f11ffb7Safresh1t/porting/customized.dat in that case; see t/porting/customized.t). 3639f11ffb7Safresh1 3649f11ffb7Safresh1EOF 365e0680481Safresh1 if ($yes_to_all and !$force) { 366e0680481Safresh1 die "This distribution is marked as CUSTOMIZED\n", 367e0680481Safresh1 "You used --yes on the command line, but without --force.\n", 368e0680481Safresh1 "Bailing out. Use --force to go ahead anyway.\n"; 3699f11ffb7Safresh1 } 370e0680481Safresh1 pause_for_input("\n"); 371e0680481Safresh1} 372e0680481Safresh1 373e0680481Safresh1if (!$ENV{TEST_JOBS} and !WIN32) { 374e0680481Safresh1 print "*** NOTE *** For speedups you can set TEST_JOBS=N in the env before running this script.\n"; 375e0680481Safresh1} 376e0680481Safresh1if (!$make_jobs and !WIN32) { 377e0680481Safresh1 print "*** NOTE *** For speedups you can pass --jobs=N as an arg to this script.\n" 378e0680481Safresh1} 379e0680481Safresh1print "About to clean the $type_dir/ directory, and ensure its contents is up to date.\n"; 380e0680481Safresh1print "Will also checkout -f on $type_dir/, MANIFEST and Porting/Maintainers.pl\n"; 381e0680481Safresh1print "*** WARNING *** - this may DELETE uncommitted changes. Hit ^C if you have ANY doubts!\n"; 382e0680481Safresh1pause_for_input("\n"); 383e0680481Safresh1# clean out the cpan directory, this cleans up any temporary files that might be 384e0680481Safresh1# in the way, or other issues that might come up if the user bails out of the sync 385e0680481Safresh1# script and then runs it again. 386e0680481Safresh1my $clean_out= `git clean -dfx $type_dir`; # use backticks to hide the output 387*3d61058aSafresh1system git => 'checkout', '-f', 388e0680481Safresh1 $type_dir, 389e0680481Safresh1 'MANIFEST', 390e0680481Safresh1 'Porting/Maintainers.pl'; # let the user see the output 391e0680481Safresh1print "the $type_dir/ directory is now clean and up to date\n---\n"; 3929f11ffb7Safresh1 393898184e3Ssthenmy $distribution = $$info {DISTRIBUTION}; 394898184e3Ssthen 395898184e3Ssthenmy @files = glob $$info {FILES}; 39691f110e0Safresh1if (!-d $files [0] || grep { $_ eq $module } @problematic) { 397898184e3Ssthen say "This looks like a setup $0 cannot handle (yet)"; 398898184e3Ssthen unless ($force) { 399898184e3Ssthen say "Will not continue without a --force option"; 400898184e3Ssthen exit 1; 401898184e3Ssthen } 402898184e3Ssthen say "--force is in effect, so we'll soldier on. Wish me luck!"; 403898184e3Ssthen} 404898184e3Ssthen 4059f11ffb7Safresh1use Cwd 'cwd'; 4069f11ffb7Safresh1my $orig_pwd = cwd(); 407898184e3Ssthen 408e0680481Safresh1chdir "$type_dir"; 409898184e3Ssthen 41091f110e0Safresh1my $pkg_dir = $files[0]; 411898184e3Ssthen $pkg_dir =~ s!.*/!!; 412898184e3Ssthen 413*3d61058aSafresh1my $tail_pat = qr/\.(?:tar\.(?:g?z|bz2|Z)|zip|tgz|tbz)/; 414*3d61058aSafresh1my $version_pat = qr/-v?([0-9._]+(?:-TRIAL[0-9]*)?)$tail_pat\z/; 415e0680481Safresh1 416*3d61058aSafresh1my ($old_version) = $distribution =~ $version_pat; 417e0680481Safresh1 418e0680481Safresh1if (!$old_version) { 419e0680481Safresh1 die "WTF: failed to parse old version from '$distribution'\n"; 420e0680481Safresh1} 421898184e3Ssthen 4229f11ffb7Safresh1sub wget { 4239f11ffb7Safresh1 my ($url, $saveas) = @_; 424eac174f2Safresh1 my $ht_res; 4259f11ffb7Safresh1 eval { 426eac174f2Safresh1 require IO::Socket::SSL; 427eac174f2Safresh1 require Net::SSLeay; 4289f11ffb7Safresh1 require HTTP::Tiny; 4299f11ffb7Safresh1 my $http = HTTP::Tiny->new(); 430eac174f2Safresh1 $ht_res = $http->mirror( $url => $saveas ); 431eac174f2Safresh1 1; 4329f11ffb7Safresh1 } or 433eac174f2Safresh1 # Try harder to download the file 4349f11ffb7Safresh1 # Some system do not have wget. Fall back to curl if we do not 4359f11ffb7Safresh1 # have it. On Windows, `which wget` is not going to work, so 4369f11ffb7Safresh1 # just use wget, as this script has always done. 4379f11ffb7Safresh1 WIN32 || -x substr(`which wget`, 0, -1) 4389f11ffb7Safresh1 ? system wget => $url, '-qO', $saveas 4399f11ffb7Safresh1 : system curl => $url, '-sSo', $saveas; 440eac174f2Safresh1 441eac174f2Safresh1 # We were able to use HTTP::Tiny and it didn't have fatal errors, 442eac174f2Safresh1 # but we failed the request 443eac174f2Safresh1 if ( $ht_res && ! $ht_res->{'success'} ) { 444eac174f2Safresh1 die "Cannot retrieve file: $url\n" . 445eac174f2Safresh1 sprintf "Status: %s\nReason: %s\nContent: %s\n", 446eac174f2Safresh1 map $_ // '(unavailable)', @{$ht_res}{qw< status reason content >}; 447eac174f2Safresh1 } 4489f11ffb7Safresh1} 4499f11ffb7Safresh1 450898184e3Ssthen# 451898184e3Ssthen# Find the information from CPAN. 452898184e3Ssthen# 453898184e3Ssthenmy $new_file; 454898184e3Ssthenmy $new_version; 455e0680481Safresh1my $re_update = ""; 4569f11ffb7Safresh1if (defined $tarball) { 4579f11ffb7Safresh1 $tarball = rel2abs( $tarball, $orig_pwd ) ; 4589f11ffb7Safresh1 die "Tarball $tarball does not exist\n" if !-e $tarball; 4599f11ffb7Safresh1 die "Tarball $tarball is not a plain file\n" if !-f _; 4609f11ffb7Safresh1 $new_file = $tarball; 461*3d61058aSafresh1 $new_version = $version // ($new_file =~ $version_pat) [0]; 4629f11ffb7Safresh1 die "Blead and that tarball both have version $new_version of $module\n" 4639f11ffb7Safresh1 if $new_version eq $old_version; 4649f11ffb7Safresh1} 4659f11ffb7Safresh1else { 466898184e3Ssthen # 467898184e3Ssthen # Poor man's cache 468898184e3Ssthen # 469898184e3Ssthen unless (-f $package_file && -M $package_file < 1) { 4709f11ffb7Safresh1 wget $package_url, $package_file; 471898184e3Ssthen } 472898184e3Ssthen 473eac174f2Safresh1 my $cpan_mod = $info->{MAIN_MODULE} // $module; 4746fb12b70Safresh1 open my $fh, '<', $package_file; 475eac174f2Safresh1 (my $new_line) = grep {/^\Q$cpan_mod\E /} <$fh> # Yes, this needs a lot of memory 476898184e3Ssthen or die "Cannot find $cpan_mod on CPAN\n"; 477898184e3Ssthen (undef, $new_version, my $new_path) = split ' ', $new_line; 47891f110e0Safresh1 if (defined $version) { 47991f110e0Safresh1 $new_path =~ s/-$new_version\./-$version\./; 48091f110e0Safresh1 $new_version = $version; 48191f110e0Safresh1 } 482898184e3Ssthen $new_file = (split '/', $new_path) [-1]; 483898184e3Ssthen 484e0680481Safresh1 if ($old_version eq $new_version) { 485e0680481Safresh1 $re_update = "Re-"; 486e0680481Safresh1 print "The latest version of $module is $new_version, but blead already has it.\n"; 487e0680481Safresh1 print "Continuing may update MANIFEST or other metadata so it may make sense to continue anyway.\n"; 488e0680481Safresh1 print "Are you sure you want to continue?\n"; 489e0680481Safresh1 pause_for_input(); 490e0680481Safresh1 } 4919f11ffb7Safresh1 4929f11ffb7Safresh1 my $url = "https://cpan.metacpan.org/authors/id/$new_path"; 493898184e3Ssthen say "Fetching $url"; 494898184e3Ssthen # 495898184e3Ssthen # Fetch the new distro 496898184e3Ssthen # 4979f11ffb7Safresh1 wget $url, $new_file; 498898184e3Ssthen} 499898184e3Ssthen 500e0680481Safresh1my $old_dir = "$pkg_dir-$old_version-OLD"; 501898184e3Ssthen 502898184e3Ssthensay "Cleaning out old directory"; 503898184e3Ssthensystem git => 'clean', '-dfxq', $pkg_dir; 504898184e3Ssthen 505898184e3Ssthensay "Unpacking $new_file"; 5066fb12b70Safresh1Archive::Tar->extract_archive( $new_file ); 507898184e3Ssthen 508*3d61058aSafresh1(my $new_dir = basename($new_file)) =~ s/$tail_pat\z//; 50991f110e0Safresh1# ensure 'make' will update all files 5106fb12b70Safresh1my $t= time; 5116fb12b70Safresh1for my $file (find_type_f($new_dir)) { 5129f11ffb7Safresh1 make_writable($file); # for convenience if the user later edits it 5136fb12b70Safresh1 utime($t,$t,$file); 5146fb12b70Safresh1}; 515898184e3Ssthen 516898184e3Ssthensay "Renaming directories"; 517898184e3Ssthenrename $pkg_dir => $old_dir; 518898184e3Ssthen 51991f110e0Safresh1say "Creating new package directory"; 52091f110e0Safresh1mkdir $pkg_dir; 52191f110e0Safresh1 52291f110e0Safresh1say "Populating new package directory"; 52391f110e0Safresh1my $map = $$info {MAP}; 52491f110e0Safresh1my @EXCLUDED_QR; 52591f110e0Safresh1my %EXCLUDED_QQ; 52691f110e0Safresh1if ($$info {EXCLUDED}) { 52791f110e0Safresh1 foreach my $entry (@{$$info {EXCLUDED}}) { 52891f110e0Safresh1 if (ref $entry) {push @EXCLUDED_QR => $entry} 52991f110e0Safresh1 else {$EXCLUDED_QQ {$entry} = 1} 53091f110e0Safresh1 } 53191f110e0Safresh1} 53291f110e0Safresh1 5336fb12b70Safresh1FILE: for my $file ( find_type_f( $new_dir )) { 53491f110e0Safresh1 my $old_file = $file; 535eac174f2Safresh1 $file =~ s{^\Q$new_dir\E/}{}; 53691f110e0Safresh1 53791f110e0Safresh1 next if $EXCLUDED_QQ{$file}; 53891f110e0Safresh1 for my $qr (@EXCLUDED_QR) { 53991f110e0Safresh1 next FILE if $file =~ $qr; 54091f110e0Safresh1 } 54191f110e0Safresh1 54291f110e0Safresh1 if ( $map ) { 54391f110e0Safresh1 for my $key ( sort { length $b <=> length $a } keys %$map ) { 54491f110e0Safresh1 my $val = $map->{$key}; 54591f110e0Safresh1 last if $file =~ s/^$key/$val/; 54691f110e0Safresh1 } 54791f110e0Safresh1 } 54891f110e0Safresh1 else { 54991f110e0Safresh1 $file = $files[0] . '/' . $file; 55091f110e0Safresh1 } 55191f110e0Safresh1 552e0680481Safresh1 if ( $file =~ m{^$type_dir/} ) { 553e0680481Safresh1 $file =~ s{^$type_dir/}{}; 55491f110e0Safresh1 } 55591f110e0Safresh1 else { 55691f110e0Safresh1 $file = '../' . $file; 55791f110e0Safresh1 } 55891f110e0Safresh1 55991f110e0Safresh1 my $prefix = ''; 56091f110e0Safresh1 my @parts = split '/', $file; 56191f110e0Safresh1 pop @parts; 56291f110e0Safresh1 for my $part (@parts) { 56391f110e0Safresh1 $prefix .= '/' if $prefix; 56491f110e0Safresh1 $prefix .= $part; 56591f110e0Safresh1 mkdir $prefix unless -d $prefix; 56691f110e0Safresh1 } 56791f110e0Safresh1 56891f110e0Safresh1 rename $old_file => $file; 56991f110e0Safresh1} 5706fb12b70Safresh1remove_tree( $new_dir ); 571898184e3Ssthen 572898184e3Ssthenif (-f "$old_dir/.gitignore") { 573898184e3Ssthen say "Restoring .gitignore"; 574898184e3Ssthen system git => 'checkout', "$pkg_dir/.gitignore"; 575898184e3Ssthen} 576898184e3Ssthen 5776fb12b70Safresh1my @new_files = find_type_f( $pkg_dir ); 578898184e3Ssthen@new_files = grep {$_ ne $pkg_dir} @new_files; 579898184e3Ssthens!^[^/]+/!! for @new_files; 580898184e3Ssthenmy %new_files = map {$_ => 1} @new_files; 581898184e3Ssthen 5826fb12b70Safresh1my @old_files = find_type_f( $old_dir ); 583898184e3Ssthen@old_files = grep {$_ ne $old_dir} @old_files; 584898184e3Ssthens!^[^/]+/!! for @old_files; 585898184e3Ssthenmy %old_files = map {$_ => 1} @old_files; 586898184e3Ssthen 587898184e3Ssthenmy @delete; 588898184e3Ssthenmy @commit; 589898184e3Ssthenmy @gone; 590e0680481Safresh1my $changes_file; 591898184e3SsthenFILE: 592898184e3Ssthenforeach my $file (@new_files) { 593898184e3Ssthen next if -d "$pkg_dir/$file"; # Ignore directories. 594898184e3Ssthen next if $old_files {$file}; # It's already there. 595e0680481Safresh1 if ($file=~/Changes/i or $file=~/Changelog/) { 596e0680481Safresh1 if ($changes_file) { 597e0680481Safresh1 die "More than one changes file? $file and $changes_file both exist?"; 598e0680481Safresh1 } 599e0680481Safresh1 $changes_file = "$pkg_dir/$file"; 600e0680481Safresh1 } 601898184e3Ssthen if ($IGNORABLE {$file}) { 602898184e3Ssthen push @delete => $file; 603898184e3Ssthen next; 604898184e3Ssthen } 605898184e3Ssthen push @commit => $file; 606898184e3Ssthen} 607898184e3Ssthenforeach my $file (@old_files) { 608898184e3Ssthen next if -d "$old_dir/$file"; 609898184e3Ssthen next if $new_files {$file}; 610898184e3Ssthen push @gone => $file; 611898184e3Ssthen} 612898184e3Ssthen 613e0680481Safresh1my @changes_info; 614e0680481Safresh1if (!$changes_file) { 615e0680481Safresh1 print "Could not find a changes file!\n", 616e0680481Safresh1 "If this is not correct and there is one, please consider updating this script!\n"; 617e0680481Safresh1} else { 618e0680481Safresh1 open my $ifh, "<", $changes_file 619e0680481Safresh1 or die "Failed to open '$changes_file':$!"; 620e0680481Safresh1 chomp(my @lines = <$ifh>); 621e0680481Safresh1 close $ifh; 622e0680481Safresh1 my $seen_new_version; 623e0680481Safresh1 my $is_update = $new_version ne $old_version; 624e0680481Safresh1 625e0680481Safresh1 for(my $idx = 0; $idx < @lines; $idx++) { 626e0680481Safresh1 if ($lines[$idx] =~ /$new_version/ || 627e0680481Safresh1 ($pkg_dir eq "CPAN" and $lines[$idx] =~/^\d{4}-\d{2}-\d{2}/ 628e0680481Safresh1 && $lines[$idx+2] 629e0680481Safresh1 && $lines[$idx+2] =~ /release $new_version/) 630e0680481Safresh1 ){ 631e0680481Safresh1 $seen_new_version = 1; 632e0680481Safresh1 push @changes_info, $lines[$idx]; 633e0680481Safresh1 } elsif ($seen_new_version) { 634e0680481Safresh1 if ($is_update && $pkg_dir eq "ExtUtils-MakeMaker") { 635e0680481Safresh1 if ($lines[$idx] =~/$old_version/) { 636e0680481Safresh1 last; 637e0680481Safresh1 } 638e0680481Safresh1 } 639e0680481Safresh1 elsif (($lines[$idx]=~/\d\.\d/ and $lines[$idx]=~/20\d\d/) || 640e0680481Safresh1 ($lines[$idx]=~/---------------------------------/) || 641e0680481Safresh1 ($pkg_dir eq "CPAN" and $lines[$idx] =~/^\d{4}-\d{2}-\d{2}/) || 642e0680481Safresh1 ($pkg_dir eq "version" and $lines[$idx] =~/^\d\.\d+/) || 643e0680481Safresh1 ($pkg_dir eq "Getopt-Long" and $lines[$idx] =~/Changes in version/) || 644e0680481Safresh1 ($pkg_dir eq "ExtUtils-Install" and $lines[$idx] =~/^\d+\.\d+/) || 645e0680481Safresh1 0 # less commit churn if we have to tweak the heuristics above 646e0680481Safresh1 ){ 647e0680481Safresh1 last; 648e0680481Safresh1 } 649e0680481Safresh1 push @changes_info, $lines[$idx]; 650e0680481Safresh1 651e0680481Safresh1 } 652e0680481Safresh1 } 653e0680481Safresh1 if (!@changes_info) { 654e0680481Safresh1 die "No changes?"; 655e0680481Safresh1 } else { 656e0680481Safresh1 print "Changes from $changes_file\n"; 657e0680481Safresh1 print $_,"\n" for @changes_info; 658e0680481Safresh1 } 659e0680481Safresh1} 660e0680481Safresh1 661898184e3Ssthen# 662898184e3Ssthen# Find all files with an exec bit 663898184e3Ssthen# 6646fb12b70Safresh1my @exec = find_type_f( $pkg_dir ); 665898184e3Ssthenmy @de_exec; 666898184e3Ssthenforeach my $file (@exec) { 667898184e3Ssthen # Remove leading dir 668898184e3Ssthen $file =~ s!^[^/]+/!!; 669898184e3Ssthen if ($file =~ m!^t/!) { 670898184e3Ssthen push @de_exec => $file; 671898184e3Ssthen next; 672898184e3Ssthen } 673898184e3Ssthen # Check to see if the file exists; if it doesn't and doesn't have 674898184e3Ssthen # the exec bit, remove it. 675898184e3Ssthen if ($old_files {$file}) { 676898184e3Ssthen unless (-x "$old_dir/$file") { 677898184e3Ssthen push @de_exec => $file; 678898184e3Ssthen } 679898184e3Ssthen } 680898184e3Ssthen} 681898184e3Ssthen 682898184e3Ssthen# 683898184e3Ssthen# No need to change the +x bit on files that will be deleted. 684898184e3Ssthen# 685898184e3Ssthenif (@de_exec && @delete) { 686898184e3Ssthen my %delete = map {+"$pkg_dir/$_" => 1} @delete; 687898184e3Ssthen @de_exec = grep {!$delete {$_}} @de_exec; 688898184e3Ssthen} 689898184e3Ssthen 6909f11ffb7Safresh1# 6919f11ffb7Safresh1# Mustn't change the +x bit on files that are whitelisted 6929f11ffb7Safresh1# 6939f11ffb7Safresh1if (@de_exec) { 6949f11ffb7Safresh1 my %permitted = map { (my $x = $_) =~ tr/\n//d; $x => 1 } grep !/^#/, 6959f11ffb7Safresh1 do { local @ARGV = '../Porting/exec-bit.txt'; <> }; 696e0680481Safresh1 @de_exec = grep !$permitted{"$type_dir/$pkg_dir/$_"}, @de_exec; 6979f11ffb7Safresh1} 698e0680481Safresh1@$_ = sort @$_ for \@delete, \@commit, \@gone, \@de_exec; 6999f11ffb7Safresh1 700898184e3Ssthensay "unlink $pkg_dir/$_" for @delete; 701898184e3Ssthensay "git add $pkg_dir/$_" for @commit; 702898184e3Ssthensay "git rm -f $pkg_dir/$_" for @gone; 703898184e3Ssthensay "chmod a-x $pkg_dir/$_" for @de_exec; 704898184e3Ssthen 705e0680481Safresh1print "--\nWill perform the above steps and then start testing.\n"; 706e0680481Safresh1print "You may want to `tail -F $MAKE_LOG` in another window\n"; 707e0680481Safresh1pause_for_input("\n"); 708898184e3Ssthen 709898184e3Ssthenunlink "$pkg_dir/$_" for @delete; 710898184e3Ssthensystem git => 'add', "$pkg_dir/$_" for @commit; 711898184e3Ssthensystem git => 'rm', '-f', "$pkg_dir/$_" for @gone; 7126fb12b70Safresh1de_exec( "$pkg_dir/$_" ) for @de_exec; 713898184e3Ssthen 714898184e3Ssthen# 715898184e3Ssthen# Restore anything that is customized. 716898184e3Ssthen# We don't really care whether we've deleted the file - since we 717898184e3Ssthen# do a git restore, it's going to be resurrected if necessary. 718898184e3Ssthen# 719898184e3Ssthenif ($$info {CUSTOMIZED}) { 720898184e3Ssthen say "Restoring customized files"; 721898184e3Ssthen foreach my $file (@{$$info {CUSTOMIZED}}) { 722898184e3Ssthen system git => "checkout", "$pkg_dir/$file"; 723898184e3Ssthen } 724898184e3Ssthen} 725898184e3Ssthen 726898184e3Ssthenchdir ".."; 727e0680481Safresh1{ 728e0680481Safresh1 # we update the MANIFEST file always now, so that we can 729e0680481Safresh1 # ensure each file from this sync is updated to say that we 730e0680481Safresh1 # got it from the latest version. 731e0680481Safresh1 say "Updating the MANIFEST file"; 732898184e3Ssthen my $MANIFEST = "MANIFEST"; 7339f11ffb7Safresh1 my $MANIFEST_NEW = "$MANIFEST.new"; 7349f11ffb7Safresh1 7359f11ffb7Safresh1 open my $orig, "<", $MANIFEST 7369f11ffb7Safresh1 or die "Failed to open $MANIFEST for reading: $!\n"; 7379f11ffb7Safresh1 open my $new, ">", $MANIFEST_NEW 7389f11ffb7Safresh1 or die "Failed to open $MANIFEST_NEW for writing: $!\n"; 739e0680481Safresh1 my %keep = map +("$type_dir/$pkg_dir/$_" => 1), keys %new_files; 740e0680481Safresh1 my %gone = map +("$type_dir/$pkg_dir/$_" => 1), @gone; 7419f11ffb7Safresh1 while (my $line = <$orig>) { 742e0680481Safresh1 chomp $line; 743e0680481Safresh1 my ($file, $descr) = split /\t+/, $line; 744e0680481Safresh1 if (!$file) { 745e0680481Safresh1 die "Can't parse MANIFEST line: '$line' at line $.\n"; 746e0680481Safresh1 } 747e0680481Safresh1 if ($keep{$file} and !$descr) { 748e0680481Safresh1 # make sure we have at least one tab, old versions of 749e0680481Safresh1 # this script would add lines to MANIFEST with no tab. 750e0680481Safresh1 $line =~ s/^(\S+)\z/$1\t\t/; 751e0680481Safresh1 752e0680481Safresh1 my $file_descr = ""; 753e0680481Safresh1 if ( $file =~ /\.t/ ) { 754e0680481Safresh1 $file_descr = "Test file"; 755e0680481Safresh1 } 756e0680481Safresh1 elsif ( $file =~ /\.pm/ ) { 757e0680481Safresh1 $file_descr = "Module"; 758e0680481Safresh1 } 759e0680481Safresh1 elsif ( $file =~ /\.pl/ ) { 760e0680481Safresh1 $file_descr = "Script"; 761e0680481Safresh1 } 762e0680481Safresh1 $file_descr .= " related to " if $file_descr; 763e0680481Safresh1 # and update the line to show where the file came from. 764e0680481Safresh1 $line =~ s/(\t+).*/$1$file_descr$module/; 765e0680481Safresh1 } 766e0680481Safresh1 say $new $line if !$gone{$file}; 7679f11ffb7Safresh1 } 7689f11ffb7Safresh1 769e0680481Safresh1 say $new "$type_dir/$pkg_dir/$_\t\t$pkg_dir" for @commit; 7709f11ffb7Safresh1 7719f11ffb7Safresh1 close $new or die "Can't close $MANIFEST: $!\n"; 7729f11ffb7Safresh1 7739f11ffb7Safresh1 system $^X => "Porting/manisort", '--quiet', "--output=$MANIFEST", $MANIFEST_NEW; 7749f11ffb7Safresh1 unlink $MANIFEST_NEW 7759f11ffb7Safresh1 or die "Can't delete temporary $MANIFEST_NEW: $!\n"; 776898184e3Ssthen} 777898184e3Ssthen 778898184e3Ssthen 779e0680481Safresh1 780e0680481Safresh1# Prepare for running (selected) tests - strictly speaking this isn't 781e0680481Safresh1# necessary, as we run the tests with "run_make" now, but this allows 782e0680481Safresh1# us to separate build issues from test issues. 783e0680481Safresh1run_make 'test-prep' unless $no_test; 784898184e3Ssthen 7859f11ffb7Safresh1# The build system installs code from CPAN dists into the lib/ directory, 7869f11ffb7Safresh1# creating directories as needed. This means that the cleaning-related rules 7879f11ffb7Safresh1# in the Makefile need to know which directories to clean up. The Makefile 7889f11ffb7Safresh1# is generated by Configure from Makefile.SH, so *that* file needs the list 7899f11ffb7Safresh1# of directories. regen/lib_cleanup.pl is capable of automatically updating 7909f11ffb7Safresh1# the contents of Makefile.SH (and win32/Makefile, which needs similar but 7919f11ffb7Safresh1# not identical lists of directories), so we can just run that (using the 7929f11ffb7Safresh1# newly-built Perl, as is done with the regen programs run by "make regen"). 7939f11ffb7Safresh1# 7949f11ffb7Safresh1# We do this if any files at all have been added or deleted, regardless of 7959f11ffb7Safresh1# whether those changes result in any directories being added or deleted, 7969f11ffb7Safresh1# because the alternative would be to replicate the regen/lib_cleanup.pl 7979f11ffb7Safresh1# logic here. That's fine, because regen/lib_cleanup.pl is idempotent if run 7989f11ffb7Safresh1# repeatedly. 7999f11ffb7Safresh1if (@commit || @gone) { 8009f11ffb7Safresh1 say "Running regen/lib_cleanup.pl to handle potential added/deleted dirs"; 8019f11ffb7Safresh1 my $exe_dir = WIN32 ? ".\\" : './'; 8029f11ffb7Safresh1 system "${exe_dir}perl$Config{_exe}", "-Ilib", "regen/lib_cleanup.pl" 8039f11ffb7Safresh1 and die "regen/lib_cleanup.pl failed\n"; 8049f11ffb7Safresh1} 8059f11ffb7Safresh1 806898184e3Ssthen# 807898184e3Ssthen# Must clean up, or else t/porting/FindExt.t will fail. 8086fb12b70Safresh1# Note that we can always retrieve the original directory with a git checkout. 809898184e3Ssthen# 810e0680481Safresh1print "About to clean up the old version, update Maintainers.pl and start tests\n"; 811e0680481Safresh1pause_for_input("\n"); 812898184e3Ssthen 813e0680481Safresh1remove_tree( "$type_dir/$old_dir" ); 814e0680481Safresh1unlink "$type_dir/$new_file" unless $tarball; 815898184e3Ssthen 816898184e3Ssthen 81791f110e0Safresh1open my $Maintainers_pl, '<', 'Porting/Maintainers.pl'; 81891f110e0Safresh1open my $new_Maintainers_pl, '>', 'Maintainers.pl'; 81991f110e0Safresh1 820e0680481Safresh1my $found = 0; 82191f110e0Safresh1my $in_mod_section; 82291f110e0Safresh1while (<$Maintainers_pl>) { 82391f110e0Safresh1 if ($in_mod_section) { 824e0680481Safresh1 if ($found == 1) { 825e0680481Safresh1 # Keep track of when and who did the sync. 826e0680481Safresh1 # This must be before the DISTRIBUTION check. 827e0680481Safresh1 # This ensures that *something* is updated when we re-update. 828e0680481Safresh1 my $date = localtime; 829e0680481Safresh1 my $user = $ENV{USER} ? "$ENV{USER} on " : ""; 830e0680481Safresh1 my $key = "SYNCINFO"; 831e0680481Safresh1 if ( /^'([A-Z_]+)'\s+=>/ and $1 eq $key) { 832e0680481Safresh1 s/(=>\s+)'[^']+'/$1'$user$date'/; 833e0680481Safresh1 } 834e0680481Safresh1 else { 835e0680481Safresh1 print $new_Maintainers_pl 836e0680481Safresh1 " '$key' => '$user$date',\n"; 837e0680481Safresh1 } 838e0680481Safresh1 $found = 2; 839e0680481Safresh1 $in_mod_section = 0; 840e0680481Safresh1 } 84191f110e0Safresh1 if (/DISTRIBUTION/) { 84291f110e0Safresh1 if (s/\Q$old_version/$new_version/) { 84391f110e0Safresh1 $found = 1; 84491f110e0Safresh1 } 84591f110e0Safresh1 } 846e0680481Safresh1 if (/^\s*\}/) { # sanity 84791f110e0Safresh1 $in_mod_section = 0; 84891f110e0Safresh1 } 84991f110e0Safresh1 } 85091f110e0Safresh1 851e0680481Safresh1 if (/\Q$module\E/ and !$found) { 85291f110e0Safresh1 $in_mod_section = 1; 85391f110e0Safresh1 } 85491f110e0Safresh1 85591f110e0Safresh1 print $new_Maintainers_pl $_; 85691f110e0Safresh1} 85791f110e0Safresh1 85891f110e0Safresh1if ($found) { 8599f11ffb7Safresh1 say "Successfully updated Maintainers.pl"; 86091f110e0Safresh1 unlink 'Porting/Maintainers.pl'; 86191f110e0Safresh1 rename 'Maintainers.pl' => 'Porting/Maintainers.pl'; 8626fb12b70Safresh1 chmod 0755 => 'Porting/Maintainers.pl'; 86391f110e0Safresh1} 86491f110e0Safresh1else { 86591f110e0Safresh1 say "Could not update Porting/Maintainers.pl."; 86691f110e0Safresh1 say "Make sure you update this by hand before committing."; 86791f110e0Safresh1} 86891f110e0Safresh1 869e0680481Safresh1# Run the tests. First the test belonging to the module, followed by the 870e0680481Safresh1# tests in t/porting 871e0680481Safresh1 872e0680481Safresh1my $shell_quote = WIN32 ? '"' : "'"; 873e0680481Safresh1if ($no_test) { 874e0680481Safresh1 print "*** NOT RUNNING TESTS ***\n"; 875e0680481Safresh1} else { 876e0680481Safresh1 run_make "test-harness TEST_ARGS=$shell_quote-re $pkg_dir$shell_quote"; 877e0680481Safresh1 run_make "test-porting"; 878e0680481Safresh1} 879e0680481Safresh1 880e0680481Safresh1my $committed; 881e0680481Safresh1if (@changes_info) { 882e0680481Safresh1 system git => 'commit', 883e0680481Safresh1 join("\n", 884e0680481Safresh1 "-m$type_dir/$pkg_dir - ${re_update}Update to version $new_version", 885e0680481Safresh1 "",@changes_info), 886e0680481Safresh1 "$type_dir/$pkg_dir", "MANIFEST", "Porting/Maintainers.pl" 887e0680481Safresh1 or $committed = 1; # note system returns true for an error! 888e0680481Safresh1} 889e0680481Safresh1 890e0680481Safresh1 8919f11ffb7Safresh1print <<"EOF"; 892898184e3Ssthen 8939f11ffb7Safresh1======================================================================= 8949f11ffb7Safresh1 895eac174f2Safresh1$module is now at version $new_version 896eac174f2Safresh1Next, you should run "make minitest" and then "make test". 8979f11ffb7Safresh1 898eac174f2Safresh1Minitest uses miniperl, which does not support XS modules. The full test 899eac174f2Safresh1suite uses perl, which does. Minitest can fail - e.g. if a cpan module 900eac174f2Safresh1has added an XS dependency - even if the full test suite passes just fine. 901eac174f2Safresh1 902eac174f2Safresh1Hopefully all will complete successfully, but if not, you can make any 9039f11ffb7Safresh1changes you need to get the tests to pass. Don't forget that you'll need 9049f11ffb7Safresh1a "CUSTOMIZED" entry in Porting/Maintainers.pl if you change any of the 905e0680481Safresh1files under $type_dir/$pkg_dir. 9069f11ffb7Safresh1 9079f11ffb7Safresh1EOF 908898184e3Ssthen 909e0680481Safresh1if ($committed) { 910e0680481Safresh1 print <<"EOF"; 911e0680481Safresh1The changes have already been committed. If the tests above fail you can 912e0680481Safresh1discard this patch with 913e0680481Safresh1 914e0680481Safresh1 git reset --hard HEAD^. 915e0680481Safresh1 916e0680481Safresh1You may also want to review the commit message and alter it with 917e0680481Safresh1 918e0680481Safresh1 git commit --amend 919e0680481Safresh1 920e0680481Safresh1Regardless you still need to push this commit upstream with something like 921e0680481Safresh1 922e0680481Safresh1 git push origin HEAD:$ENV{USER}/update_${pkg_dir}_v_$new_version 923e0680481Safresh1 924e0680481Safresh1EOF 925e0680481Safresh1} else { 926e0680481Safresh1 print <<"EOF"; 927e0680481Safresh1Once all tests pass, you can commit it with a command like: 928e0680481Safresh1 929e0680481Safresh1 git commit -m${shell_quote}$type_dir/$pkg_dir - Update to version $new_version${shell_quote} $type_dir/$pkg_dir 930e0680481Safresh1 931e0680481Safresh1and then push it upstream with a command like 932e0680481Safresh1 933e0680481Safresh1 git push origin HEAD:$ENV{USER}/update_${pkg_dir}_v_$new_version 934e0680481Safresh1 935e0680481Safresh1EOF 936e0680481Safresh1} 937e0680481Safresh1 938898184e3Ssthen__END__ 939