App-opan
view release on metacpan or search on metacpan
script/opan view on Meta::CPAN
do_merge(app);
$c->render(text => "$pan_path Added to opan\n");
};
push(@{app->commands->namespaces}, 'App::opan::Command');
helper cpan_url => sub { Mojo::URL->new($ENV{OPAN_MIRROR} || 'https://www.cpan.org/') };
my $nopin_static = Mojolicious::Static->new(
paths => [ 'pans/custom/dists' ]
);
my $pinset_static = Mojolicious::Static->new(
paths => [ 'pans/pinset/dists' ]
);
my $combined_static = Mojolicious::Static->new(
paths => [ 'pans/custom/dists', 'pans/pinset/dists' ]
);
my $base_static = Mojolicious::Static->new(
paths => [ 'pans' ]
);
foreach my $pan (qw(upstream nopin combined pinset custom)) {
get "/${pan}/modules/02packages.details.txt" => sub {
$base_static->dispatch($_[0]->stash(path => "${pan}/index"));
};
get "/${pan}/modules/02packages.details.txt.gz" => sub {
$base_static->dispatch($_[0]->stash(path => "${pan}/index.gz"));
};
}
my $serve_upstream = sub {
my ($c) = @_;
$c->render_later;
$c->ua->get(
$c->cpan_url.'authors/id/'.$c->stash->{dist_path},
sub {
my (undef, $tx) = @_;
$c->tx->res($tx->res);
$c->rendered;
}
);
return;
};
get '/upstream/authors/id/*dist_path' => $serve_upstream;
get '/combined/authors/id/*dist_path' => sub {
$_[0]->stash(path => $_[0]->stash->{dist_path});
$combined_static->dispatch($_[0]) or $serve_upstream->($_[0]);
};
get '/nopin/authors/id/*dist_path' => sub {
$_[0]->stash(path => $_[0]->stash->{dist_path});
$nopin_static->dispatch($_[0]) or $serve_upstream->($_[0]);
};
get "/autopin/modules/02packages.details.txt" => sub {
return $_[0]->render(text => 'Autopin off', status => 404)
unless $ENV{OPAN_AUTOPIN};
$base_static->dispatch($_[0]->stash(path => "nopin/index"));
};
get "/autopin/modules/02packages.details.txt.gz" => sub {
return $_[0]->render(text => 'Autopin off', status => 404)
unless $ENV{OPAN_AUTOPIN};
$base_static->dispatch($_[0]->stash(path => "nopin/index.gz"));
};
get '/autopin/authors/id/*dist_path' => sub {
return $_[0]->render(text => 'Autopin off', status => 404)
unless $ENV{OPAN_AUTOPIN};
return if $nopin_static->dispatch($_[0]->stash(path => $_[0]->stash->{dist_path}));
return if eval {
do_pin(app, $_[0]->stash->{path});
$pinset_static->dispatch($_[0]);
};
return $_[0]->render(text => 'Not found', status => 404);
};
caller() ? app : app->tap(sub { shift->log->level('fatal') })->start;
=head1 NAME
App::opan - A CPAN overlay for darkpan and pinning purposes
=head1 SYNOPSIS
Set up an opan (creates a directory tree in C<pans/>):
$ opan init
$ opan pin MSTROUT/M-1.tar.gz
$ opan add ./My-Dist-1.23.tar.gz
Now, you can start the server:
$ opan daemon -l http://localhost:8030/
Server available at http://localhost:8030/
Then in another terminal, run one of:
$ cpanm --mirror http://localhost:8030/combined/ --mirror-only --installdeps .
$ PERL_CARTON_MIRROR=http://localhost:8030/combined/ carton install
Or, to let opan do that part for you, skip starting the server and run one of:
$ opan cpanm --installdeps .
$ opan carton install
=head1 DESCRIPTION
Two basic approaches to using this thing. First, if you're using carton, you
can probably completely ignore the pinning system, so just do:
$ opan init
$ opan add ./My-DarkPan-Dist-1.23.tar.gz
$ git add pans/; git commit -m 'fresh opan'
$ opan carton install
You can reproduce this install with simply:
$ opan carton install --deployment
When you want to update to a new version of the cpan index (assuming you
already have an additional requirement that's too old in your current
snapshot):
$ opan pull
$ git add pans/; git commit -m 'update pans'
$ opan carton install
Second, if you're not using carton, but you want reproducible installs, you
can still mostly ignore the pinning system by doing:
$ opan init
$ opan add ./My-DarkPan-Dist-1.23.tar.gz
$ opan cpanm --autopin --installdeps .
$ git add pans/; git commit -m 'opan with current version pinning'
( run in 2.188 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )