App-cpanbaker

 view release on metacpan or  search on metacpan

META.yml  view on Meta::CPAN

---
abstract: 'cpan module baker, backup your whole cpan module files'
author:
  - 'Yo-An Lin <cornelius.howl {at} gmail.com>'
build_requires:
  ExtUtils::MakeMaker: 6.42
configure_requires:
  ExtUtils::MakeMaker: 6.42
distribution_type: module
generated_by: 'Module::Install version 1.00'
license: perl
meta-spec:

README.mkd.old  view on Meta::CPAN


# CPANBAKER - backup your whole module files

backup your whole cpan module files

* backup cpan self && cpanminus
* backup cpan config
* backup all user's cpan config ~/.cpan
* backup cpanmini ?
* backup module files
* backup cpan mini
* backup local::lib

    perl -Mlocal::lib

    get install base from perl -V 

    PERL_LOCAL_LIB_ROOT

* backup man pages

    $ head /opt/local/share/man/man3/Moose.3
    $ man -w Moose
    $ perldoc -l Moose

* backup script files (/usr/bin...)


    scan $PATH env
    for file in * ; do if [[ -n `head $file | grep perl` ]] echo $file ; done


    $ perl -V to get INC
    $ cd to /
    $ tar these path
    $ find perl man pages


    $ cpanbak --installed > module-list
    $ cpanbak --install   < module-list

    is equal to:

        $ cpanm < module-list

    $ cpanbak -b  # backup
    $ cpanbak -z -b file.tgz # use gzip
    $ cpanbak -7 -b file.7z  # use 7zip

    $ cpanbak -b file.tgz # backup to file
    $ cpanbak -r file.tgz # restore

    --exclude [pattern]

    $ cpanbak --local -b file.tgz   # backup local lib only

* compare path list to find top level paths (?)

README.mkdn  view on Meta::CPAN

# NAME

cpanbaker - backup your cpan module files.

# OPTIONS

    $ cpanbaker [options] [filename]

    --sudo
            use sudo to backup files.

    --exclude part,...
            don't backup ...
            valid part names are minicpan, bin, local-lib, perlbrew, libs

    --include part,...
            backup include ...
            valid part names are minicpan, bin, local-lib, perlbrew, libs

    --dry
            dry run. do not archive files.

    --installed
            get installed module list.

    -l file, --log file
            specify log file.

README.mkdn  view on Meta::CPAN

            tar with bzip2 compression.

    -d, --debug
            debug mode.

    -h
            show help messages

# USAGE

To backup:

    $ cpanbaker 

To backup with gzip compression:

    $ cpanbaker -z

To backup with gzip compression and specify a filename:

    $ cpanbaker -z blah.tar.gz

To backup in dry-run mode:

    $ cpanbaker --dry

With sudo (root permission):

    $ cpanbaker --sudo

To exclude perlbrew stuff:

    $ cpanbaker --exclude=perlbrew

README.mkdn  view on Meta::CPAN

    $ cpanm < module_list   # reinstall modules

To exclude minicpan stuff:

    $ cpanbaker --exclude=minicpan

To exclude minicpan and perlbrew:

    $ cpanbaker --exclude=perlbrew,minicpan

To backup perlbrew stuff only:

    $ cpanbaker --include=perlbrew

Verbose mode:

    $ cpanbaker -v

Very verbose mode:

    $ cpanbaker -vv

bin/cpanbaker  view on Meta::CPAN

elsif( $opt_extract ) {
    unless ( $filename ) {
        die('Please specify filename');
    }
    my @cmd = ( "tar", "xpf", $filename , "-C /");
    exit(0);
}


my %bak_parts = (
    bin => \&backup_bin ,
    perlbrew => \&backup_perlbrew,
    minicpan => \&backup_minicpan,
    'local-lib' => \&backup_locallib,
    manpages => \&backup_manpages,
    cpanconfig => \&backup_cpanconfig,
    libs    => \&backup_libs,
);
my @bak_parts = keys %bak_parts;
my %exclude_parts = map { $_ => 1 } split /,/, $opt_exclude_parts;
my %include_parts = map { $_ => 1 } (split /,/,$opt_include_parts) || @bak_parts;

my @exclude_pattern = ();


my $logger = Log::Dispatch->new(
        outputs =>  [ 

bin/cpanbaker  view on Meta::CPAN

sub check_partname {
    my $name = shift;
    if( ! $bak_parts{ $name } )  {
        print STDERR "Invalid part name: $name\n";
        print STDERR "Valid part name: ", join(', ',@bak_parts) . "\n"; 
        exit(0);
    }
}


sub backup_cpanconfig {
    my %cpandir = ( 
        cpan => File::Spec->join( $ENV{HOME} , '.cpan' ),
        cpanplus => File::Spec->join( $ENV{HOME} , '.cpanplus' ),
        cpanminus => File::Spec->join( $ENV{HOME} , '.cpanm' ),
    );
    my @cpandirs = ();
    for my $type ( keys %cpandir ) {
        my $dir = $cpandir{ $type };
        if( -e $dir ) {
            $logger->info( "Found $type: $dir\n" ) if $opt_verbose;
            push @cpandirs , $dir;
        }
    }
    return @cpandirs;
}

sub backup_bin {

    $logger->info( "* Searching perl scripts from \$PATH\n" );
    $logger->info( $ENV{PATH} . "\n" ) 
        if $opt_debug;

    my @env_paths = uniq sort split /:/, $ENV{PATH};
    my @bin_files = ();
    for my $path ( @env_paths ) {

        $logger->info( "Scanning " . $path . "\n" ) 

bin/cpanbaker  view on Meta::CPAN

                push @bin_files , $file if $firstline =~ m{perl};
            } else { 
                $logger->error( "$file: $!\n");
                next;
            }
        }
    }
    return @bin_files;
}

sub backup_minicpan {
    my $file = File::Spec->join( $ENV{HOME} , '.minicpanrc' );
    open my $fh , "<" , $file;
    my @lines = <$fh>;
    close $fh;
    chomp( @lines );
    my ($local) = grep /^local:\s*/, @lines;
    if( $local ) {
        $local =~ s{^local:\s*}{};
        $logger->info( 'Found minicpan local: ' . $local . "\n" );
        return $local;
    }
    return ();
}

sub backup_perlbrew {
    if( $ENV{PERLBREW_ROOT} ) {
        $logger->info( "Found perlbrew root:" . $ENV{PERLBREW_ROOT} . "\n" ) if $opt_verbose;
        return $ENV{PERLBREW_ROOT};
    }
}

sub backup_locallib {
    my @paths;
    push @paths, $ENV{PERL_LOCAL_LIB_ROOT} if $ENV{PERL_LOCAL_LIB_ROOT};

#     PERL_MB_OPT="--install_base /Users/c9s/perl5"
#     PERL_MM_OPT="INSTALL_BASE=/Users/c9s/perl5"
    my $mb_opt = $ENV{PERL_MB_OPT};
    my $mm_opt = $ENV{PERL_MM_OPT};
    if( $mb_opt && $mb_opt =~ m{--install_base\s+(\S+)} )  {
        $logger->info( "Found INSTALL_BASE from Module::Build opt: $1\n" ) if $opt_verbose;
        push @paths , $1;
    }

    if( $mm_opt && $mm_opt =~ m{INSTALL_BASE=(\S+)} ) {
        $logger->info( "Found INSTALL_BASE from ExtUtil::MakeMaker opt: $1\n" ) if $opt_verbose;
        push @paths , $1;
    }

    return uniq sort @paths;
}

sub backup_manpages {
    my $manpath = qx(man -w);
    $logger->info( "Found manpages path: $manpath\n" );

    my @paths = split /:/,$manpath;
    my @manfiles = ();
    for my $p ( @paths ) {
        my @files = File::Find::Rule->file( "*.3" )->in( $p );
        for( @files ) {
            open my $fh, "<", $_;
            my $firstline = <$fh>;
            close $fh;

            push @manfiles , $_ if $firstline =~ /Pod::/;
        }
    }
    return @manfiles;
}

sub backup_libs {
    my @libdirs = @INC;
    # when exclude local-lib or .. should remove them from INC paths

    if ( $exclude_parts{'local-lib'} ) {
        @libdirs = grep !/^$ENV{PERL_LOCAL_LIB_ROOT}/,@libdirs;
    }

    if ( $exclude_parts{perlbrew} ) {
        @libdirs = grep !/^$ENV{PERLBREW_ROOT}/, @libdirs;
    }

bin/cpanbaker  view on Meta::CPAN



check_partname( $_ ) for keys %exclude_parts;
for my $p ( keys %include_parts ) { 
    check_partname( $p );
    if( defined $exclude_parts{ $p } )  { 
        delete $include_parts{ $p };
    }
}

print STDERR "Will backup: " . join(', ', keys %include_parts ) . "\n";


my @tar_paths;
for my $part ( keys %include_parts ) {

    $logger->info( "Gathering information of $part ...\n" );

    my $cb = $bak_parts{ $part };
    my @paths = $cb->( $logger );

bin/cpanbaker  view on Meta::CPAN

#   * skip log files
#   * skip build files

# my $logger = Logger::Simple->new( LOG => File::Spec->join( $ENV{HOME} , '.cpanbaker-log' ) );
# my $log = Log::Any->get_logger( category => __PACKAGE__ );
# $log->info( 'test test test' );
__END__

=head1 NAME

cpanbaker - backup your cpan module files.

=head1 OPTIONS

    $ cpanbaker [options] [filename]

    --sudo
            use sudo to backup files.

    --exclude part,...
            don't backup ...
            valid part names are minicpan, bin, local-lib, perlbrew, libs

    --include part,...
            backup include ...
            valid part names are minicpan, bin, local-lib, perlbrew, libs

    --dry
            dry run. do not archive files.

    --installed
            get installed module list.

    -l file, --log file
            specify log file.

bin/cpanbaker  view on Meta::CPAN

            tar with bzip2 compression.

    -d, --debug
            debug mode.

    -h
            show help messages

=head1 USAGE

To backup:

    $ cpanbaker 

To backup with gzip compression:

    $ cpanbaker -z

To backup with gzip compression and specify a filename:

    $ cpanbaker -z blah.tar.gz

To backup in dry-run mode:

    $ cpanbaker --dry

With sudo (root permission):

    $ cpanbaker --sudo

To exclude perlbrew stuff:

    $ cpanbaker --exclude=perlbrew

bin/cpanbaker  view on Meta::CPAN

    $ cpanm < module_list   # reinstall modules

To exclude minicpan stuff:

    $ cpanbaker --exclude=minicpan

To exclude minicpan and perlbrew:

    $ cpanbaker --exclude=perlbrew,minicpan

To backup perlbrew stuff only:

    $ cpanbaker --include=perlbrew

Verbose mode:

    $ cpanbaker -v

Very verbose mode:

    $ cpanbaker -vv

lib/App/cpanbaker.pm  view on Meta::CPAN

package App::cpanbaker;
use strict;
use warnings;
our $VERSION = '0.05';

1;
__END__

=head1 NAME

App::cpanbaker - cpan module baker, backup your whole cpan module files

=head1 SYNOPSIS

    use App::cpanbaker;

=head1 DESCRIPTION

Use cpanbaker, backup your whole cpan module files.

cpanbaker not only backup module files , also script files and cpan, cpanplus,
cpanminus, minicpan configs.

And cpanbaker also detects perlbrew, local::lib directories to backup.

=head1 SUPPORTS

    * script files
    * perlbrew.
    * local::lib.
    * inc path.
    * minicpan
    * cpan, cpanplus, cpanm config directories.



( run in 1.912 second using v1.01-cache-2.11-cpan-49f99fa48dc )