http://paperlined.org/dev/perl/non-root_cpan/setup_local_cpan.pl
#!/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 <unless $dont_test is true>
# - 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</a>#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; <PIN>};
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 (<PIN>) {
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</a>#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 <DATA>;
close FOUT;
# patch Local::Lib's Makefile.PL to allow us to override some CPAN::Config settings
open FIN, "<Makefile.PL" or die;
open FOUT, ">Makefile.2.PL" or die;
while (<FIN>) {
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;
Generated by GNU enscript 1.6.4.