File Coverage

blib/lib/App/TestOnTap/PackInfo.pm
Criterion Covered Total %
statement 33 95 34.7
branch 0 28 0.0
condition 0 3 0.0
subroutine 11 17 64.7
pod 0 1 0.0
total 44 144 30.5


line stmt bran cond sub pod time code
1             package App::TestOnTap::PackInfo;
2              
3 19     19   129 use strict;
  19         43  
  19         580  
4 19     19   97 use warnings;
  19         46  
  19         1235  
5              
6             our $VERSION = '1.001';
7             my $version = $VERSION;
8             $VERSION = eval $VERSION;
9              
10 19     19   131 use App::TestOnTap::Util qw(slashify $IS_WINDOWS $IS_PACKED $SHELL_ARG_DELIM $FILE_SEP);
  19         87  
  19         2672  
11              
12 19     19   135 use Config qw(myconfig);
  19         41  
  19         1098  
13 19     19   9442 use ExtUtils::Installed;
  19         1984181  
  19         782  
14 19     19   164 use File::Basename;
  19         44  
  19         1213  
15 19     19   127 use File::Slurp qw(write_file);
  19         40  
  19         763  
16 19     19   110 use File::Spec;
  19         43  
  19         408  
17 19     19   91 use File::Temp qw(tempfile tempdir);
  19         42  
  19         911  
18 19     19   615 use FindBin qw($RealBin $RealScript);
  19         1073  
  19         1714  
19 19     19   127 use POSIX;
  19         40  
  19         170  
20              
21             sub handle
22             {
23 0     0 0   my $opts = shift;
24 0           my $version = shift;
25 0           my $_argsPodName = shift;
26 0           my $_argsPodInput = shift;
27 0           my $argsPodName = shift;
28 0           my $argsPodInput = shift;
29 0           my $manualPodName = shift;
30 0           my $manualPodInput = shift;
31              
32 0 0         die("Only one of --_pp, --_pp_script, --_pp_info allowed\n") if grep(/^_(pp)$/, keys(%$opts)) > 1;
33 0 0         if ($opts->{_pp}) { _pp($opts, $version, $_argsPodName, $_argsPodInput, $argsPodName, $argsPodInput, $manualPodName, $manualPodInput); }
  0 0          
    0          
34 0           elsif ($opts->{_pp_script}) { _pp_script($opts, $version, $_argsPodName, $_argsPodInput, $argsPodName, $argsPodInput, $manualPodName, $manualPodInput); }
35 0           elsif ($opts->{_pp_info}) { _pp_info($opts); }
36 0           else { die("INTERNAL ERROR"); }
37            
38 0           exit(0);
39             }
40              
41             sub _pp_script
42             {
43 0     0     my $scriptFile = __internal_pp_script(@_);
44 0           print "Wrote script '$scriptFile'\n";
45             }
46              
47             sub _pp
48             {
49 0     0     my $tmpDir = tempdir('testontap_ppscript_XXXX', TMPDIR => 1, CLEANUP => 1);
50 0           $_[0]->{_pp_script} = "$tmpDir/testontap_pp.pl";
51 0           my $scriptFile = __internal_pp_script(@_);
52 0           system("$^X $SHELL_ARG_DELIM$scriptFile$SHELL_ARG_DELIM");
53             }
54              
55             sub _pp_info
56             {
57 0     0     my $opts = shift;
58              
59 0 0         die("Sorry, you're not running a binary/packed instance\n") unless $IS_PACKED;
60              
61 0           print "$0\n";
62 0           foreach my $sec (qw(USERNAME HOSTNAME CONFIG ENV MODULES CMD))
63             {
64 0           print "### $sec BEGIN\n";
65 0           print PAR::read_file("TESTONTAP_${sec}_FILE");
66 0           print "### $sec END\n";
67             }
68             }
69              
70             ###
71              
72             sub __construct_outfilename
73             {
74 0     0     my $version = shift;
75            
76 0 0         my $os = $IS_WINDOWS ? 'windows' : $^O;
77 0           my $arch = (POSIX::uname())[4];
78 0 0         my $exeSuffix = $IS_WINDOWS ? '.exe' : '';
79 0           my $bnScript = basename($RealScript);
80            
81 0           return "$bnScript-$version-$os-$arch$exeSuffix";
82             }
83              
84             sub __internal_pp_script
85             {
86 0     0     my $opts = shift;
87 0           my $version = shift;
88 0           my $_argsPodName = shift;
89 0           my $x__argsPodInput = slashify(File::Spec->rel2abs(shift), '/');
90 0           my $argsPodName = shift;
91 0           my $x_argsPodInput = slashify(File::Spec->rel2abs(shift), '/');
92 0           my $manualPodName = shift;
93 0           my $x_manualPodInput = slashify(File::Spec->rel2abs(shift), '/');
94              
95 0 0         die("Sorry, you're already running a binary/packed instance\n") if $IS_PACKED;
96            
97 0           my $scriptFile = slashify(File::Spec->rel2abs($opts->{_pp_script}));
98 0 0         die("The path '$scriptFile' already exists\n") if -e $scriptFile;
99            
100 0           my $x_input = slashify("$RealBin/$RealScript", '/');
101 0           my $x_output = __construct_outfilename($version);
102 0 0         my $x_verbose = $opts->{verbose} ? 1 : 0;
103 0           my $x_fsep = $FILE_SEP;
104 0 0         $x_fsep .= "\\" if $x_fsep eq "\\";
105              
106 0           my $x_liblocs = "my \@liblocs;\n";
107 0           foreach my $libloc (@INC)
108             {
109 0 0 0       next if ($libloc eq '.' || ref($libloc));
110 0           $x_liblocs .= "push(\@liblocs, '-I', '" . slashify(File::Spec->rel2abs($libloc), '/') . "');\n";
111             }
112 0           chomp($x_liblocs);
113            
114 0           my $script = <
115             #! $^X
116             use strict;
117             use warnings;
118              
119             use Config qw(myconfig);
120             use ExtUtils::Installed;
121             use File::Basename;
122             use File::Slurp qw(write_file);
123             use File::Spec;
124             use File::Temp qw(tempfile);
125             use Getopt::Long;
126             use Net::Domain qw(hostfqdn);
127              
128             \$| = 1;
129              
130             eval "require PAR::Packer";
131             die("Sorry, PAR:Packer is not installed/working!\\n") if \$@;
132              
133             my \$IS_WINDOWS = \$^O eq 'MSWin32';
134              
135             my \$_argsPodInput = slashify(File::Spec->rel2abs('$x__argsPodInput'));
136             my \$argsPodInput = slashify(File::Spec->rel2abs('$x_argsPodInput'));
137             my \$manualPodInput = slashify(File::Spec->rel2abs('$x_manualPodInput'));
138              
139             my \$outfile = slashify(File::Spec->rel2abs('$x_output'));
140             my \$verbose = $x_verbose;
141             my \$debug = 0;
142             my \$info = 1;
143             GetOptions('outfile=s' => \\\$outfile, 'verbose!' => \\\$verbose, 'info!' => \\\$info, 'debug' => \\\$debug) || usage();
144             \$verbose = 1 if \$debug;
145              
146             my \$outdir = dirname(\$outfile);
147             die("The output directory doesn't exist: '\$outdir'\\n") unless -d \$outdir;
148             die("The outfile exists: '\$outfile'\\n") if -e \$outfile;
149              
150             print "Getting username...\\n" if \$verbose;
151             my (undef, \$usernameFile) = tempfile('testontap_username_XXXX', TMPDIR => 1, UNLINK => 1);
152             if (\$info)
153             {
154             my \$username = \$IS_WINDOWS ? getlogin() : scalar(getpwuid(\$<));
155             write_file(\$usernameFile, "\$username\\n") || die("Failed to write '\$usernameFile': $!\\n");
156             }
157              
158             print "Getting hostname...\\n" if \$verbose;
159             my (undef, \$hostnameFile) = tempfile('testontap_hostname_XXXX', TMPDIR => 1, UNLINK => 1);
160             if (\$info)
161             {
162             my \$hostname = hostfqdn();
163             write_file(\$hostnameFile, "\$hostname\\n") || die("Failed to write '\$hostnameFile': $!\\n");
164             }
165              
166             print "Getting environment...\\n" if \$verbose;
167             my (undef, \$envFile) = tempfile('testontap_env_XXXX', TMPDIR => 1, UNLINK => 1);
168             if (\$info)
169             {
170             my \$env = getEnv();
171             write_file(\$envFile, \$env) || die("Failed to write '\$envFile': $!\\n");
172             }
173              
174             print "Getting config...\\n" if \$verbose;
175             my (undef, \$configFile) = tempfile('testontap_config_XXXX', TMPDIR => 1, UNLINK => 1);
176             if (\$info)
177             {
178             my \$config = myconfig();
179             write_file(\$configFile, \$config) || die("Failed to write '\$configFile': \$!\\n");
180             }
181            
182             print "Getting modules...\\n" if \$verbose;
183             my (undef, \$modulesFile) = tempfile('testontap_modules_XXXX', TMPDIR => 1, UNLINK => 1);
184             if (\$info)
185             {
186             my \$modules = find_modules();
187             write_file(\$modulesFile, \$modules) || die("Failed to write '\$modulesFile': $!\\n");
188             }
189              
190             print "Getting cmd...\\n" if \$verbose;
191             my (undef, \$cmdFile) = tempfile('testontap_cmd_XXXX', TMPDIR => 1, UNLINK => 1);
192              
193             $x_liblocs
194             \$_ = slashify(\$_) foreach (\@liblocs);
195              
196             my \@cmd =
197             (
198             'pp',
199             \$verbose ? ("--verbose=\$verbose") : (),
200             \@liblocs,
201             '-a', "\$_argsPodInput;lib/$_argsPodName",
202             '-a', "\$argsPodInput;lib/$argsPodName",
203             '-a', "\$manualPodInput;lib/$manualPodName",
204             '-a', "\$cmdFile;TESTONTAP_CMD_FILE",
205             '-a', "\$configFile;TESTONTAP_CONFIG_FILE",
206             '-a', "\$modulesFile;TESTONTAP_MODULES_FILE",
207             '-a', "\$usernameFile;TESTONTAP_USERNAME_FILE",
208             '-a', "\$hostnameFile;TESTONTAP_HOSTNAME_FILE",
209             '-a', "\$envFile;TESTONTAP_ENV_FILE",
210             '-M', 'Encode::*',
211             '-o', \$outfile,
212             slashify(File::Spec->rel2abs('$x_input'))
213             );
214              
215             my \@cmdCopy = \@cmd;
216             \$_ .= "\\n" foreach (\@cmdCopy);
217             if (\$info)
218             {
219             write_file(\$cmdFile, { binmode => ':raw' }, \@cmdCopy) || die("Failed to write '\$cmdFile': \$!\\n");
220             }
221              
222             if (\$verbose)
223             {
224             print "Packing to '\$outfile' using:\\n";
225             print " \$_\\n" foreach (\@cmd);
226             }
227             else
228             {
229             print "Packing to '\$outfile'...";
230             }
231              
232             if (\$debug)
233             {
234             print "username file : \$usernameFile\\n";
235             print "hostname file : \$hostnameFile\\n";
236             print "config file : \$configFile\\n";
237             print "env file : \$envFile\\n";
238             print "modules file : \$modulesFile\\n";
239             print "cmd file : \$cmdFile\\n";
240             print "Continue? (no) : ";
241             my \$ans = ;
242             exit(1) unless \$ans =~ /^\\s*yes\\s*\$/i;
243             }
244              
245             my \$xit = system(\@cmd) >> 8;
246             die("\\nError during packing: \$xit\\n") if \$xit;
247             print "done\\n";
248              
249             exit(0);
250              
251             ###
252              
253             sub getEnv
254             {
255             my \$env = '';
256             \$env .= "\$_ => '\$ENV{\$_}'\\n" foreach (sort(keys(\%ENV)));
257            
258             return \$env;
259             }
260              
261             sub find_modules
262             {
263             my \$ei = ExtUtils::Installed->new(skip_cwd => 1);
264              
265             my \$modules = '';
266             foreach my \$module (sort(\$ei->modules()))
267             {
268             my \$ver = \$ei->version(\$module);
269             \$modules .= "\$module => \$ver\\n";
270             }
271            
272             return \$modules;
273             }
274              
275             sub slashify
276             {
277             my \$s = shift;
278             my \$fsep = shift || '$x_fsep';
279              
280             my \$dblStart = \$s =~ s#^[\\\\/]{2}##;
281             \$s =~ s#[/\\\\]+#\$fsep#g;
282              
283             return \$dblStart ? "\$fsep\$fsep\$s" : \$s;
284             }
285              
286             sub usage
287             {
288             print <
289             Usage: \$0
290             [--outfile ]
291             [--verbose || --no-verbose];
292             [--info || --no-info]
293              
294             Creates a testontap binary with a default name of '$x_output'.
295             Use '--outfile' to change.
296              
297             Use '--verbose' or '--no-verbose' to turn on/off verboseness.
298             Defaults to verboseness when script was created (currently '$x_verbose').
299              
300             By default a number of information parts is embedded in the packed file (to be printed
301             with '--_pp_info'). Use '--no-info' to embed blank data only.
302             USAGE
303             exit(42);
304             }
305             SCRIPT
306              
307 0 0         write_file($scriptFile, $script) || die("Failed to write '$scriptFile': $!\n");
308            
309 0 0         if (!$IS_WINDOWS)
310             {
311 0           my $mode = (stat($scriptFile))[2];
312 0           $mode |= 0100;
313 0           chmod($mode, $scriptFile);
314             }
315            
316 0           return $scriptFile;
317             }
318              
319             1;