#!/usr/bin/perl # - TODO: include our own hard-coded dist=>module mapping # (on EVERY SINGLE install line), and use # # - patch local-lib-1.004009/Makefile.PL to include some bits that # modify the CPAN::Config in almost the exact same way as # the if($no_manpages) code further down does, # but it has to do it RIGHT BEFORE the # if(length $cpan_command) # line. BEGIN {$ENV{HTTP_PROXY} = "http://172.28.97.18:8080/"} use strict; use warnings; use LWP::Simple; use File::Spec; use Data::Dumper; my $PREFIX = File::Spec->rel2abs("."); $ENV{PERL5LIB} = join(":", "$PREFIX/lib", "$PREFIX/lib/perl5", "$PREFIX/lib/site_perl", "$PREFIX/lib/perl5/site_perl"); # DEBUG: uncomment to see the full results of setting PERL5LIB print "$ENV{PERL5LIB}\n"; exit #system($^X, "-MData::Dumper", "-e", 'print Dumper \@INC'); exit; mkdir("build"); my %dont_test = map {$_,1} qw[ ]; my %test_but_ignore_results = map {$_,1} qw[ ExtUtils-MakeMaker ExtUtils-ParseXS Test-Simple Test-Builder-Tester Pod-Simple ]; # Local::Lib is what we're really going for, but it has some prerequisites that we need to install in a more-or-less hard-coded fashion. # Once Local::Lib is installed, we should be able to install things in the proper way. # # The syntax is: # dist-name/Module::Name # where the module name can just be "::" to indicate that it's the same as the dist-name, but with dashes converted to colons. install(qw[ ExtUtils-MakeMaker/:: Test-Simple/:: File-Temp/:: Test-Harness/:: Test-Builder-Tester/:: Pod-Escapes/:: Test/:: Pod-Simple/:: Scalar-List-Utils/List::Util PathTools/File::Spec ExtUtils-Install/:: ExtUtils-CBuilder/:: Module-Build/:: ExtUtils-ParseXS/ExtUtils::ParseXS CPAN/:: IO-Compress-Base/:: Compress-Raw-Bzip2/:: IO-Compress-Bzip2/:: Compress-Raw-Zlib/:: IO-Compress/IO::Compress::Gzip Compress-Zlib/:: IO-Zlib/:: Package-Constants/:: Algorithm-Diff/:: Text-Diff/:: Getopt-Long/:: ]); 0 && download_makefilepl_maketest_install("local-lib", "build", 0, "--bootstrap=$PREFIX"); # now get a couple of other minimal things up and running so CPAN can function properly 0 && install("Test-Harness"); 0 && download_makefilepl_maketest_install("Archive-Tar", "build", 0, 0, "-d"); sub install { foreach my $dist_name (@_) { (my $dist_only = $dist_name) =~ s#/.*##; download_makefilepl_maketest_install($dist_name, "build", exists $dont_test{$dist_only}, exists $test_but_ignore_results{$dist_only}); } } # does several things: # - downloads # - extracts # - runs perl Makefile.PL # - runs make # - runs make test # - runs make install sub download_makefilepl_maketest_install { my $dist_name = shift; my $build_dirname = shift; my $dont_test = shift || 0; my $ignore_test_results = shift || 0; my @other_MakefilePL_args = @_; my $last_dir = File::Spec->rel2abs("."); my $expanded_dir = download_CPAN_module($dist_name, $build_dirname); return unless ($expanded_dir =~ /\S/); chdir($expanded_dir); my $test_results; if (-e "Makefile.PL") { system($^X, "Makefile.PL", "PREFIX=$PREFIX", @other_MakefilePL_args) && exit 1; system("make") && exit 1; if (!$dont_test) { if ($ignore_test_results) { system("make test"); } else { system("make test") && exit 1; } } system("make install") && exit 1; } elsif (-e "Build.PL") { system($^X, "Build.PL", "PREFIX=$PREFIX", @other_MakefilePL_args) && exit 1; system("Build") && exit 1; if (!$dont_test) { if ($ignore_test_results) { system("Build", "test"); } else { system("Build", "test") && exit 1; } } system("Build", "install") && exit 1; } else { die "I don't know how to build $last_dir\n\t"; } chdir($last_dir); } # determines the latest version of a CPAN module, # downloads its file, # expands its tarball into the current directory, # and return the name of the subdirectory it was extracted to, if any sub download_CPAN_module { my $dist_name = shift; # for example, if you want "http://search.cpan.org/dist/DBI/", this is just "DBI" my $extract_to_directory = shift || "."; my ($dist_only, $module_name) = split m#/#, $dist_name, 2; if ($module_name eq '::') { # syntactic sugar ($module_name = $dist_only) =~ s/-/::/g; } my $html = get "http://search.cpan.org/dist/$dist_only/"; if (!defined($html)) { die "Unable to download 'http://search.cpan.org/dist/$dist_only/'\n\t"; } my ($url) = ($html =~ m#"([^">]+\.tar\.gz)">Download#i); (my $filename = $url) =~ s#.*/##; $url = "http://search.cpan.org$url"; my ($latest_version) = ($url =~ m#-([.0-9_]*)\.tar\.gz$#i); my $original_latest_version = $latest_version; # if they provided a module name (in addition to the dist name), we can check if it's already installed, and skip a lot of work if ($module_name && $latest_version) { $latest_version =~ s/_//g; my $pid = open PIN, "-|"; defined($pid) or die; if ($pid == 0) { #close STDOUT; close STDERR; #close STDERR; exec($^X, "-eeval {require ${module_name}}; exit 1 if \$\@; print \$${module_name}::VERSION"); } my $current_version = do {local $/=undef; }; my $exit_status = ($? >> 8); if (($? >> 8) || !$current_version || $current_version < $latest_version) { $current_version ||= "(none)"; print "Need to download $module_name (wanted $latest_version, currently have $current_version)\n"; } else { #print "$exit_status Currently-installed version of $filename is good enough (needed >>$module_name<< >>$latest_version<<).\n"; return ""; print "Already have the latest version of $module_name ($original_latest_version).\n"; return ""; } #else {print "wanted: $latest_version $module_name, got exit status: $exit_status\n"; exit} } ##my $current_module = CPAN::Shell->expand("Distribution", $dist_only); ##my $current_version = $current_module ? $current_module->inst_version : undef; #print "latest version of $dist_only is $latest_version, current installed version is $current_version\n"; exit; # ^^^ this doesn't work because CPAN doesn't/can't have its index files until after we finish bootstrapping print "\n", "="x79, "\n"; print "Downloading $url ...\n"; (my $expected_dir = $url) =~ s#.*/|\.tar\.gz$##sig; $expected_dir = File::Spec->catdir($extract_to_directory, $expected_dir); LWP::Simple::getstore($url, $filename); if (!-e $filename) { die "Unable to download $url.\n\t"; } if (-d $expected_dir) { system "rm", "-rf", "--", $expected_dir; } local *PIN; my $abs_filename = File::Spec->rel2abs($filename); open PIN, "cd $extract_to_directory; gzip -dc $abs_filename | tar -xvf- |" or die; my $ret; while () { s/[\n\r\s]+$//s; s/^\S\s//s; next unless m#^([^/]*)/#; my $combined = File::Spec->catdir($extract_to_directory, $1); #print "-->$combined<--\n"; if (-d $combined) { # if this is a directory name, then we're done $ret ||= $combined; } } close PIN; unlink($filename); return $ret; } __END__ ########################### download Local::Lib ######################## ## figure out what the latest version of Local::Lib is my ($local_lib_latest_version) = ($local_lib_summary =~ m#/([^/">]+)\.tar\.gz">Download#i); #if (grep /^--clean$/, @ARGV) { print "Completely removing your personal CPAN archive...\n"; system "rm", "-rf", "$ENV{HOME}/.cpan/", $local_lib_latest_version; # exit; #} my $local_lib_URL = "http://search.cpan.org/CPAN/authors/id/A/AP/APEIRON/$local_lib_latest_version.tar.gz"; print "Downloading $local_lib_URL ...\n"; my $tarball = LWP::Simple::get($local_lib_URL); open POUT, "| gzip -dc - | tar -xvf -" or die; print POUT $tarball; close POUT; chdir($local_lib_latest_version); open FOUT, ">cpan_config_patch" or die; print FOUT ; close FOUT; # patch Local::Lib's Makefile.PL to allow us to override some CPAN::Config settings open FIN, "Makefile.2.PL" or die; while () { if (/PERL_MM_USE_DEFAULT/) { print FOUT q{ system($^X, "cpan_config_patch"); # do some custom changes to CPAN::Config}, "\n"; } print FOUT $_; } close FIN; close FOUT; ########################## run Local::Lib's Makefile.PL ########################## # from .../eg/scripted_install.pl use Cwd; use File::Spec; my $target = $ENV{TARGET} ? Cwd::abs_path($ENV{TARGET}) : undef; my $bootstrap = $target ? "--bootstrap=$target" : "--bootstrap"; system($^X, 'Makefile.2.PL', $bootstrap) && exit 1; system('make', 'test') && exit 1; system('make', 'install') && exit 1; ########################## run Local::Lib's Makefile.PL ########################## exit; eval <<'EOF'; use CPAN; use Cwd; use File::Spec; my $target = $ENV{TARGET} ? Cwd::abs_path($ENV{TARGET}) : undef; my $mod = CPAN::Shell->expand(Module => "local::lib"); $mod->get; my $dir = CPAN::Shell->expand(Distribution => $mod->cpan_file)->dir; chdir($dir); my $make = $CPAN::Config->{make}; #my $make = "make"; my $bootstrap = $target ? "--bootstrap=$target" : "--bootstrap"; #my $bootstrap = "--bootstrap"; system($^X, 'Makefile.PL', $bootstrap) && exit 1; system($make, 'test') && exit 1; system($make, 'install') && exit 1; EOF __DATA__ # CPAN overrides use warnings; use strict; use Data::Dumper; use CPAN; CPAN::Config->load; $CPAN::Config->{urllist} = ["http://www.perl.com/CPAN/", "http://cpan.uchicago.edu/pub/CPAN/"]; $CPAN::Config->{http_proxy} = "http://172.28.97.18:8080/"; $CPAN::Config->{http_proxy} = "http://172.28.97.18:8080/"; $CPAN::Config->{sitelib} = $CPAN::Config->{cpan_home}; CPAN::Config->commit;