⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extract.pm

📁 source of perl for linux application,
💻 PM
字号:
package CPANPLUS::Internals::Extract;use strict;use CPANPLUS::Error;use CPANPLUS::Internals::Constants;use File::Spec                  ();use File::Basename              ();use Archive::Extract;use IPC::Cmd                    qw[run];use Params::Check               qw[check];use Module::Load::Conditional   qw[can_load check_install];use Locale::Maketext::Simple    Class => 'CPANPLUS', Style => 'gettext';local $Params::Check::VERBOSE = 1;=pod=head1 NAMECPANPLUS::Internals::Extract=head1 SYNOPSIS    ### for source files ###    $self->_gunzip( file => 'foo.gz', output => 'blah.txt' );        ### for modules/packages ###    $dir = $self->_extract( module      => $modobj,                             extractdir  => '/some/where' );=head1 DESCRIPTIONCPANPLUS::Internals::Extract extracts compressed files for CPANPLUS.It can do this by either a pure perl solution (preferred) with the use of C<Archive::Tar> and C<Compress::Zlib>, or with binaries, likeC<gzip> and C<tar>. The flow looks like this:    $cb->_extract        Delegate to Archive::Extract =head1 METHODS=head2 $dir = _extract( module => $modobj, [perl => '/path/to/perl', extractdir => '/path/to/extract/to', prefer_bin => BOOL, verbose => BOOL, force => BOOL] )C<_extract> will take a module object and extract it to C<extractdir>if provided, or the default location which is obtained from your config.The file name is obtained by looking at C<< $modobj->status->fetch >>and will be parsed to see if it's a tar or zip archive.If it's a zip archive, C<__unzip> will be called, otherwise C<__untar>will be called. In the unlikely event the file is of neither format,an error will be thrown.C<_extract> takes the following options:=over 4=item moduleA C<CPANPLUS::Module> object. This is required.=item extractdirThe directory to extract the archive to. By default this looks something like:    /CPANPLUS_BASE/PERL_VERSION/BUILD/MODULE_NAME=item prefer_binA flag indicating whether you prefer a pure perl solution, ieC<Archive::Tar> or C<Archive::Zip> respectively, or a binary solutionlike C<unzip> and C<tar>.=item perlThe path to the perl executable to use for any perl calls. Also usedto determine the build version directory for extraction.=item verboseSpecifies whether to be verbose or not. Defaults to your correspondingconfig entry.=item forceSpecifies whether to force the extraction or not. Defaults to yourcorresponding config entry.=backAll other options are passed on verbatim to C<__unzip> or C<__untar>.Returns the directory the file was extracted to on success and falseon failure.=cutsub _extract {    my $self = shift;    my $conf = $self->configure_object;    my %hash = @_;        local $Params::Check::ALLOW_UNKNOWN = 1;        my( $mod, $verbose, $force );    my $tmpl = {        force       => { default => $conf->get_conf('force'),                               store => \$force },        verbose     => { default => $conf->get_conf('verbose'),                             store => \$verbose },        prefer_bin  => { default => $conf->get_conf('prefer_bin') },        extractdir  => { default => $conf->get_conf('extractdir') },        module      => { required => 1, allow => IS_MODOBJ, store => \$mod },        perl        => { default => $^X },    };        my $args = check( $tmpl, \%hash ) or return;        ### did we already extract it ? ###    my $loc = $mod->status->extract();        if( $loc && !$force ) {        msg(loc("Already extracted '%1' to '%2'. ".                "Won't extract again without force",                $mod->module, $loc), $verbose);        return $loc;    }    ### did we already fetch the file? ###    my $file = $mod->status->fetch();    unless( -s $file ) {        error( loc( "File '%1' has zero size: cannot extract", $file ) );            return;    }    ### the dir to extract to ###    my $to =    $args->{'extractdir'} ||                File::Spec->catdir(                        $conf->get_conf('base'),                        $self->_perl_version( perl => $args->{'perl'} ),                        $conf->_get_build('moddir'),                );     ### delegate to Archive::Extract ###    ### set up some flags for archive::extract ###    local $Archive::Extract::PREFER_BIN = $args->{'prefer_bin'};    local $Archive::Extract::DEBUG      = $conf->get_conf('debug');    local $Archive::Extract::WARN       = $verbose;    my $ae = Archive::Extract->new( archive => $file );    unless( $ae->extract( to => $to ) ) {        error( loc( "Unable to extract '%1' to '%2': %3",                    $file, $to, $ae->error ) );        return;    }        ### if ->files is not filled, we dont know what the hell was    ### extracted.. try to offer a suggestion and bail :(    unless ( $ae->files ) {        error( loc( "'%1' was not able to determine extracted ".                    "files from the archive. Instal '%2' and ensure ".                    "it works properly and try again",                    $ae->is_zip ? 'Archive::Zip' : 'Archive::Tar' ) );        return;                        }                                ### print out what files we extracted ###      msg(loc("Extracted '%1'",$_),$verbose) for @{$ae->files};          ### set them all to be +w for the owner, so we don't get permission    ### denied for overwriting files that are just +r        ### this is to rigurous -- just change to +w for the owner [cpan #13358]     #chmod 0755, map { File::Spec->rel2abs( File::Spec->catdir($to, $_) ) }    #            @{$ae->files};        for my $file ( @{$ae->files} ) {         my $path = File::Spec->rel2abs( File::Spec->catfile($to, $file) );            $self->_mode_plus_w( file => $path );    }        ### check the return value for the extracted path ###    ### Make an educated guess if we didn't get an extract_path    ### back    ### XXX apparently some people make their own dists and they     ### pack up '.' which means the leading directory is '.'     ### and only the second directory is the actual module directory    ### so, we'll have to check if our educated guess exists first,     ### then see if the extract path works.. and if nothing works...    ### well, then we really don't know.    my $dir;    for my $try (        File::Spec->rel2abs(             ### _safe_path must be called before catdir because catdir on             ### VMS currently will not handle the extra dots in the directories.            File::Spec->catdir( $self->_safe_path( path => $to ) ,                                  $self->_safe_path( path =>                                             $mod->package_name .'-'.                                              $mod->package_version        ) ) ) ,        File::Spec->rel2abs( $ae->extract_path ),    ) {        ($dir = $try) && last if -d $try;    }                                                ### test if the dir exists ###    unless( $dir && -d $dir ) {        error(loc("Unable to determine extract dir for '%1'",$mod->module));        return;        } else {            msg(loc("Extracted '%1' to '%2'", $mod->module, $dir), $verbose);                ### register where we extracted the files to,        ### also store what files were extracted        $mod->status->extract( $dir );         $mod->status->files( $ae->files );    }          ### also, figure out what kind of install we're dealing with ###    $mod->get_installer_type();    return $mod->status->extract();}1;# Local variables:# c-indentation-style: bsd# c-basic-offset: 4# indent-tabs-mode: nil# End:# vim: expandtab shiftwidth=4:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -