| Filename | C:/tmp64ng/perl/vendor/lib/Portable.pm |
| Statements | Executed 90 statements in 0s |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 0s | 0s | Portable::BEGIN@51 |
| 1 | 1 | 1 | 0s | 0s | Portable::BEGIN@52 |
| 1 | 1 | 1 | 0s | 0s | Portable::BEGIN@53 |
| 1 | 1 | 1 | 0s | 0s | Portable::BEGIN@54 |
| 1 | 1 | 1 | 0s | 0s | Portable::BEGIN@55 |
| 4 | 1 | 1 | 0s | 0s | Portable::CORE:ftfile (opcode) |
| 0 | 0 | 0 | 0s | 0s | Portable::_ARRAY |
| 6 | 6 | 5 | 0s | 0s | Portable::_HASH |
| 2 | 2 | 1 | 0s | 0s | Portable::_STRING |
| 0 | 0 | 0 | 0s | 0s | Portable::applied |
| 1 | 1 | 1 | 0s | 78.0ms | Portable::apply |
| 0 | 0 | 0 | 0s | 0s | Portable::conf |
| 2 | 2 | 2 | 0s | 0s | Portable::config |
| 0 | 0 | 0 | 0s | 0s | Portable::cpan |
| 1 | 1 | 1 | 0s | 15.6ms | Portable::default |
| 1 | 1 | 1 | 0s | 0s | Portable::dist_dirs |
| 5 | 5 | 5 | 0s | 0s | Portable::dist_root |
| 1 | 1 | 1 | 0s | 0s | Portable::dist_volume |
| 0 | 0 | 0 | 0s | 0s | Portable::env |
| 0 | 0 | 0 | 0s | 0s | Portable::homedir |
| 1 | 1 | 1 | 0s | 78.0ms | Portable::import |
| 0 | 0 | 0 | 0s | 0s | Portable::minicpan |
| 1 | 1 | 1 | 0s | 0s | Portable::new |
| 0 | 0 | 0 | 0s | 0s | Portable::perlpath |
| 2 | 2 | 1 | 0s | 0s | Portable::portable_config |
| 3 | 3 | 2 | 0s | 0s | Portable::portable_cpan |
| 0 | 0 | 0 | 0s | 0s | Portable::portable_env |
| 3 | 3 | 2 | 0s | 0s | Portable::portable_homedir |
| 3 | 3 | 2 | 0s | 0s | Portable::portable_minicpan |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Portable; | ||||
| 2 | |||||
| 3 | =pod | ||||
| 4 | |||||
| 5 | =head1 NAME | ||||
| 6 | |||||
| 7 | Portable - Perl on a Stick | ||||
| 8 | |||||
| 9 | =head1 SYNOPSIS | ||||
| 10 | |||||
| 11 | Launch a script portably | ||||
| 12 | |||||
| 13 | F:\anywhere\perl.exe -MPortable script.pl | ||||
| 14 | |||||
| 15 | Have a script specifically request to run portably | ||||
| 16 | |||||
| 17 | #!/usr/bin/perl | ||||
| 18 | use Portable; | ||||
| 19 | |||||
| 20 | =head1 DESCRIPTION | ||||
| 21 | |||||
| 22 | "Portable" is a term used for applications that are installed onto a | ||||
| 23 | portable storage device (most commonly a USB memory stick) rather than | ||||
| 24 | onto a single host. | ||||
| 25 | |||||
| 26 | This technique has become very popular for Windows applications, as it | ||||
| 27 | allows a user to make use of their own software on typical publically | ||||
| 28 | accessible computers at libraries, hotels and internet cafes. | ||||
| 29 | |||||
| 30 | Converting a Windows application into portable form has a specific set | ||||
| 31 | of challenges, as the application has no access to the Windows registry, | ||||
| 32 | no access to "My Documents" type directories, and does not exist at a | ||||
| 33 | reliable filesystem path (because the portable storage medium can be | ||||
| 34 | mounted at an arbitrary volume or filesystem location). | ||||
| 35 | |||||
| 36 | B<Portable> provides a methodology and implementation to support | ||||
| 37 | the creating of "Portable Perl" applications and distributions. | ||||
| 38 | |||||
| 39 | While this will initially be focused on a Windows implementation, | ||||
| 40 | wherever possible the module will be built to be platform-agnostic | ||||
| 41 | in the hope that future versions can support other operating systems, | ||||
| 42 | or work across multiple operating systems. | ||||
| 43 | |||||
| 44 | This module is not ready for public use. For now, see the code for | ||||
| 45 | more details on how it works... | ||||
| 46 | |||||
| 47 | =head1 METHODS | ||||
| 48 | |||||
| 49 | =cut | ||||
| 50 | |||||
| 51 | 2 | 0s | 1 | 0s | # spent 0s within Portable::BEGIN@51 which was called:
# once (0s+0s) by ExtUtils::MakeMaker::Config::BEGIN@7 at line 51 # spent 0s making 1 call to Portable::BEGIN@51 |
| 52 | 2 | 0s | 2 | 0s | # spent 0s within Portable::BEGIN@52 which was called:
# once (0s+0s) by ExtUtils::MakeMaker::Config::BEGIN@7 at line 52 # spent 0s making 1 call to Portable::BEGIN@52
# spent 0s making 1 call to strict::import |
| 53 | 2 | 0s | 2 | 0s | # spent 0s within Portable::BEGIN@53 which was called:
# once (0s+0s) by ExtUtils::MakeMaker::Config::BEGIN@7 at line 53 # spent 0s making 1 call to Portable::BEGIN@53
# spent 0s making 1 call to warnings::import |
| 54 | 2 | 0s | 1 | 0s | # spent 0s within Portable::BEGIN@54 which was called:
# once (0s+0s) by ExtUtils::MakeMaker::Config::BEGIN@7 at line 54 # spent 0s making 1 call to Portable::BEGIN@54 |
| 55 | 2 | 0s | 1 | 0s | # spent 0s within Portable::BEGIN@55 which was called:
# once (0s+0s) by ExtUtils::MakeMaker::Config::BEGIN@7 at line 55 # spent 0s making 1 call to Portable::BEGIN@55 |
| 56 | |||||
| 57 | 1 | 0s | our $VERSION = '1.22'; | ||
| 58 | |||||
| 59 | # This variable is provided exclusively for the | ||||
| 60 | # use of test scripts. | ||||
| 61 | 1 | 0s | our $FAKE_PERL; | ||
| 62 | |||||
| 63 | # Globally-accessible flag to see if Portable is enabled. | ||||
| 64 | # Defaults to undef, because if Portable.pm is not loaded | ||||
| 65 | # AT ALL, $Portable::ENABLED returns undef anyways. | ||||
| 66 | 1 | 0s | our $ENABLED = undef; | ||
| 67 | |||||
| 68 | # Param-checking | ||||
| 69 | sub _STRING ($) { | ||||
| 70 | 2 | 0s | (defined $_[0] and ! ref $_[0] and length($_[0])) ? $_[0] : undef; | ||
| 71 | } | ||||
| 72 | # spent 0s within Portable::_HASH which was called 6 times, avg 0s/call:
# once (0s+0s) by Portable::default at line 207
# once (0s+0s) by Portable::new at line 147
# once (0s+0s) by Portable::CPAN::new at line 32 of Portable/CPAN.pm
# once (0s+0s) by Portable::Config::new at line 16 of Portable/Config.pm
# once (0s+0s) by Portable::minicpan::new at line 16 of Portable/minicpan.pm
# once (0s+0s) by Portable::HomeDir::new at line 18 of Portable/HomeDir.pm | ||||
| 73 | 6 | 0s | (ref $_[0] eq 'HASH' and scalar %{$_[0]}) ? $_[0] : undef; | ||
| 74 | } | ||||
| 75 | sub _ARRAY ($) { | ||||
| 76 | (ref $_[0] eq 'ARRAY' and @{$_[0]}) ? $_[0] : undef; | ||||
| 77 | } | ||||
| 78 | |||||
| 79 | # Package variables | ||||
| 80 | 1 | 0s | my %applied; | ||
| 81 | my $cache; | ||||
| 82 | |||||
| - - | |||||
| 87 | ##################################################################### | ||||
| 88 | # Pragma/Import Interface | ||||
| 89 | |||||
| 90 | # spent 78.0ms (0s+78.0) within Portable::import which was called:
# once (0s+78.0ms) by ExtUtils::MakeMaker::Config::BEGIN@7 at line 114 of Config.pm | ||||
| 91 | 1 | 0s | my $class = shift; | ||
| 92 | 1 | 0s | 1 | 78.0ms | $class->apply( @_ ? @_ : qw{ Config CPAN } ); # spent 78.0ms making 1 call to Portable::apply |
| 93 | } | ||||
| 94 | |||||
| 95 | # spent 78.0ms (0s+78.0) within Portable::apply which was called:
# once (0s+78.0ms) by Portable::import at line 92 | ||||
| 96 | # default %applied; | ||||
| 97 | 1 | 0s | my $class = shift; | ||
| 98 | 1 | 0s | 1 | 15.6ms | my $self = $class->default; # spent 15.6ms making 1 call to Portable::default |
| 99 | 1 | 0s | my %apply = map { $_ => 1 } @_; | ||
| 100 | 1 | 0s | if ( $apply{Config} and ! $applied{Config} ) { | ||
| 101 | 1 | 0s | 2 | 62.4ms | $self->config->apply($self); # spent 62.4ms making 1 call to Portable::Config::apply
# spent 0s making 1 call to Portable::config |
| 102 | 1 | 0s | $applied{Config} = 1; | ||
| 103 | 1 | 0s | $ENABLED = 1; | ||
| 104 | } | ||||
| 105 | 1 | 0s | if ( $apply{CPAN} and ! $applied{CPAN} and $self->cpan ) { | ||
| 106 | $self->cpan->apply($self); | ||||
| 107 | $applied{CPAN} = 1; | ||||
| 108 | $ENABLED = 1; | ||||
| 109 | } | ||||
| 110 | 1 | 0s | if ( $apply{HomeDir} and ! $applied{HomeDir} and $self->homedir ) { | ||
| 111 | $self->homedir->apply($self); | ||||
| 112 | $applied{HomeDir} = 1; | ||||
| 113 | $ENABLED = 1; | ||||
| 114 | } | ||||
| 115 | |||||
| 116 | # We don't need to do anything for CPAN::Mini. | ||||
| 117 | # It will load us instead (I think) | ||||
| 118 | |||||
| 119 | 1 | 0s | return 1; | ||
| 120 | } | ||||
| 121 | |||||
| 122 | sub applied { | ||||
| 123 | $applied{$_[1]}; | ||||
| 124 | } | ||||
| 125 | |||||
| - - | |||||
| 130 | ##################################################################### | ||||
| 131 | # Constructors | ||||
| 132 | |||||
| 133 | # spent 0s within Portable::new which was called:
# once (0s+0s) by Portable::default at line 213 | ||||
| 134 | 1 | 0s | my $class = shift; | ||
| 135 | 1 | 0s | my $self = bless { @_ }, $class; | ||
| 136 | |||||
| 137 | # Param checking | ||||
| 138 | 1 | 0s | unless ( exists $self->{dist_volume} ) { | ||
| 139 | die('Missing or invalid dist_volume param'); | ||||
| 140 | } | ||||
| 141 | 1 | 0s | 2 | 0s | unless ( _STRING($self->dist_dirs) ) { # spent 0s making 1 call to Portable::_STRING
# spent 0s making 1 call to Portable::dist_dirs |
| 142 | die('Missing or invalid dist_dirs param'); | ||||
| 143 | } | ||||
| 144 | 1 | 0s | 2 | 0s | unless ( _STRING($self->dist_root) ) { # spent 0s making 1 call to Portable::_STRING
# spent 0s making 1 call to Portable::dist_root |
| 145 | die('Missing or invalid dist_root param'); | ||||
| 146 | } | ||||
| 147 | 1 | 0s | 1 | 0s | unless ( _HASH($self->{portable}) ) { # spent 0s making 1 call to Portable::_HASH |
| 148 | die('Missing or invalid portable param'); | ||||
| 149 | } | ||||
| 150 | |||||
| 151 | # Compulsory support for Config.pm | ||||
| 152 | 1 | 0s | require Portable::Config; | ||
| 153 | 1 | 0s | 1 | 0s | $self->{Config} = Portable::Config->new( $self ); # spent 0s making 1 call to Portable::Config::new |
| 154 | |||||
| 155 | # Optional support for CPAN::Config | ||||
| 156 | 1 | 0s | 1 | 0s | if ( $self->portable_cpan ) { # spent 0s making 1 call to Portable::portable_cpan |
| 157 | 1 | 0s | require Portable::CPAN; | ||
| 158 | 1 | 0s | 1 | 0s | $self->{CPAN} = Portable::CPAN->new( $self ); # spent 0s making 1 call to Portable::CPAN::new |
| 159 | } | ||||
| 160 | |||||
| 161 | # Optional support for File::HomeDir | ||||
| 162 | 1 | 0s | 1 | 0s | if ( $self->portable_homedir ) { # spent 0s making 1 call to Portable::portable_homedir |
| 163 | 1 | 0s | require Portable::HomeDir; | ||
| 164 | 1 | 0s | 1 | 0s | $self->{HomeDir} = Portable::HomeDir->new( $self ); # spent 0s making 1 call to Portable::HomeDir::new |
| 165 | } | ||||
| 166 | |||||
| 167 | # Optional support for CPAN::Mini | ||||
| 168 | 1 | 0s | 1 | 0s | if ( $self->portable_minicpan ) { # spent 0s making 1 call to Portable::portable_minicpan |
| 169 | 1 | 0s | require Portable::minicpan; | ||
| 170 | 1 | 0s | 1 | 0s | $self->{minicpan} = Portable::minicpan->new( $self ); # spent 0s making 1 call to Portable::minicpan::new |
| 171 | } | ||||
| 172 | |||||
| 173 | 1 | 0s | return $self; | ||
| 174 | } | ||||
| 175 | |||||
| 176 | # spent 15.6ms (0s+15.6) within Portable::default which was called:
# once (0s+15.6ms) by Portable::apply at line 98 | ||||
| 177 | # state $cache; | ||||
| 178 | 1 | 0s | return $cache if $cache; | ||
| 179 | |||||
| 180 | # Get the perl executable location | ||||
| 181 | 1 | 0s | my $perlpath = ($ENV{HARNESS_ACTIVE} and $FAKE_PERL) ? $FAKE_PERL : $^X; | ||
| 182 | |||||
| 183 | # The path to Perl has a localized path. | ||||
| 184 | # G:\\strawberry\\perl\\bin\\perl.exe | ||||
| 185 | # Split it up, and search upwards to try and locate the | ||||
| 186 | # portable.perl file in the distribution root. | ||||
| 187 | 1 | 0s | 1 | 0s | my ($dist_volume, $d, $f) = Portable::FileSpec::splitpath($perlpath); # spent 0s making 1 call to Portable::FileSpec::splitpath |
| 188 | 1 | 0s | 1 | 0s | my @d = Portable::FileSpec::splitdir($d); # spent 0s making 1 call to Portable::FileSpec::splitdir |
| 189 | 1 | 0s | pop @d if @d > 0 && $d[-1] eq ''; | ||
| 190 | 4 | 0s | 8 | 0s | my @tmp = grep { # spent 0s making 4 calls to Portable::CORE:ftfile, avg 0s/call
# spent 0s making 4 calls to Portable::FileSpec::catpath, avg 0s/call |
| 191 | -f Portable::FileSpec::catpath( $dist_volume, $_, 'portable.perl' ) | ||||
| 192 | } | ||||
| 193 | map { | ||||
| 194 | 1 | 0s | 4 | 0s | Portable::FileSpec::catdir(@d[0 .. $_]) # spent 0s making 4 calls to Portable::FileSpec::catdir, avg 0s/call |
| 195 | } reverse ( 0 .. $#d ); | ||||
| 196 | 1 | 0s | my $dist_dirs = $tmp[0]; | ||
| 197 | 1 | 0s | unless ( defined $dist_dirs ) { | ||
| 198 | die("Failed to find the portable.perl file"); | ||||
| 199 | } | ||||
| 200 | |||||
| 201 | # Derive the main paths from the plain dirs | ||||
| 202 | 1 | 0s | 1 | 0s | my $dist_root = Portable::FileSpec::catpath($dist_volume, $dist_dirs, '' ); # spent 0s making 1 call to Portable::FileSpec::catpath |
| 203 | 1 | 0s | 1 | 0s | my $conf = Portable::FileSpec::catpath($dist_volume, $dist_dirs, 'portable.perl' ); # spent 0s making 1 call to Portable::FileSpec::catpath |
| 204 | |||||
| 205 | # Load the YAML file | ||||
| 206 | 1 | 0s | 1 | 15.6ms | my $portable = Portable::LoadYaml::load_file( $conf ); # spent 15.6ms making 1 call to Portable::LoadYaml::load_file |
| 207 | 1 | 0s | 1 | 0s | unless ( _HASH($portable) ) { # spent 0s making 1 call to Portable::_HASH |
| 208 | die("Missing or invalid portable.perl file"); | ||||
| 209 | } | ||||
| 210 | |||||
| 211 | # Hand off to the main constructor, | ||||
| 212 | # cache the result and return it | ||||
| 213 | 1 | 0s | 1 | 0s | $cache = __PACKAGE__->new( # spent 0s making 1 call to Portable::new |
| 214 | dist_volume => $dist_volume, | ||||
| 215 | dist_dirs => $dist_dirs, | ||||
| 216 | dist_root => $dist_root, | ||||
| 217 | conf => $conf, | ||||
| 218 | perlpath => $perlpath, | ||||
| 219 | portable => $portable, | ||||
| 220 | ); | ||||
| 221 | } | ||||
| 222 | |||||
| - - | |||||
| 227 | ##################################################################### | ||||
| 228 | # Configuration Accessors | ||||
| 229 | |||||
| 230 | # spent 0s within Portable::dist_volume which was called:
# once (0s+0s) by Portable::Config::apply at line 83 of Portable/Config.pm | ||||
| 231 | 1 | 0s | $_[0]->{dist_volume}; | ||
| 232 | } | ||||
| 233 | |||||
| 234 | # spent 0s within Portable::dist_dirs which was called:
# once (0s+0s) by Portable::new at line 141 | ||||
| 235 | 1 | 0s | $_[0]->{dist_dirs}; | ||
| 236 | } | ||||
| 237 | |||||
| 238 | # spent 0s within Portable::dist_root which was called 5 times, avg 0s/call:
# once (0s+0s) by Portable::minicpan::new at line 25 of Portable/minicpan.pm
# once (0s+0s) by Portable::HomeDir::new at line 27 of Portable/HomeDir.pm
# once (0s+0s) by Portable::Config::new at line 23 of Portable/Config.pm
# once (0s+0s) by Portable::CPAN::new at line 41 of Portable/CPAN.pm
# once (0s+0s) by Portable::new at line 144 | ||||
| 239 | 5 | 0s | $_[0]->{dist_root}; | ||
| 240 | } | ||||
| 241 | |||||
| 242 | sub conf { | ||||
| 243 | $_[0]->{conf}; | ||||
| 244 | } | ||||
| 245 | |||||
| 246 | sub perlpath { | ||||
| 247 | $_[0]->{perlpath}; | ||||
| 248 | } | ||||
| 249 | |||||
| 250 | # spent 0s within Portable::portable_cpan which was called 3 times, avg 0s/call:
# once (0s+0s) by Portable::CPAN::new at line 32 of Portable/CPAN.pm
# once (0s+0s) by Portable::CPAN::new at line 40 of Portable/CPAN.pm
# once (0s+0s) by Portable::new at line 156 | ||||
| 251 | 3 | 0s | $_[0]->{portable}->{CPAN}; | ||
| 252 | } | ||||
| 253 | |||||
| 254 | # spent 0s within Portable::portable_config which was called 2 times, avg 0s/call:
# once (0s+0s) by Portable::Config::new at line 16 of Portable/Config.pm
# once (0s+0s) by Portable::Config::new at line 22 of Portable/Config.pm | ||||
| 255 | 2 | 0s | $_[0]->{portable}->{Config}; | ||
| 256 | } | ||||
| 257 | |||||
| 258 | # spent 0s within Portable::portable_homedir which was called 3 times, avg 0s/call:
# once (0s+0s) by Portable::HomeDir::new at line 26 of Portable/HomeDir.pm
# once (0s+0s) by Portable::HomeDir::new at line 18 of Portable/HomeDir.pm
# once (0s+0s) by Portable::new at line 162 | ||||
| 259 | 3 | 0s | $_[0]->{portable}->{HomeDir}; | ||
| 260 | } | ||||
| 261 | |||||
| 262 | # spent 0s within Portable::portable_minicpan which was called 3 times, avg 0s/call:
# once (0s+0s) by Portable::minicpan::new at line 16 of Portable/minicpan.pm
# once (0s+0s) by Portable::minicpan::new at line 24 of Portable/minicpan.pm
# once (0s+0s) by Portable::new at line 168 | ||||
| 263 | 3 | 0s | $_[0]->{portable}->{minicpan}; | ||
| 264 | } | ||||
| 265 | |||||
| 266 | sub portable_env { | ||||
| 267 | $_[0]->{portable}->{Env}; | ||||
| 268 | } | ||||
| 269 | |||||
| 270 | # spent 0s within Portable::config which was called 2 times, avg 0s/call:
# once (0s+0s) by Portable::CPAN::new at line 60 of Portable/CPAN.pm
# once (0s+0s) by Portable::apply at line 101 | ||||
| 271 | 2 | 0s | $_[0]->{Config}; | ||
| 272 | } | ||||
| 273 | |||||
| 274 | sub cpan { | ||||
| 275 | $_[0]->{CPAN}; | ||||
| 276 | } | ||||
| 277 | |||||
| 278 | sub homedir { | ||||
| 279 | $_[0]->{HomeDir}; | ||||
| 280 | } | ||||
| 281 | |||||
| 282 | sub minicpan { | ||||
| 283 | $_[0]->{minicpan}; | ||||
| 284 | } | ||||
| 285 | |||||
| 286 | sub env { | ||||
| 287 | $_[0]->{Env}; | ||||
| 288 | } | ||||
| 289 | |||||
| 290 | 1 | 0s | 1; | ||
| 291 | |||||
| 292 | =pod | ||||
| 293 | |||||
| 294 | =head1 SUPPORT | ||||
| 295 | |||||
| 296 | Bugs should be reported via the CPAN bug tracker. | ||||
| 297 | |||||
| 298 | L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Portable> | ||||
| 299 | |||||
| 300 | For other issues, or commercial support, contact the author. | ||||
| 301 | |||||
| 302 | =head1 AUTHOR | ||||
| 303 | |||||
| 304 | Adam Kennedy E<lt>adamk@cpan.orgE<gt> | ||||
| 305 | |||||
| 306 | =head1 SEE ALSO | ||||
| 307 | |||||
| 308 | L<http://win32.perl.org/> | ||||
| 309 | |||||
| 310 | =head1 COPYRIGHT | ||||
| 311 | |||||
| 312 | Copyright 2008 - 2011 Adam Kennedy. | ||||
| 313 | |||||
| 314 | This program is free software; you can redistribute | ||||
| 315 | it and/or modify it under the same terms as Perl itself. | ||||
| 316 | |||||
| 317 | The full text of the license can be found in the | ||||
| 318 | LICENSE file included with this module. | ||||
| 319 | |||||
| 320 | =cut | ||||
# spent 0s within Portable::CORE:ftfile which was called 4 times, avg 0s/call:
# 4 times (0s+0s) by Portable::default at line 190, avg 0s/call |