📄 cpan2dist
字号:
#!/usr/bin/perl -wuse strict;use CPANPLUS::Backend;use CPANPLUS::Dist;use CPANPLUS::Internals::Constants;use Data::Dumper;use Getopt::Long;use File::Spec;use File::Temp qw|tempfile|;use File::Basename;use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';local $Data::Dumper::Indent = 1;use constant PREREQ_SKIP_CLASS => 'CPANPLUS::To::Dist::PREREQ_SKIP';use constant ALARM_CLASS => 'CPANPLUS::To::Dist::ALARM';### print when you can$|++;my $cb = CPANPLUS::Backend->new or die loc("Could not create new CPANPLUS::Backend object");my $conf = $cb->configure_object;my %formats = map { $_ => $_ } CPANPLUS::Dist->dist_types;my $opts = {};GetOptions( $opts, 'format=s', 'archive', 'verbose!', 'force!', 'skiptest!', 'keepsource!', 'makefile!', 'buildprereq!', 'help', 'flushcache', 'ban=s@', 'banlist=s@', 'ignore=s@', 'ignorelist=s@', 'defaults', 'modulelist=s@', 'logfile=s', 'timeout=s', 'dist-opts=s%', 'set-config=s%', 'default-banlist!', 'set-program=s%', 'default-ignorelist!', 'edit-metafile!', 'install!' ); die usage() if exists $opts->{'help'};### parse optionsmy $tarball = $opts->{'archive'} || 0;my $keep = $opts->{'keepsource'} ? 1 : 0;my $prereqbuild = exists $opts->{'buildprereq'} ? $opts->{'buildprereq'} : 0;my $timeout = exists $opts->{'timeout'} ? $opts->{'timeout'} : 300;### use default answers?$ENV{'PERL_MM_USE_DEFAULT'} = $opts->{'defaults'} ? 1 : 0;my $format;### if provided, we go with the command line option, fall back to conf setting{ $format = $opts->{'format'} || $conf->get_conf('dist_type'); $conf->set_conf( dist_type => $format ); ### is this a valid format?? die loc("Invalid format: " . ($format || "[NONE]") ) . usage() unless $formats{$format}; ### any options to fix config entries { my $set_conf = $opts->{'set-config'} || {}; while( my($key,$val) = each %$set_conf ) { $conf->set_conf( $key => $val ); } } ### any options to fix program entries { my $set_prog = $opts->{'set-program'} || {}; while( my($key,$val) = each %$set_prog ) { $conf->set_program( $key => $val ); } } ### any other options passed { my %map = ( verbose => 'verbose', force => 'force', skiptest => 'skiptest', makefile => 'prefer_makefile' ); ### set config options from arguments while (my($key,$val) = each %map) { my $bool = exists $opts->{$key} ? $opts->{$key} : $conf->get_conf($val); $conf->set_conf( $val => $bool ); } } }my @modules = @ARGV;if( exists $opts->{'modulelist'} ) { push @modules, map { parse_file( $_ ) } @{ $opts->{'modulelist'} }; } die usage() unless @modules;### set up munge callback if requested{ if( $opts->{'edit-metafile'} ) { my $editor = $conf->get_program('editor'); if( $editor ) { ### register install callback ### $cb->_register_callback( name => 'munge_dist_metafile', code => sub { my $self = shift; my $text = shift or return; my($fh,$file) = tempfile( UNLINK => 1 ); unless( print $fh $text ) { warn "Could not print metafile information: $!"; return; } close $fh; system( $editor => $file ); my $cont = $cb->_get_file_contents( file => $file ); return $cont; }, ); } else { warn "No editor configured. Can not edit metafiles!\n"; } }}my $fh;LOGFILE: { if( my $file = $opts->{logfile} ) { open $fh, ">$file" or ( warn loc("Could not open '%1' for writing: %2", $file,$!), last LOGFILE ); warn "Logging to '$file'\n"; *STDERR = $fh; *STDOUT = $fh; }}### reload indices if so desired$cb->reload_indices() if $opts->{'flushcache'};{ my @ban = exists $opts->{'ban'} ? map { qr/$_/ } @{ $opts->{'ban'} } : (); if( exists $opts->{'banlist'} ) { push @ban, map { parse_file( $_, 1 ) } @{ $opts->{'banlist'} }; } push @ban, map { s/\s+//; $_ } map { [split /\s*#\s*/]->[0] } grep { /#/ } map { split /\n/ } _default_ban_list() if $opts->{'default-banlist'}; ### use our prereq install callback $conf->set_conf( prereqs => PREREQ_ASK ); ### register install callback ### $cb->_register_callback( name => 'install_prerequisite', code => \&__ask_about_install, ); ### check for ban patterns when handling prereqs sub __ask_about_install { my $mod = shift or return; my $prereq = shift or return; ### die with an error object, so we can verify that ### the die came from this location, and that it's an ### 'acceptable' death my $pat = ban_me( $prereq ); die bless sub { loc("Module '%1' requires '%2' to be installed " . "but found in your ban list (%3) -- skipping", $mod->module, $prereq->module, $pat ) }, PREREQ_SKIP_CLASS if $pat; return 1; } ### should we skip this module? sub ban_me { my $mod = shift; for my $pat ( @ban ) { return $pat if $mod->module =~ /$pat/i; } return; }} ### patterns to strip from prereq lists{ my @ignore = exists $opts->{'ignore'} ? map { qr/$_/ } @{ $opts->{'ignore'} } : (); if( exists $opts->{'ignorelist'} ) { push @ignore, map { parse_file( $_, 1 ) } @{ $opts->{'ignorelist'} }; } push @ignore, map { s/\s+//; $_ } map { [split /\s*#\s*/]->[0] } grep { /#/ } map { split /\n/ } _default_ignore_list() if $opts->{'default-ignorelist'}; ### register install callback ### $cb->_register_callback( name => 'filter_prereqs', code => \&__filter_prereqs, ); sub __filter_prereqs { my $cb = shift; my $href = shift; for my $name ( keys %$href ) { my $obj = $cb->parse_module( module => $name ) or ( warn "Cannot make a module object out of ". "'$name' -- skipping\n", next ); if( my $pat = ignore_me( $obj ) ) { warn loc("'%1' found in your ignore list (%2) ". "-- filtering it out\n", $name, $pat); delete $href->{ $name }; } } return $href; } ### should we skip this module? sub ignore_me { my $mod = shift; for my $pat ( @ignore ) { return $pat if $mod->module =~ /$pat/i; return $pat if $mod->package_name =~ /$pat/i; } return; } } my %done;for my $name (@modules) { my $obj; ### is it a tarball? then we get it locally and transform it ### and it's dependencies into .debs if( $tarball ) { ### make sure we use an absolute path, so chdirs() dont ### mess things up $name = File::Spec->rel2abs( $name ); ### ENOTARBALL? unless( -e $name ) { warn loc("Archive '$name' does not exist"); next; } $obj = CPANPLUS::Module::Fake->new( module => basename($name), path => dirname($name), package => basename($name), ); ### if it's a traditional CPAN package, we can tidy ### up the module name some $obj->module( $obj->package_name ) if $obj->package_name; ### get the version from the package name $obj->version( $obj->package_version || 0 ); ### set the location of the tarball $obj->status->fetch($name); ### plain old cpan module? } else { ### find the corresponding module object ### $obj = $cb->parse_module( module => $name ) or ( warn "Cannot make a module object out of ". "'$name' -- skipping\n", next ); } ### you banned it? if( my $pat = ban_me( $obj ) ) { warn loc("'%1' found in your ban list (%2) -- skipping\n", $obj->module, $pat ); next; } ### or just ignored it? if( my $pat = ignore_me( $obj ) ) { warn loc("'%1' found in your ignore list (%2) -- skipping\n", $obj->module, $pat ); next; } my $target = $opts->{'install'} ? 'install' : 'create'; my $dist = eval { local $SIG{ALRM} = sub { die bless {}, ALARM_CLASS } if $timeout; alarm $timeout || 0; my $dist_opts = $opts->{'dist-opts'} || {};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -