File Coverage

/root/.cpan/build/App-scriptdist-1.006-0/blib/script/scriptdist
Criterion Covered Total %
statement 110 133 82.7
branch 16 32 50.0
condition 1 4 25.0
subroutine 17 17 100.0
pod n/a
total 144 186 77.4


line stmt bran cond sub pod time code
1             #!/usr/local/bin/perl
2 1     1   4446 use utf8;
  1         194  
  1         5  
3 1     1   28 use v5.10;
  1         2  
4              
5 1     1   6 use strict;
  1         1  
  1         13  
6 1     1   3 use warnings;
  1         1  
  1         35  
7              
8 1     1   4 use vars qw( %Content $VERSION $Quiet $Rc_directory $Dir_sep );
  1         2  
  1         61  
9              
10 1     1   292 use App::scriptdist qw(:all);
  1         15020  
  1         158  
11              
12 1     1   5 use Cwd;
  1         1  
  1         39  
13 1     1   7 use ExtUtils::Command;
  1         1  
  1         45  
14 1     1   3 use ExtUtils::Manifest;
  1         2  
  1         22  
15 1     1   3 use File::Basename qw(basename);
  1         1  
  1         21  
16 1     1   3 use File::Spec;
  1         1  
  1         10  
17 1     1   315 use File::Spec::Functions;
  1         673  
  1         57  
18 1     1   4 use FindBin ();
  1         1  
  1         785  
19              
20 1         48922 $VERSION = '1.003';
21              
22             =encoding utf8
23              
24             =head1 NAME
25              
26             scriptdist - create a distribution for a perl script
27              
28             =head1 SYNOPSIS
29              
30             % scriptdist script.pl
31              
32             =head1 DESCRIPTION
33              
34             The scriptdist program takes a script file and builds, in the current
35             working directory, a Perl script distribution around it. You can add
36             other files to the distribution once it is in place.
37              
38             This script is designed to be a stand-alone program. You do not need
39             any other files to use it. However, you can create a directory named
40             .scriptdist in your home directory, and scriptdist will look for local
41             versions of template files there. Any files in F<~/.scriptdist/t>
42             will show up as is in the script's t directory (until I code the parts
43             to munge those files). The script assumes you have specified your
44             home directory in the environment variable HOME.
45              
46             You can turn on optional progress and debugging messages by setting
47             the environment variable SCRIPTDIST_DEBUG to a true value.
48              
49             =head2 The process
50              
51             =over 4
52              
53             =item * Check for release information
54              
55             The first time the scriptdist is run, or any time the scriptdist cannot
56             find the file C<.scriptdistrc>, it prompts for CPAN and SourceForge
57             developer information that it can add to the F<.releaserc> file. (NOT
58             YET IMPLEMENTED)
59              
60             =item * Create a directory named after the script
61              
62             The distribution directory is named after the script name,
63             with a F<.d> attached. The suffix is there only to avoid a
64             name conflict. You can rename it after the script is moved
65             into the directory. If the directory already exists, the
66             script stops. You can either move or delete the directory
67             and start again.
68              
69             =item * Look for template files
70              
71             The program looks in F<.scriptdistrc> for files to copy into
72             the target script distribution directory. After that, it
73             adds more files unless they already exist (i.e. the script
74             found them in the template directory). The script replaces
75             strings matching C<%%SCRIPTDIST_FOO%%> with the internal
76             value of FOO. The defined values are currently SCRIPT, which
77             substitutes the script name, and VERSION, whose value is
78             currently hard-coded at '0.10'.
79              
80             While looking for files, scriptdist skips directories named
81             F, F<.git>, and F<.svn>.
82              
83             =item * Add Changes
84              
85             A bare bones Changes file
86              
87             =item * Create the Makefile.PL
88              
89             =item * Create the t directory
90              
91             =item * Add compile.t, pod.t, prereq.t
92              
93             =item * Create test_manifest
94              
95             =item * Copy the script into the directory
96              
97             =item * Run make manifest
98              
99             =item * Create git repo
100              
101             Unless you set the C, C creates
102             a git repo, adds everything, and does an initial import.
103              
104             =back
105              
106             =head2 Creating the Makefile.PL
107              
108             A few things have to show up in the Makefile.PL—the name of
109             the script and the prerequisites modules are the most important.
110             Luckily, scriptdist can discover these things and fill them in
111             automatically.
112              
113             =head1 TO DO
114              
115             =over 4
116              
117             =item * Copy modules into lib directory (to create module dist)
118              
119             =item * Command line switches to turn things on and off
120              
121             =back
122              
123             =head2 Maybe a good idea, maybe not
124              
125             =over 4
126              
127             =item * Add a cover.t and pod coverage test?
128              
129             =item * Interactive mode?
130              
131             =item * automatically import into Git?
132              
133             =back
134              
135             =head1 SOURCE AVAILABILITY
136              
137             This source is part of a Github project.
138              
139             https://github.com/briandfoy/scriptdist
140              
141             =head1 CREDITS
142              
143             Thanks to Soren Andersen for putting this script through its paces
144             and suggesting many changes to actually make it work.
145              
146             =head1 AUTHOR
147              
148             brian d foy, C<< >>
149              
150             =head1 COPYRIGHT
151              
152             Copyright © 2004-2024, brian d foy . All rights reserved.
153              
154             This code is available under the Artistic License 2.0.
155              
156             =cut
157              
158             # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
159             # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
160             # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
161              
162             my %Defaults = (
163             version => '0.10', # version for the copied script, not this one
164             minimum_perl_version => 5,
165             modules => [],
166             name => $FindBin::Script,
167             home => ( $ENV{HOME} // '' ),
168             quiet => defined $ENV{SCRIPTDIST_DEBUG} ? !$ENV{SCRIPTDIST_DEBUG} : 0,
169             path => $ARGV[0],
170 1 50 50     7 dir_sep => do {
171 1 50       6 if( $^O =~ m/MSWin32/ ) { '\\' }
  0 50       0  
172 0         0 elsif( $^O =~ m/Mac/ ) { ":" }
173 1         7 else { '/' }
174             },
175             );
176              
177 1         41 $Defaults{script} = basename( $Defaults{path} );
178 1         3 $Defaults{directory} = "$Defaults{script}.d";
179 1         7 $Defaults{rc_dir} = catfile( $Defaults{home}, "." . $Defaults{name} );
180              
181             my $show_message = sub {
182 41 50   41   80 return if $Defaults{quiet};
183 41         352 print STDERR $_[0];
184 1         4 };
185              
186 1         3 $show_message->( "Processing $Defaults{script}...\n" );
187 1         4 $show_message->( "Quiet is $Defaults{quiet}\n" );
188 1         3 $show_message->( "Home directory is $Defaults{home}\n" );
189              
190             my $Config_file = catfile(
191 1         5 $Defaults{home}, "." . $Defaults{name} . "rc" );
192              
193 1 50       3 warn <<"HERE" unless $Defaults{home} ne '';
194             The environment variable HOME has no value, so I will look in
195             the current directory for $Defaults{rc_dir} and $Config_file. Set
196             the HOME environment variable to choose another directory.
197             HERE
198              
199             # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
200             # Extract included modules
201             {
202 1         2 my $class = 'Module::Extract::Use';
203 1 50   1   61 if( eval "use $class; 1" ) {
  1         144  
  0         0  
  0         0  
204 0         0 my $extor = $class->new;
205 0         0 my $modules = $extor->get_modules_with_details( $Defaults{path} );
206              
207             $show_message->( "\tFound modules\n\t\t", join "\n\t\t",
208 0   0     0 map { $_->module . " => " . ( $_->version // '0' ) } @$modules
  0         0  
209             );
210              
211 0         0 $Defaults{modules} = $modules;
212             }
213             else {
214 1         4 $show_message->( "Install $class to detect prerequisites\n" );
215             }
216             }
217              
218             # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
219             # Extract declared Perl version
220             {
221 1         1 my $class = 'Module::Extract::DeclaredMinimumPerl';
  1         3  
  1         1  
222 1 50   1   53 if( eval "use $class; 1" ) {
  1         60  
  0            
  0            
223 0         0 my $extor = $class->new;
224 0         0 my $version = $extor->get_minimum_declared_perl( $Defaults{path} );
225              
226 0         0 $show_message->( "\tFound minimum version $version\n" );
227              
228 0         0 $Defaults{minimum_perl_version} = $version;
229             }
230             else {
231 1         3 $show_message->( "Install $class to detect minimum versions\n" );
232             }
233             }
234              
235             # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
236             # Make directories
237 1 50       23 die <<"HERE" if -d $Defaults{directory};
238             Directory $Defaults{directory} already exists! Either delete it or
239             move it out of the way, then rerun this program.
240             HERE
241              
242 1         3 foreach my $dir (
243 1         8 map { $_, catfile( $_, "t" ) } $Defaults{directory} ) {
244 2         11 $show_message->( "Making directory $dir...\n" );
245 2 50       311 mkdir $dir, 0755 or die "Could not make [$dir]: $!\n";
246             }
247              
248             # Copy local template files
249 1         7 $show_message->( "RC directory is $Defaults{rc_dir}\n" );
250 1         9 $show_message->( "cwd is ", getcwd, "\n" );
251              
252 1 50       16 if( -d $Defaults{rc_dir} ) {
253 1         3 $show_message->( "Looking for local templates...\n" );
254 1         6 foreach my $input ( find_files( $Defaults{rc_dir} ) ) {
255 2         522 $show_message->( "rc_dir is $Defaults{rc_dir}\n" );
256 2         7 $show_message->( "dir_sep is $Defaults{dir_sep}\n" );
257 2         9 $show_message->( "Input is $input\n" );
258 2         59 my( $path ) = $input =~ m/\Q$Defaults{rc_dir}$Defaults{dir_sep}\E(.*)/g;
259 2         8 $show_message->( "Path is $path\n" );
260              
261 2         18 my @path = File::Spec->splitdir( $path );
262 2         5 my $file = pop @path;
263 2         7 $show_message->( "File is $file\n" );
264              
265 2 50       13 if( @path ) {
266 0         0 local @ARGV = catfile( $Defaults{directory}, @path );
267 0 0       0 ExtUtils::Command::mkpath unless -d $ARGV[0];
268             }
269              
270 2         13 my $output = catfile( $Defaults{directory}, $path );
271 2         7 $show_message->( "Output is $file\n" );
272 2         7 copy( $input, $output, \%Defaults );
273             }
274             }
275              
276              
277 1         158 FILE: foreach my $filename ( sort keys %{ content( \%Defaults ) } ) {
  1         4  
278 8         105 my @path = split m|\Q$Defaults{dir_sep}|, $filename;
279              
280 8         45 my $file = catfile( $Defaults{directory}, @path );
281              
282 8         24 $show_message->( "Checking for file [$filename]... " );
283 8 100       173 if( -e $file ) { $show_message->( "already exists\n" ); next FILE }
  1         4  
  1         8  
284              
285 7         16 $show_message->( "Adding file [$filename]...\n" );
286 7 50       497 open my($fh), '>:utf8', $file or do {
287 0         0 warn "Could not write to [$file]: $!\n";
288 0         0 next FILE;
289             };
290              
291 1     1   6 no warnings 'uninitialized';
  1         1  
  1         1375  
292 7         214 print $fh $Content{$filename};
293             }
294              
295             # Add the script itself
296             {
297 1         3 $show_message->( "Adding [$Defaults{script}]...\n" );
  1         4  
298 1         6 my $dist_script = catfile( $Defaults{directory}, $Defaults{script} );
299              
300 1 50       25 if( -e $Defaults{path} ) {
301 1         5 $show_message->( "Copying script...\n" );
302 1         4 copy( $Defaults{path}, $dist_script );
303             }
304             else {
305 0         0 $show_message->( "Using script template...\n" );
306 0         0 open my $fh, '>:utf8', $dist_script;
307 0         0 print { $fh } script_template( $Defaults{script} );
  0         0  
308             }
309             }
310              
311             # Create the MANIFEST file
312 1         174 $show_message->( "Creating MANIFEST...\n" );
313 1 50       9 chdir $Defaults{directory} or die "Could not change to $Defaults{directory}: $!\n";
314 1         2 $ExtUtils::Manifest::Verbose = 0;
315 1         5 ExtUtils::Manifest::mkmanifest;
316              
317 1         2351 gitify();