File Coverage

blib/lib/Shell/Tools.pm
Criterion Covered Total %
statement 106 117 90.6
branch 0 4 0.0
condition n/a
subroutine 35 37 94.5
pod n/a
total 141 158 89.2


line stmt bran cond sub pod time code
1             #!perl
2             package Shell::Tools;
3 8     8   344674 use warnings;
  8         11  
  8         245  
4 8     8   34 use strict;
  8         10  
  8         410  
5              
6             our $VERSION = '0.02';
7              
8             =head1 Name
9              
10             Shell::Tools - Perl extension to reduce boilerplate in Perl shell scripts
11              
12             =head1 Synopsis
13              
14             use Shell::Tools; # is the same as the following:
15            
16             use warnings;
17             use strict;
18             use IO::File ();
19             use IO::Handle ();
20             use Carp qw/carp croak confess/;
21             use Pod::Usage 'pod2usage';
22             use Getopt::Std 1.04 'getopts';
23             sub main::HELP_MESSAGE { ... } # calls pod2usage()
24             sub main::VERSION_MESSAGE { ... } # see documentation below
25             $Getopt::Std::STANDARD_HELP_VERSION = 1; # exit after --help or --version
26             use Cwd qw/getcwd cwd abs_path/;
27             use File::Spec::Functions qw/canonpath catdir catfile curdir rootdir updir
28             no_upwards file_name_is_absolute splitdir abs2rel rel2abs/;
29             use File::Basename qw/fileparse basename dirname/;
30             use File::Temp qw/tempfile tempdir/;
31             use File::Copy qw/move copy/;
32             use File::Path 2.08 qw/make_path remove_tree/;
33             use File::Find 'find';
34             use Fcntl qw/LOCK_SH LOCK_EX LOCK_UN LOCK_NB SEEK_SET SEEK_CUR SEEK_END/;
35             use FindBin ();
36             use Data::Dumper 'Dumper';
37             use Scalar::Util 'looks_like_number';
38             use List::Util qw/first reduce/;
39              
40             =head1 Description
41              
42             This module exports a collection of functions from several core Perl modules
43             which can often be very useful when writing Perl shell scripts.
44              
45             B L, which exports
46             additional CPAN modules' functions and classes.
47              
48             =head2 Warning
49              
50             This module is intended to help write short, simple shell scripts.
51             Because of its many exports it is not recommended for large applications,
52             CGI scripts, object-oriented applications and the like.
53              
54             =head1 Version
55              
56             This document describes version 0.02 of Shell::Tools.
57              
58             =head1 Exports
59              
60             This module exports the following modules and functions.
61              
62             Each module has an L tag that is the same name as the module.
63             This is useful if you want to exclude some modules' functions from being exported,
64             for example C<< use Shell::Tools qw/ !:File::Copy /; >>.
65              
66             =head2 L and L
67              
68             These are enabled in the calling script.
69             (No Exporter tag.)
70              
71             =cut
72              
73             ## no critic (ProhibitConstantPragma)
74              
75 8     8   36 use base 'Exporter';
  8         15  
  8         1195  
76             our @EXPORT = (); ## no critic (ProhibitAutomaticExportation)
77             our %EXPORT_TAGS = ();
78              
79             sub import { ## no critic (RequireArgUnpacking)
80 9     9   194 warnings->import;
81 9         91 strict->import;
82 9         1820 __PACKAGE__->export_to_level(1, @_);
83 9         8894 return;
84             }
85              
86              
87             =head2 L and L
88              
89             These modules are loaded, nothing is exported.
90             (No Exporter tag.)
91              
92             Perl before v5.14 did not load these automatically.
93             Loading these modules allows you to do things like:
94              
95             open my $fh, ">", $file or die $!;
96             $fh->autoflush(1);
97             $fh->print("Hello");
98             # Note: calling binmode this way may not work on older Perls
99             $fh->binmode(":raw");
100              
101             =cut
102              
103 8     8   611 use IO::File (); # core since Perl 5.00307
  8         7677  
  8         117  
104 8     8   46 use IO::Handle (); # core since Perl 5.00307
  8         7  
  8         177  
105              
106              
107             =head2 L
108              
109             L's C, C and C.
110              
111             =cut
112              
113 8     8   29 use constant _EXP_CARP => qw/carp croak confess/;
  8         12  
  8         632  
114 8     8   38 use Carp _EXP_CARP; # core since Perl 5
  8         14  
  8         706  
115             push @EXPORT, _EXP_CARP;
116             $EXPORT_TAGS{"Carp"} = [_EXP_CARP];
117              
118              
119             =head2 L and L
120              
121             =head1 SYNOPSIS
122            
123             foo.pl [OPTIONS] FILENAME
124             OPTIONS:
125             -f - foo
126             -b BAR - bar
127            
128             =cut
129            
130             getopts('fb:', \my %opts) or pod2usage;
131             pod2usage("must specify a filename") unless @ARGV==1;
132              
133             This module provides the functions C and C.
134             C simply calls L.
135             C first checks for C<$main::VERSION_STRING> and prints that if available,
136             otherwise it will use C<$main::VERSION> to construct a message,
137             and if neither is available, it will use the "last modified" time of the script.
138             Also, C<$Getopt::Std::STANDARD_HELP_VERSION> is set, so the C call
139             will exit the script if it sees C<--help> or C<--version>.
140              
141             We require L 1.04 or greater for the
142             support of the C<--help> and C<--version> switches.
143              
144             Note that L before Version 1.36 only looked for
145             a POD section titled C; from 1.36 upwards it also looks for a
146             section titled C (note uppercase is always important).
147              
148             =cut
149              
150 8     8   32 use constant _EXP_GETOPT_STD => qw/getopts/;
  8         8  
  8         427  
151 8     8   13213 use Getopt::Std 1.04 _EXP_GETOPT_STD;
  8         403  
  8         751  
152             # Getopt::Std is core since Perl 5
153             # Getopt::Std 1.04 is core since Perl v5.8.1
154             push @EXPORT, _EXP_GETOPT_STD;
155             $EXPORT_TAGS{"Getopt::Std"} = [_EXP_GETOPT_STD];
156              
157 8     8   74 use constant _EXP_POD_USAGE => qw/pod2usage/;
  8         9  
  8         434  
158 8     8   3990 use Pod::Usage _EXP_POD_USAGE; # core since Perl v5.6.0
  8         307672  
  8         1995  
159             push @EXPORT, _EXP_POD_USAGE;
160             $EXPORT_TAGS{"Pod::Usage"} = [_EXP_POD_USAGE];
161              
162             sub main::HELP_MESSAGE {
163 0     0     pod2usage(-output=>shift);
164 0           return;
165             }
166             sub main::VERSION_MESSAGE {
167 0     0     my $fh = shift;
168 0 0         if ($main::VERSION_STRING) { print {$fh} $main::VERSION_STRING, "\n" }
  0 0          
  0            
169 0           elsif ($main::VERSION) { print {$fh} $FindBin::Script, ' Version ', $main::VERSION, "\n" }
  0            
170 0           else { print {$fh} $FindBin::Script, ' (last modified ',
  0            
171             scalar localtime((stat(catfile($FindBin::RealBin,$FindBin::RealScript)))[9]), ")\n" }
172 0           return;
173             }
174             $Getopt::Std::STANDARD_HELP_VERSION = 1;
175              
176              
177             =head2 L
178              
179             my $cwd = getcwd(); # POSIX getcwd(3)
180             my $cwd = cwd();
181             my $abs_path = abs_path($file); # realpath(3)
182              
183             =cut
184              
185 8     8   84 use constant _EXP_CWD => qw/getcwd cwd abs_path/;
  8         12  
  8         677  
186 8     8   37 use Cwd _EXP_CWD; # core since Perl 5
  8         15  
  8         731  
187             push @EXPORT, _EXP_CWD;
188             $EXPORT_TAGS{"Cwd"} = [_EXP_CWD];
189              
190              
191             =head2 L
192              
193             my $path = canonpath($path);
194             my $path = catdir(@dirs);
195             my $path = catfile(@dirs, $filename);
196             my @paths = no_upwards(@paths);
197             my $is_abs = file_name_is_absolute($path);
198             my @dirs = splitdir($directories);
199             # note abs2rel() and rel2abs() use Cwd::cwd() if $base is omitted
200             my $rel_path = abs2rel($path, $base);
201             my $abs_path = rel2abs($path, $base);
202             my $curdir = curdir(); # e.g. "."
203             my $rootdir = rootdir(); # e.g. "/"
204             my $updir = updir(); # e.g. ".."
205              
206             # Hint - one way to list all entries in a directory:
207             my @files = do { opendir my $dh, "." or die $!; no_upwards readdir $dh };
208              
209             See L for docs.
210              
211             Note the additional L tag C is provided
212             as an alias for C.
213              
214             =cut
215              
216 8         442 use constant _EXP_FILE_SPEC => qw/canonpath catdir catfile curdir rootdir
217 8     8   43 updir no_upwards file_name_is_absolute splitdir abs2rel rel2abs/;
  8         8  
218 8     8   4575 use File::Spec::Functions _EXP_FILE_SPEC; # core since Perl 5.00504
  8         5014  
  8         1099  
219             push @EXPORT, _EXP_FILE_SPEC;
220             $EXPORT_TAGS{"File::Spec::Functions"} = [_EXP_FILE_SPEC];
221             $EXPORT_TAGS{"File::Spec"} = [_EXP_FILE_SPEC];
222              
223              
224             =head2 L
225              
226             my $filename = fileparse($path, @suffixes); # suffixes optional
227             my ($filename, $dirs, $suffix) = fileparse($path, @suffixes);
228             $path = $dirs . $filename . $suffix;
229              
230             The functions C and C are also provided for compatibility,
231             but L says that C is preferred.
232              
233             =cut
234              
235 8     8   38 use constant _EXP_FILE_BASENAME => qw/fileparse basename dirname/;
  8         10  
  8         465  
236 8     8   34 use File::Basename _EXP_FILE_BASENAME; # core since Perl 5
  8         12  
  8         781  
237             push @EXPORT, _EXP_FILE_BASENAME;
238             $EXPORT_TAGS{"File::Basename"} = [_EXP_FILE_BASENAME];
239              
240              
241             =head2 L
242              
243             my $fh = tempfile();
244             my ($fh,$fn) = tempfile(UNLINK=>1);
245             my (undef,$fn) = tempfile(OPEN=>0);
246             my $tmpdir = tempdir(CLEANUP=>1);
247              
248             =cut
249              
250 8     8   36 use constant _EXP_FILE_TEMP => qw/tempfile tempdir/;
  8         11  
  8         443  
251 8     8   803 use File::Temp _EXP_FILE_TEMP; # core since Perl v5.6.1
  8         10805  
  8         609  
252             push @EXPORT, _EXP_FILE_TEMP;
253             $EXPORT_TAGS{"File::Temp"} = [_EXP_FILE_TEMP];
254              
255              
256             =head2 L
257              
258             copy("src","dst") or die "Copy failed: $!";
259             move("src","dst") or die "Move failed: $!";
260              
261             =cut
262              
263 8     8   38 use constant _EXP_FILE_COPY => qw/move copy/;
  8         12  
  8         448  
264 8     8   518 use File::Copy _EXP_FILE_COPY; # core since Perl 5.002
  8         1741  
  8         821  
265             push @EXPORT, _EXP_FILE_COPY;
266             $EXPORT_TAGS{"File::Copy"} = [_EXP_FILE_COPY];
267              
268              
269             =head2 L
270              
271             # will carp and croak
272             make_path('foo/bar/baz', '/quz/blah');
273             remove_tree('foo/bar/baz', '/quz/blah');
274              
275             Note that we require L 2.08 or greater
276             because its interface has undergone several changes and its documentation
277             strongly recommends using this version or newer.
278              
279             =cut
280              
281 8     8   44 use constant _EXP_FILE_PATH => qw/make_path remove_tree/;
  8         12  
  8         450  
282 8     8   33 use File::Path 2.08 _EXP_FILE_PATH;
  8         174  
  8         594  
283             # File::Path is core since Perl 5.001
284             # File::Path 2.08 is core since Perl v5.11.1
285             push @EXPORT, _EXP_FILE_PATH;
286             $EXPORT_TAGS{"File::Path"} = [_EXP_FILE_PATH];
287              
288              
289             =head2 L
290              
291             find({ no_chdir=>1, wanted=>sub {
292             return if -d;
293             ...;
294             } }, @DIRS);
295              
296             =cut
297              
298 8     8   32 use constant _EXP_FILE_FIND => qw/find/;
  8         9  
  8         391  
299 8     8   32 use File::Find _EXP_FILE_FIND; # core since Perl 5
  8         15  
  8         741  
300             push @EXPORT, _EXP_FILE_FIND;
301             $EXPORT_TAGS{"File::Find"} = [_EXP_FILE_FIND];
302              
303              
304             =head2 L (selected)
305              
306             C (L) and C (L)
307              
308             =cut
309              
310 8     8   32 use constant _EXP_FCNTL => qw/LOCK_SH LOCK_EX LOCK_UN LOCK_NB SEEK_SET SEEK_CUR SEEK_END/;
  8         12  
  8         412  
311 8     8   34 use Fcntl _EXP_FCNTL; # core since Perl 5
  8         13  
  8         630  
312             push @EXPORT, _EXP_FCNTL;
313             $EXPORT_TAGS{"Fcntl"} = [_EXP_FCNTL];
314              
315              
316             =head2 L
317              
318             Nothing is exported; use these variables:
319             C<$FindBin::Bin>, C<$FindBin::Script>, C<$FindBin::RealBin>, and C<$FindBin::RealScript>
320              
321             =cut
322              
323 8     8   490 use FindBin (); # core since Perl 5.00307
  8         777  
  8         163  
324              
325              
326             =head2 L
327              
328             print Dumper(\%ENV);
329              
330             =cut
331              
332 8     8   27 use constant _EXP_DATA_DUMPER => qw/Dumper/;
  8         10  
  8         345  
333 8     8   660 use Data::Dumper _EXP_DATA_DUMPER; # core since Perl 5.005
  8         4758  
  8         642  
334             push @EXPORT, _EXP_DATA_DUMPER;
335             $EXPORT_TAGS{"Data::Dumper"} = [_EXP_DATA_DUMPER];
336              
337              
338             =head2 L (selected)
339              
340             my $nr = "123.45";
341             print "$nr looks like a number" if looks_like_numer($nr);
342              
343             =cut
344              
345 8     8   33 use constant _EXP_SCALAR_UTIL => qw/looks_like_number/;
  8         74  
  8         397  
346 8     8   34 use Scalar::Util _EXP_SCALAR_UTIL; # core since Perl v5.7.3
  8         12  
  8         661  
347             push @EXPORT, _EXP_SCALAR_UTIL;
348             $EXPORT_TAGS{"Scalar::Util"} = [_EXP_SCALAR_UTIL];
349              
350              
351             =head2 L (selected)
352              
353             # first is more efficient than grep for boolean tests
354             my $found = first { /3/ } 10..20;
355             my $maxval = reduce { $a > $b ? $a : $b } 1..10;
356              
357             =cut
358              
359 8     8   34 use constant _EXP_LIST_UTIL => qw/first reduce/;
  8         8  
  8         417  
360 8     8   35 use List::Util _EXP_LIST_UTIL; # core since Perl v5.7.3
  8         9  
  8         1106  
361             push @EXPORT, _EXP_LIST_UTIL;
362             $EXPORT_TAGS{"List::Util"} = [_EXP_LIST_UTIL];
363              
364              
365             1;
366             __END__