#!/usr/local/bin/perl -w eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}' if 0; # not running under some shell use strict; use vars qw($opt_h $opt_v $opt_O $opt_o $opt_l $opt_L $opt_P $opt_T); my( $SDIST_VERSION ) = ' $Revision: 0.3 $ ' =~ /\$Revision:\s+([^\s]+)/; my ($SCRIPT_VERSION) = '0.01'; use Getopt::Std; use File::Copy; sub usage{ warn "\n@_\n" if @_; die "sdist [-L directory] [-v version] [-l extra_library_files] script_file_name version: $SDIST_VERSION -L specify a directory to search for library files -l specify extra library files to be included -O allow an existing directory and files to be overwritten -o allow an existing directory to be used without overwriting files -P omit the stub POD section -T omit the autogenerated skeleton test file -v insert the specified version number for the script -h display this help message and quit "; } getopts("L:oOPThl:v:") || usage; usage if ($opt_h); # get the name of the script file (includes any extension) my $script_file = $ARGV[0]; usage "Must supply the filename of the script\n" if (!$script_file); # $SCRIPT_VERSION is 0.01, unless changed by the user. This will be # inserted as $VERSION into the skeleton script file, where # Makefile.PL will look if( $opt_v ){ $SCRIPT_VERSION = $opt_v; } # $name is used in the name of the distribution (together with $VERSION), # and is used as NAME in Makefile.PL. (my $name = $script_file) =~ s/(.*)\.\w+$/$1/; warn "\n"; # create directory $name if ($opt_O or $opt_o) { if ( -e $name ) { warn "Reusing existing $name directory\n"; } else { warn "Creating directory $name\n"; mkdir($name, 0777) || die "Can't mkdir $name: $!\n"; } } else { if ( -e $name ) { die "Won't overwrite existing $name without -O or -o option!!!\n"; } else { mkdir($name, 0777) || die "Can't mkdir $name: $!\n"; } } # get any supplied library files, and copy them to $name my (@lib_files, $lib_file); if ( $opt_l ) { @lib_files = split /,/, $opt_l; foreach $lib_file (@lib_files) { my $dest = "$name/$lib_file"; if (! $opt_L) { if ( -e $lib_file ) { if ((not -e $dest) or ((-e $dest) and $opt_O)) { warn "Copying $lib_file to $name\n"; copy($lib_file, $dest) or die "Couldn't copy $lib_file to $name: $!\n"; } else { warn "Preserving existing $dest\n"; } } else { die "Couldn't find $lib_file: $!\n"; } } else { if ( -e "$opt_L/$lib_file") { if ((not -e $dest) or ((-e $dest) and $opt_O)) { warn "Copying $opt_L/$lib_file to $name\n"; copy("$opt_L/$lib_file", $dest) or die "Couldn't copy $lib_file to $name: $!\n"; } else { warn "Preserving existing $dest\n"; } } else { if ( -e $lib_file ) { if ((not -e $dest) or ((-e $dest) and $opt_O)) { warn "Copying $lib_file to $name\n"; copy($lib_file, $dest) or die "Couldn't copy $lib_file to $name: $!\n"; } else { warn "Preserving existing $dest\n"; } } else { die "Couldn't find $lib_file: $!\n"; } } } } } chdir($name) || die "Can't chdir to $name: $!\n"; my $year = 1900 + (localtime(time))[5]; # create the skeleton script file if ((not -e $script_file) or ((-e $script_file) and $opt_O)) { open (SCRIPT, ">$script_file") || die "Can't open $script_file: $!\n"; warn "Creating skeleton script $name/$script_file\n"; warn "Inserting \$VERSION = $SCRIPT_VERSION into $name/$script_file\n"; # print header of skeleton script file, which includes $VERSION print SCRIPT <<"END"; #!/usr/local/bin/perl use strict; use vars qw(\$VERSION); \$VERSION = '$SCRIPT_VERSION'; ########################################################### # # Remember to insert the actual code from $script_file # ########################################################### END #insert skeleton POD stuff, unless requested not to if ( not $opt_P ) { $" = "\n\t"; warn "Appending stub POD to $name/$script_file\n"; my $pod = <<"END"; ## Below is the stub of documentation for your script. You better edit it! # #=pod # #=head1 NAME # #$name - Perl script for blah blah blah # #=head1 SYNOPSIS # # blah blah blah # #=head1 DESCRIPTION # # Describe in detail how to use the script # #=head1 PREREQUISITES # #This script requires the C module. It also requires #C. # #=head1 COREQUISITES # #CGI # #=head1 OSNAMES # #any # #=head1 SCRIPT CATEGORIES # #CPAN/Administrative #Fun/Educational # #=head1 AUTHOR # # Your name, with your email address # #=head1 SEE ALSO # #perl(1). # #=head1 COPYRIGHT # # $script_file is Copyright (c) $year, by you. # All rights reserved. You may distribute this code under the terms # of either the GNU General Public License or the Artistic License, # as specified in the Perl README file. # #=cut END $pod =~ s/^\#//gm; print SCRIPT $pod; } close SCRIPT; } else { warn "Preserving existing $name/$script_file\n"; } # start to create Makefile.PL if ((not -e "Makefile.PL") or ((-e "Makefile.PL") and $opt_O)) { warn "Writing $name/Makefile.PL\n"; open(PL, ">Makefile.PL") || die "Can't create $name/Makefile.PL: $!\n"; # print header of Makefile.PL print PL <<'END'; use ExtUtils::MakeMaker; # # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. # # If any modules outside of the core perl distribution are required, # these should be included as a PREREQ_PM entry in WriteMakefile below, # as indicated in the example. This example requires the modules # MOD1 and MOD2 to be installed, with minimal versions 1 and 5, # respectively. If the version number is 0, any version is sufficient. # # As well, if you wish to force a minimal perl version to run the # script, insert a line, for example, # # require 5.004; # # below. END # insert NAME, VERSION_FROM, and dist information into Makefile.PL print PL "WriteMakefile(\n"; print PL " 'NAME' => '$name',\n"; print PL " 'VERSION_FROM' => '$script_file', # finds \$VERSION\n"; print PL " 'dist' => { COMPRESS => 'gzip', SUFFIX => 'gz' },\n "; # include $script_file in EXE_FILES my $exe_files = "'$script_file'"; # also include any extra library files in PM if ( $opt_l ) { my $pm; foreach $lib_file ( @lib_files ) { $pm .= "'$lib_file' => '\$(INST_LIB)/$lib_file',\n\t"; } print PL " 'PM' => { $pm }, # lib files to install\n"; } print PL " 'EXE_FILES' => [ $exe_files ], # scripts to install\n"; print PL "# Uncomment and edit the following line to include required modules\n"; print PL "# 'PREREQ_PM' => { 'MOD1' => 1, 'MOD2' => 5 },\n"; print PL ");\n\n"; close(PL) || die "Can't close $name/Makefile.PL: $!\n"; } else { warn "Preserving existing $name/Makefile.PL\n"; } # make the testing t/ subdirectory if (not $opt_T) { if ($opt_O or $opt_o) { if ( -e "t" ) { warn "Reusing existing $name/t directory\n"; } else { warn "Creating directory $name/t\n"; mkdir("t", 0777) || die "Can't mkdir $name/t: $!\n"; } } else { if ( -e "t" ) { die "\nWon't overwrite existing $name/t without -O or -o options\n"; } else { mkdir("t", 0777) || die "Can't mkdir $name/t: $!\n"; } } # create a test.t template under t/, unless told not to if ((not -e "t/test.t") or ((-e "t/test.t") and $opt_O)) { warn "Writing $name/t/test.t\n"; open(EX, ">t/test.t") || die "Can't create $name/t/test.t: $!\n"; # print the header to test.t print EX <<'END'; # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.t' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . BEGIN { $| = 1; print "1..1\n"; } END {print "not ok 1\n" unless $loaded;} END # if extra library files are included, 'require' them in test.t if ( $opt_l ) { foreach $lib_file (@lib_files) { print EX "require '$lib_file';\n"; } } # print the end of test.t print EX <<'END'; $loaded = 1; print "ok 1\n"; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): END close(EX) || die "Can't close $name/test.t: $!\n"; } else { warn "Preserving existing $name/test.t\n"; } } # generate a sample README file if ((not -e "README") or ((-e "README") and $opt_O)) { warn "Writing $name/README\n"; open(EX, ">README") || die "Can't create $name/README: $!\n"; print EX <<"END"; This is the README file for $script_file, a perl script to blah blah blah. For more information on how to use the script, see the pod documentation via the command perldoc $script_file or, after installation, view the man pages with man $name For instructions on how to install the script, see the file INSTALL. Problems, questions, etc. may be sent to me\@my.host.name $script_file is Copyright (c) $year, by you. All rights reserved. You may distribute this code under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. END close(EX) || die "Can't close $name/README: $!\n"; } else { warn "Preserving existing $name/README\n"; } # generate a sample INSTALL file if ((not -e "INSTALL") or ((-e "INSTALL") and $opt_O)) { warn "Writing $name/INSTALL\n"; open(EX, ">INSTALL") || die "Can't create $name/INSTALL: $!\n"; print EX <<"END"; To install the script and man pages in the standard areas, give the sequence of commands perl Makefile.PL make make test make install If you want to install the script in your own private space, use perl Makefile.PL PREFIX=/my/private/perllib \\ INSTALLMAN1DIR=/my/private/perllib/man/man1 \\ INSTALLMAN3DIR=/my/private/perllib/man/man3 make make test make install Any libraries installed in such non-standard places may then need to have the appropriate path to them specified in the script. Note that `make test` may not necessarily be enabled. END close(EX) || die "Can't close $name/INSTALL: $!\n"; } else { warn "Preserving existing $name/INSTALL\n"; } # generate a sample Changes file if ((not -e "Changes") or ((-e "Changes") and $opt_O)) { warn "Writing $name/Changes\n"; open(EX, ">Changes") || die "Can't create $name/Changes: $!\n"; print EX "Revision history for Perl script $script_file.\n\n"; print EX "$SCRIPT_VERSION ",scalar localtime,"\n"; print EX "\t- original version; created by sdist $SDIST_VERSION\n\n"; close(EX) || die "Can't close $name/Changes: $!\n"; } else { warn "Preserving existing $name/Changes\n"; } # generate the MANIFEST file, containing a list of all files # in the current directory $name, plus those under t/ warn "Writing $name/MANIFEST\n"; open(MANI,'>MANIFEST') or die "Can't create MANIFEST: $!"; # get a list of files in the main $name directory my @files; eval {opendir(D, '.');}; unless ($@) { @files = grep {not /^\./} readdir(D); closedir(D); } if (!@files) { @files = <*>; } if (!@files) { @files = map {chomp && $_} `ls`; } if (@files) { if ($^O eq 'VMS') { foreach (@files) { # Clip trailing '.' for portability -- non-VMS OSs don't expect it s%\.$%%; # Fix up for case-sensitive file systems s/$name/$name/i && next; $_ = "\U$_" if $_ eq 'manifest' or $_ eq 'changes' or $_ eq 'readme' or $_ eq 'install' ; $_ = 'Makefile.PL' if $_ eq 'makefile.pl'; } } # write the file names to MANIFEST, unless the file is a # directory, where we find the files under this directory # and write their names to MANIFEST my $file; foreach $file (@files) { if ( -d $file ) { my @subfiles; eval {opendir(D, $file);}; unless ($@) { @subfiles = readdir(D); closedir(D); } if (!@subfiles) {@subfiles = <$file/*>;} if (!@subfiles) { @subfiles = map {chomp && $_} `ls`; } if ($^O eq 'VMS') { foreach (@subfiles) { # Clip trailing '.' for portability -- non-VMS OSs don't expect it s%\.$%%; } } my $subfile; foreach $subfile (@subfiles) { print MANI "$file/$subfile\n" unless ($subfile =~ /^\./); } } else { print MANI "$file\n" unless ($file =~ /^\./); } } } else { warn "Couldn't read files under $name: please edit the MANIFEST file by hand\n"; } close MANI || die "Can't close $name/MANIFEST: $!\n"; # Print out a final message, reminding the user that some # editing of files still needs to be done print <<"END"; As detailed in the documentation, remember to edit the skeleton script file $script_file in $name/, the README and INSTALL files, Makefile.PL for \$VERSION and if you require a minimal perl version and/or non-standard modules, and the tests under t/. END __END__ =head1 NAME sdist - generate a Makefile.PL for a perl script =head1 SYNOPSIS B [B<-I> directory] [B<-v> version] [B<-l> extra_library_files] script_file_name B B<-h> =head1 README This script builds a Makefile.PL for perl scripts, together with the necessary files to make a distribution. Installing scripts then follows the same procedure as for modules: perl Makefile.PL make make test make install with the distribution itself being made via make dist or make zipdist which builds a I or I distribution, respectively. More complete documentation on its use, including how to include non-standard library files in the distribution, is contained in the embedded pod documentation, which can be viewed via perldoc sdist This script is Copyright (c) 1998, by Randy Kobes (randy@theory.uwinnipeg.ca). All rights reserved. You may distribute this code under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =head1 DESCRIPTION Like using I for modules, I builds a Makefile.PL for perl scripts, together with the necessary files to make a distribution. Installing scripts then follows the standard procedure as for modules: perl Makefile.PL make make test make install The distribution itself can be made with make dist which, by default, builds a I distribution, or by using make zipdist which builds a I distribution. Any required library files outside of those found in the core perl distribution may also be included by specifying the I<-l> and, optionally, the I<-L> options; these will be copied into directory from which the distribution is made. These library files, together with the main script file, are installed in the I<$INSTALLSCRIPT> directory specified in the Perl configuration files. Generated man pages are installed into I<$INSTALLMAN1DIR> or I<$INSTALLMAN3DIR>. The argument I to sdist should be the name of the main script file, including extension. A skeleton script file of the same name will be generated in the build, possibly including the version number and basic pod documentation, depending on the options used. The actual code of your script file should then be inserted manually into this skeleton file. The name of the distribution will be derived from the main script file (without the extension), together with the version number. As well as editing the main script file, you should also customize the generated I and I files, and also check I, particularly if you would like to require a minimal perl version to run and/or include modules outside of the core perl distribution. Finally, any tests under the created t/ directory should be customized. =head1 OPTIONS =over 5 =item B<-L> I Specify the path to search for required library files. If this is not given, the current directory is assumed. =item B<-l> I Specifies any required library files not found in the core perl libraries that should be included in the distribution. If more than one file is needed, separate them by commas (eg, I<-l mylib1.pl,mylib2.pl>) with no spaces. =item B<-O> Allows a pre-existing directory to be used, with any existing files in that directory to be overwritten. =item B<-o> Allows a pre-existing directory to be used, but any existing files in that directory will not be overwritten. =item B<-P> Omit the autogenerated stub POD section from the skeleton script. =item B<-T> Omit the autogenerated skeleton test. =item B<-h> Print the usage, help and version for this sdist and exit. =item B<-v> I Specify a version number for the main script, which will set the variable I<$VERSION> in the skeleton script. The default is 0.01. =back =head1 EXAMPLES The following are based on the main script file my_script.pl # with default version 0.01 and no extra library files. sdist my_script.pl # with version number 2.0, no extra library files, and # no skeleton tests generated sdist -v 2.0 -T my_script.pl # with version 2.0, no extra library files, and no skeleton # pod entries in the skeleton script sdist -P -v 2.0 my_script.pl # with default version 0.01, and an extra library file mylib.pl # found in the current directory sdist -l mylib.pl my_script.pl # with default version 0.01, and two extra library files # mylib1.pl and mylib2.pl in the directory /my/perl/lib sdist -L /my/perl/lib -l mylib1.pl,mylib2.pl my_script.pl =head1 ENVIRONMENT No environment variables are used. =head1 PREREQUISITES This script uses the C and C modules. =head1 OSNAMES any =head1 SCRIPT CATEGORIES CPAN =head1 AUTHOR Mainly derived from code of I and I. Randy Kobes . =head1 SEE ALSO L, L, and L. =head1 DIAGNOSTICS The usual warnings if it cannot read or write the files involved. =head1 COPYRIGHT This script is Copyright (c) 1998, by Randy Kobes. All rights reserved. You may distribute this code under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file. =cut