Skip to content

Instantly share code, notes, and snippets.

@typester
Created March 2, 2010 05:46
Show Gist options
  • Save typester/319180 to your computer and use it in GitHub Desktop.
Save typester/319180 to your computer and use it in GitHub Desktop.
name 'sticky_version';
description 'Install dependency module';
synopsis 'PERL_CPANM_STICKY_VERSION=. cpanm --installdeps .';
author 'Daisuke Murase';
api_version 0.1;
my %deps = ();
use POSIX ();
hook init => sub {
my $args = shift;
my $app = $args->{app};
return unless $app->env('STICKY_VERSION');
unless ($app->{installdeps}) {
for my $module (grep {$_} split /:+/, $app->env('STICKY_VERSION')) {
my $dir = $app->fetch_module($module);
unless ($dir) {
$app->diag("! Couldn't find module or a distribution $module\n");
return;
}
if ($app->{seen}{$dir}++) {
$app->diag("Already built the distribution $dir. Skipping.\n");
return;
}
$app->chat("Entering $dir\n");
$app->chdir($app->{base});
$app->chdir($dir);
my($use_module_build, $configured, $configured_ok);
if (-e 'Makefile.PL') {
local $ENV{X_MYMETA} = 'YAML';
# NOTE: according to Devel::CheckLib, most XS modules exit
# with 0 even if header files are missing, to avoid receiving
# tons of FAIL reports in such cases. So exit code can't be
# trusted if it went well.
if ($app->configure("$app->{perl} Makefile.PL")) {
$configured_ok = -e 'Makefile';
}
$configured++;
}
if (-e 'MYMETA.yml') {
$app->chat("Checking dependencies from MYMETA.yml ...\n");
my $meta = $app->parse_meta('MYMETA.yml');
%deps = (%{$meta->{requires} || {}});
unless ($app->{notest}) {
%deps = (%deps, %{$meta->{build_requires} || {}}, %{$meta->{test_requires} || {}});
}
}
}
}
};
hook locate_dist => 0, sub {
my $args = shift;
return unless $args->{app}->env('STICKY_VERSION');
my $ver = $deps{ $args->{module} }
or return;
$args->{app}->chat("Searching $args->{module} $ver on search.cpan.org ...\n");
my $uri = "http://search.cpan.org/perldoc?$args->{module}";
my $html = $args->{app}->get($uri);
my ($dist) = $html
=~ m!<a href="/CPAN/authors/id/.*?([^/]*)\.(?:tar\.gz|tgz|tar\.bz2|zip)">!;
$dist =~ s/-[^\-]*$//;
$uri = "http://search.cpan.org/dist/${dist}-${ver}";
$html = $args->{app}->get($uri);
$html =~ m!<a href="/CPAN/authors/id/(.*?\.(?:tar\.gz|tgz|tar\.bz2|zip))">!
and return $args->{app}->cpan_uri($1);
return "http://github.com/gitpan/${dist}/tarball/${ver}";
};
hook find_deps => sub {
my $args = shift;
my $target = $args->{app}->env('STICKY_VERSION')
or return;
my $err;
while (my ($module, $ver) = each %{$args->{deps}}) {
if (grep { $_ eq $args->{module} } grep {$_} split /:+/, $target) {
if (defined $deps{$module}) {
$args->{app}->diag("! Dupe dependency definision: $module");
$err++;
last;
}
$deps{$module} = $ver || 0;
$args->{app}
->chat(qq[Added sticky dependency $module $ver from $args->{module}\n]);
}
else {
if (!defined($deps{$module}) and defined($ver)) {
$args->{app}
->diag(qq[! Unknown dependency found: $module $ver in $args->{module}\n]);
$err++;
}
}
}
POSIX::_exit(0) if $err; # XXX
};
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment