File Coverage

blib/lib/App/TestOnTap/PackInfo.pm
Criterion Covered Total %
statement 27 89 30.3
branch 0 28 0.0
condition 0 3 0.0
subroutine 9 15 60.0
pod 0 1 0.0
total 36 136 26.4


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