App-opan
view release on metacpan or search on metacpan
Revision history for App-opan
0.003005 - 2021-04-13
- Avoid upload test requiring https
0.003004 - 2021-04-12
- Switch default cpan URL to https for security
0.003003 - 2021-03-21
- Bump Mojolicious dep to avoid 'format' footgun
- Fixup routing names for Mojolicious 9+
0.003002 - 2019-05-09
- Document OPAN_MIRROR
- Remove big scary warning
0.003001 - 2018-10-18
- Serve 02packages for all pans for easier introspection
0.003000 - 2018-09-02
- Use gzip instead of zcat because Mac OS X's zcat is bizarre
- Refactor to use more Mojo::File
- Added token protected upload endpoint with CPAN::Uploader compat
- Added periodic updater.
0.002002 - 2017-05-22
- port the tests to new Mojo::File API as well so it still installs
0.002001 - 2017-01-22
- port to new Mojo::File API
- Changes file actually in dist
0.002000 - 2016-09-24
MANIFEST This list of files
script/opan
t/fix/AAAAAAAAA-1.00.tar.gz
t/fix/AAAAAAAAA-1.01.tar.gz
t/fix/empty.index
t/fix/M-1.000001.tar.gz
t/fix/M-1.tar.gz
t/fix/upstream.fragment
t/help.t
t/pan.t
t/upload.t
xt/ext.t
META.yml Module YAML meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
README README file (added by Distar)
LICENSE LICENSE file (added by Distar)
lib/App/opan.pm lib/App/opan.pm file (added by Distar)
Virtual PAN with no presence on disk.
Identical to nopin, but fetching a dist from upstream does an implict
"pin".
Since this can modify your opan config, it's only enabled if the
environment variable "OPAN_AUTOPIN" is set to a true value (calling the
"cpanm" or "carton" commands with "--autopin" sets this for you, because
you already specified you wanted that).
uploads
To enable the /upload endpoint, set the ENV var OPAN_AUTH_TOKENS to a
colon separated list of accepted tokens for uploads. This will allow a
post with a 'file' upload argument, checking http basic auth password
against the provided auth tokens.
recurring pull
Set ENV OPAN_RECURRING_PULL to a true value to make opan automatically
pull from upstream every 600 seconds
custom upstream
Set the ENV var OPAN_MIRROR to specify a cpan mirror - the default is
www.cpan.org. Remember that if you need to temporarily overlay your
overlay but only for one user, there's nothing stopping you setting
lib/App/opan.pm view on Meta::CPAN
monkey_patch $pkg, description => sub { pod_section($cmd, 1) };
monkey_patch $pkg, usage => sub { pod_section($cmd, 0) };
monkey_patch $pkg,
run => sub { my $self = shift; $code->($self->app, @_) };
}
use Mojolicious::Lite;
Mojo::IOLoop->recurring(600 => sub { do_pull(app); }) if $ENV{OPAN_RECURRING_PULL};
post "/upload" => sub {
my $c = shift;
unless ($TOKENS{$c->req->url->to_abs->password || ""}) {
$c->res->headers->www_authenticate("Basic realm=opan");
return $c->render(status => 401, text => "Token missing or not found\n");
}
my $upload = $c->req->upload('dist') || $c->req->upload('pause99_add_uri_httpupload')
or return $c->render(status => 400, text => "dist file missing\n");
my $pan_dir = path('pans/custom/dists/M/MY/MY')->make_path;
$upload->move_to(my $pan_path = $pan_dir->child($upload->filename))
or $c->render(
status => 500,
text => "Failed to move ${upload} into custom pan: $!\n"
);
add_dist_to_index('pans/custom/index', $pan_path);
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/') };
lib/App/opan.pm view on Meta::CPAN
Virtual PAN with no presence on disk.
Identical to nopin, but fetching a dist from upstream does an implict L</pin>.
Since this can modify your opan config, it's only enabled if the environment
variable C<OPAN_AUTOPIN> is set to a true value (calling the L</cpanm> or
L</carton> commands with C<--autopin> sets this for you, because you already
specified you wanted that).
=head2 uploads
To enable the /upload endpoint, set the ENV var OPAN_AUTH_TOKENS to a colon
separated list of accepted tokens for uploads. This will allow a post with a
'file' upload argument, checking http basic auth password against the provided
auth tokens.
=head2 recurring pull
Set ENV OPAN_RECURRING_PULL to a true value to make opan automatically pull
from upstream every 600 seconds
=head2 custom upstream
Set the ENV var OPAN_MIRROR to specify a cpan mirror - the default is
script/opan view on Meta::CPAN
monkey_patch $pkg, description => sub { pod_section($cmd, 1) };
monkey_patch $pkg, usage => sub { pod_section($cmd, 0) };
monkey_patch $pkg,
run => sub { my $self = shift; $code->($self->app, @_) };
}
use Mojolicious::Lite;
Mojo::IOLoop->recurring(600 => sub { do_pull(app); }) if $ENV{OPAN_RECURRING_PULL};
post "/upload" => sub {
my $c = shift;
unless ($TOKENS{$c->req->url->to_abs->password || ""}) {
$c->res->headers->www_authenticate("Basic realm=opan");
return $c->render(status => 401, text => "Token missing or not found\n");
}
my $upload = $c->req->upload('dist') || $c->req->upload('pause99_add_uri_httpupload')
or return $c->render(status => 400, text => "dist file missing\n");
my $pan_dir = path('pans/custom/dists/M/MY/MY')->make_path;
$upload->move_to(my $pan_path = $pan_dir->child($upload->filename))
or $c->render(
status => 500,
text => "Failed to move ${upload} into custom pan: $!\n"
);
add_dist_to_index('pans/custom/index', $pan_path);
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/') };
script/opan view on Meta::CPAN
Virtual PAN with no presence on disk.
Identical to nopin, but fetching a dist from upstream does an implict L</pin>.
Since this can modify your opan config, it's only enabled if the environment
variable C<OPAN_AUTOPIN> is set to a true value (calling the L</cpanm> or
L</carton> commands with C<--autopin> sets this for you, because you already
specified you wanted that).
=head2 uploads
To enable the /upload endpoint, set the ENV var OPAN_AUTH_TOKENS to a colon
separated list of accepted tokens for uploads. This will allow a post with a
'file' upload argument, checking http basic auth password against the provided
auth tokens.
=head2 recurring pull
Set ENV OPAN_RECURRING_PULL to a true value to make opan automatically pull
from upstream every 600 seconds
=head2 custom upstream
Set the ENV var OPAN_MIRROR to specify a cpan mirror - the default is
$ENV{OPAN_AUTH_TOKENS} = 'abc:bcd';
$ENV{OPAN_MIRROR} = 'http://www.cpan.org/';
}
require "$FindBin::Bin/../script/opan";
local $CWD = $tempdir;
my $t = Test::Mojo->new;
$t->app->start('init');
$t->post_ok('/upload')->status_is('401');
$t->post_ok('/upload', {Authorization => "Basic OmFiYw=="})->status_is('400');
my $upload = {dist => {content => 'HELLO', filename => 'world.tgz'}};
$t->post_ok('/upload', {Authorization => "Basic OmFiYw=="}, form => $upload)->status_is('200');
my $f=$tempdir->child('test')->spurt('TEST');
my $url=$t->ua->server->url->path('upload')->to_abs.'';
if (eval { require CPAN::Uploader; 1 }) {
Mojo::IOLoop->subprocess(sub {
my $sub = shift;
return CPAN::Uploader->upload_file($f.'', {upload_uri => $url, user => 'foo', password => 'abc', debug => 1 });
}, sub {
my ($sub,$ret) = @_;
ok(!$ret, 'no return is good return');
Mojo::IOLoop->stop;
});
Mojo::IOLoop->start;
ok( -s 'pans/custom/dists/M/MY/MY/test', 'file got uploaded');
}
done_testing
( run in 2.959 seconds using v1.01-cache-2.11-cpan-b16cb0d3907 )