1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
#!/usr/bin/perl -w
### Setup a "Good" Copy of @INC to use at runtime, and a
### temporary one to use at bootstrap time.
BEGIN {
use strict;
use warnings;
use Config;
use FindBin;
use File::Spec;
use File::Spec::Unix;
use vars qw[@RUN_TIME_INC $LIB_DIR $BUNDLE_DIR $BASE $PRIV_LIB];
$LIB_DIR = File::Spec->catdir( $FindBin::Bin, qw[.. lib] );
$BUNDLE_DIR = File::Spec->catdir( $FindBin::Bin, qw[.. inc bundle] );
### must set the PERL5LIB env var here as well, as some
### code in CPANPLUS resets it between iterations. So we
### have to set our 'final' perl5lib before loading any
### CPANPLUS code. The constants code is 'safe' but better
### safe than sorry. So duplicating the 'constants' behaviour
### of DOT_CPANPLUS
# use CPANPLUS::Internals::Constants;
my $who = getlogin || getpwuid($<) || $<;
$BASE = File::Spec->catfile(
$FindBin::Bin, '..', '.cpanplus', $who);
$PRIV_LIB = File::Spec->catfile( $BASE, 'lib' );
@RUN_TIME_INC = ($PRIV_LIB, @INC);
unshift @INC, $LIB_DIR, $BUNDLE_DIR;
### set it in the environment too, for when we shell out
### (like at 'perl makefile.pl' time.
$ENV{'PERL5LIB'} = join $Config{'path_sep'}, grep { defined }
$PRIV_LIB, # to find the boxed config
#$LIB_DIR, # the CPANPLUS libs
$ENV{'PERL5LIB'}; # original PERL5LIB
}
use FindBin;
use File::Find qw[find];
use CPANPLUS::Error;
use CPANPLUS::Configure;
use CPANPLUS::Internals::Constants;
use CPANPLUS::Internals::Utils;
### now, load in all the .pms from the bundle dir, so they're in
### memory. Skip the ones already loaded, and ignore failed requires.
### XXX this section *somehow* makes 'system(cmd.exe)' return immediately
### on win32, when run from cpanp-boxed (regular cpanp is fine). Probably
### need to load only a subsection of these modules, for safety sake.
{ for my $dir ( ($BUNDLE_DIR, $LIB_DIR) ) {
my $base_re = quotemeta $dir;
find( sub { my $file = $File::Find::name;
return unless -e $file && -f _ && -s _;
return if $file =~ /\._/; # osx temp files
### strip base dir. Might not end in / (or local
### dir delimiter), so remove that if needed too
$file =~ s/^$base_re(\W)?//;
### file already loaded.
return if $INC{$file};
### construct pm name and strip suffix
my $unixfile = File::Spec::Unix->catfile(
File::Spec->splitdir( $file )
);
my $pm = join '::', File::Spec->splitdir( $file );
$pm =~ s/\.pm$//i or return; # not a .pm file
### make sure we *DONT* load these blatantly
#return if $pm =~ /(?:IPC::Run::)|(?:File::Spec::)/;
eval "require $pm ; 1";
### if the require *FAILS* it's still added to %INC
### in some cases (mostly if a require in the required
### file fails or some such.. so remove it from our %INC!
if( $@ ) {
push @failures, $unixfile;
### dont enable warnings -- some modules
### are OS specific. Uncomment only for debug
### reasons
#warn $@;
}
}, $dir );
}
### delete AFTER we've loaded everything!
delete $INC{$_} for @failures;
### set @INC back to our non-bundled version
@INC = @RUN_TIME_INC;
}
### setup the configuration
my $ConfObj = CPANPLUS::Configure->new;
my $Config = CONFIG_BOXED;
my $Util = 'CPANPLUS::Internals::Utils';
my $ConfigFile = $ConfObj->_config_pm_to_file( $Config => $PRIV_LIB );
my $AutoFlush = File::Spec->catfile( $PRIV_LIB, split('::','CPANPLUS::Internals::Utils::Autoflush.pm') );
### setup the environment if needed
{ ### no base dir even, set it up
unless( IS_DIR->( $BASE ) ) {
$Util->_mkdir( dir => $BASE ) or die CPANPLUS::Error->stack_as_string;
}
### no config file exists yet, so we create it
unless( -e $ConfigFile ) {
### alter what needs changing
$ConfObj->set_conf( base => $BASE ); # new base dir
$ConfObj->set_conf( verbose => 1 ); # be verbose
$ConfObj->set_conf( prereqs => 1 ); # install prereqs
$ConfObj->save( $Config => $PRIV_LIB ); # save the pm in that dir
}
### no Autoflush exists yet, copy it from lib/
unless( -e $AutoFlush ) {
my $targ = File::Spec->catdir( $PRIV_LIB, split('::','CPANPLUS::Internals::Utils') );
$Util->_mkdir( dir => $targ );
$Util->_copy(
file => File::Spec->catfile( $LIB_DIR, split('::','CPANPLUS::Internals::Utils::Autoflush.pm') ),
to => $targ,
) or die CPANPLUS::Error->stack_as_string;
}
}
print qq[
===
Your boxed CPANPLUS install is setup to use:
Basedir: $BASE
Config: $ConfigFile
If you wish to save your boxed configuration, please type:
s save boxed
You can bootstrap your CPANPLUS by running:
s selfupdate dependencies
s selfupdate enabled_features
===
\n
];
### set the @INC to a runtime version, so our bundled modules
### are 'hidden' from probing, but loaded already for 'use' and
### 'require' statements
{ $Module::Load::Conditional::CHECK_INC_HASH = 1;
do File::Spec->catfile( $FindBin::Bin, 'cpanp' ) or die "$! $@";
}
|