makerel revision 1.9
1#!/usr/bin/perl -w 2 3# A tool to build a perl release tarball 4# Very basic but functional - if you're on a unix system. 5# 6# If you're on Win32 then it should still work, but various Unix command-line 7# tools will need to be available somewhere. An obvious choice is to install 8# Cygwin and ensure its 'bin' folder is on the PATH in the shell where you run 9# this script. The Cygwin 'bin' folder needs to precede the Windows 'system32' 10# folder so that Cygwin's 'find' command is found in preference to the Windows 11# 'find' command. Your Cygwin installation will need to contain at least the 12# 'cpio' command, in addition to the commands installed by default, and it will 13# also be useful to have 'curl' and 'diffstat' installed too for later stages 14# of the release process (namely, Porting\corelist.pl and generating the commit 15# statistics for the perlXYZdelta.pod file respectively). Finally, ensure that 16# the 'awk' and 'shasum' commands are copies of gawk.exe and sha1sum.exe 17# respectively, rather the links to them that only work in a Cygwin bash shell 18# which they are by default. 19# 20# No matter how automated this gets, you'll always need to read 21# and re-read pumpkin.pod and release_managers_guide.pod to 22# check for things to be done at various stages of the process. 23# 24# Tim Bunce, June 1997 25 26use ExtUtils::Manifest qw(fullcheck); 27$ExtUtils::Manifest::Quiet = 1; 28use Getopt::Std; 29 30$|=1; 31 32sub usage { die <<EOF; } 33usage: $0 [ -r rootdir ] [-s suffix ] [ -b ] [ -n ] 34 -r rootdir directory under which to create the build dir and tarball 35 defaults to '..' 36 -s suffix suffix to append to to the perl-x.y.z dir and tarball name 37 defaults to the concatenaion of the local_patches entry 38 in patchlevel.h (or blank, if none) 39 -b make a .bz2 file in addtion to a .gz file 40 -n do not make any tarballs, just the directory 41EOF 42 43my %opts; 44getopts('bnr:s:', \%opts) or usage; 45@ARGV && usage; 46 47$relroot = defined $opts{r} ? $opts{r} : ".."; 48 49die "Must be in root of the perl source tree.\n" 50 unless -f "./MANIFEST" and -f "patchlevel.h"; 51 52open PATCHLEVEL,"<patchlevel.h" or die; 53my @patchlevel_h = <PATCHLEVEL>; 54close PATCHLEVEL; 55my $patchlevel_h = join "", grep { /^#\s*define/ } @patchlevel_h; 56print $patchlevel_h; 57$revision = $1 if $patchlevel_h =~ /PERL_REVISION\s+(\d+)/; 58$patchlevel = $1 if $patchlevel_h =~ /PERL_VERSION\s+(\d+)/; 59$subversion = $1 if $patchlevel_h =~ /PERL_SUBVERSION\s+(\d+)/; 60die "Unable to parse patchlevel.h" unless $subversion >= 0; 61$vers = sprintf("%d.%d.%d", $revision, $patchlevel, $subversion); 62 63# fetch list of local patches 64my (@local_patches, @lpatch_tags, $lpatch_tags); 65@local_patches = grep { /^static.*local_patches/../^};/ } @patchlevel_h; 66@local_patches = grep { !/^\s*,?NULL/ } @local_patches; 67@lpatch_tags = map { /^\s*,"(\w+)/ } @local_patches; 68$lpatch_tags = join "-", @lpatch_tags; 69 70$perl = "perl-$vers"; 71$reldir = "$perl"; 72 73$lpatch_tags = $opts{s} if defined $opts{s}; 74$reldir .= "-$lpatch_tags" if $lpatch_tags; 75 76print "\nMaking a release for $perl in $relroot/$reldir\n\n"; 77 78print "Cross-checking the MANIFEST...\n"; 79($missfile, $missentry) = fullcheck(); 80@$missentry 81 = grep {$_ !~ m!^\.git/! and $_ !~ m!(?:/|^)\.gitignore!} @$missentry; 82if (@$missfile ) { 83 warn "Can't make a release with MANIFEST files missing:\n"; 84 warn "\t".$_."\n" for (@$missfile); 85} 86if (@$missentry ) { 87 warn "Can't make a release with files not listed in MANIFEST\n"; 88 warn "\t".$_."\n" for (@$missentry); 89 90} 91if ("@$missentry" =~ m/\.orig\b/) { 92 # Handy listing of find command and .orig files from patching work. 93 # I tend to run 'xargs rm' and copy and paste the file list. 94 my $cmd = "find . -name '*.orig' -print"; 95 print "$cmd\n"; 96 system($cmd); 97} 98die "Aborted.\n" if @$missentry or @$missfile; 99print "\n"; 100 101# VMS no longer has hardcoded version numbers descrip.mms 102 103print "Creating $relroot/$reldir release directory...\n"; 104die "$relroot/$reldir release directory already exists\n" if -e "$relroot/$reldir"; 105die "$relroot/$reldir.tar.gz release file already exists\n" if -e "$relroot/$reldir.tar.gz"; 106mkdir("$relroot/$reldir", 0755) or die "mkdir $relroot/$reldir: $!\n"; 107print "\n"; 108 109 110print "Copying files to release directory...\n"; 111# ExtUtils::Manifest maniread does not preserve the order 112$cmd = "awk '{print \$1}' MANIFEST | cpio -pdm $relroot/$reldir"; 113system($cmd) == 0 114 or die "$cmd failed"; 115print "\n"; 116 117chdir "$relroot/$reldir" or die $!; 118 119 120my $SEARCH_ROOTS = 't ext lib dist cpan'; 121 122print "Setting file permissions...\n"; 123system("find . -type f -print | xargs chmod 0444"); 124system("find . -type d -print | xargs chmod 0755"); 125system("find $SEARCH_ROOTS -name '*.t' -print | xargs chmod +x"); 126system("find $SEARCH_ROOTS -name 'test.pl' -print | xargs chmod +x"); 127my @exe = qw( 128 Configure 129 configpm 130 configure.gnu 131 embed.pl 132 installperl 133 installman 134 keywords.pl 135 opcode.pl 136 t/TEST 137 *.SH 138 vms/ext/filespec.t 139 x2p/*.SH 140 Porting/findrfuncs 141 Porting/genlog 142 Porting/makerel 143 Porting/*.pl 144 mpeix/nm 145 mpeix/relink 146 Cross/generate_config_sh 147 Cross/warp 148); 149system("chmod +x @exe") == 0 150 or die "system: $!"; 151 152my @writables = qw( 153 NetWare/config_H.wc 154 NetWare/Makefile 155 keywords.h 156 opcode.h 157 opnames.h 158 pp_proto.h 159 pp.sym 160 proto.h 161 embed.h 162 embedvar.h 163 global.sym 164 overload.c 165 overload.h 166 perlapi.h 167 perlapi.c 168 cpan/Devel-PPPort/module2.c 169 cpan/Devel-PPPort/module3.c 170 reentr.c 171 reentr.h 172 regcharclass.h 173 regnodes.h 174 warnings.h 175 lib/warnings.pm 176 win32/Makefile 177 win32/Makefile.ce 178 win32/makefile.mk 179 win32/config_H.bc 180 win32/config_H.gc 181 win32/config_H.vc 182 utils/Makefile 183 uconfig.h 184); 185system("chmod +w @writables") == 0 186 or die "system: $!"; 187 188chdir ".." or die $!; 189 190exit if $opts{n}; 191 192my $src = (-e $perl) ? $perl : 'perl'; # 'perl' in maint branch 193 194print "Creating and compressing the tar.gz file...\n"; 195$cmd = "tar cf - $reldir | gzip --best > $reldir.tar.gz"; 196system($cmd) == 0 or die "$cmd failed"; 197 198if ($opts{b}) { 199 print "Creating and compressing the tar.bz2 file...\n"; 200 $cmd = "tar cf - $reldir | bzip2 > $reldir.tar.bz2"; 201 system($cmd) == 0 or die "$cmd failed"; 202} 203 204print "\n"; 205 206system("ls -ld $perl*"); 207print "\n"; 208 209my $null = $^O eq 'MSWin32' ? 'NUL' : '/dev/null'; 210for my $sha (qw(sha1 shasum sha1sum)) { 211 if (`which $sha 2>$null`) { 212 system("$sha $perl*.tar.*"); 213 last; 214 } 215} 216