#!/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 ); ### 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 } } 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 "$! $@"; }