#!/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<strict> module.  It also requires
#C<Mail::Send 1.08>.
#
#=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<sdist> [B<-I> directory] [B<-v> version] [B<-l> extra_library_files] script_file_name

B<sdist> 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<tar.gz> or I<zip> 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<h2xs -X -n module_name> for modules, I<sdist> 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<tar.gz> distribution, or by using

   make zipdist

which builds a I<zip> 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<script_file_name> 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<README> and  I<INSTALL> files, and also check 
I<Makefile.PL>, 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<library_path>

Specify the path to search for required library files. If this
is not given, the current directory is assumed.

=item B<-l> I<library_files>

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<version>

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<Getopt::Std> and C<File::Copy> modules.

=head1 OSNAMES

any

=head1 SCRIPT CATEGORIES

CPAN

=head1 AUTHOR

Mainly derived from code of I<h2xs> and I<ExtUtils::MakeMaker>.
Randy Kobes <randy@theory.uwinnipeg.ca>.

=head1 SEE ALSO

L<perl>, L<ExtUtils::MakeMaker>, and L<h2xs>.

=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