App-cpanbaker

 view release on metacpan or  search on metacpan

bin/cpanbaker  view on Meta::CPAN

#!/usr/bin/env perl
use Getopt::Long;
use List::MoreUtils qw(uniq);
use File::Find::Rule;
use File::Spec;
use Log::Dispatch;
use Getopt::Long;
use DateTime;
use warnings;
use strict;
$|++;

my $opt_verbose;
my $opt_very_verbose;
my $opt_installed;
my $opt_exclude_parts = "";
my $opt_include_parts = "";
my $opt_logfile;
my $opt_debug;
my $opt_sudo;

my $opt_gzip;
my $opt_bzip;

my $opt_help;
my $opt_dry;
my $opt_extract;

my $opt_skip_pods;
my $opt_skip_manpages;

my $opt_result = GetOptions(
    "exclude=s"     => \$opt_exclude_parts,
    "include=s"     => \$opt_include_parts,
    "installed"     => \$opt_installed,       # get installed modules
    "l|log=s"       => \$opt_logfile,
    "v|verbose"     => \$opt_verbose,
    "vv"            => \$opt_very_verbose,
    "d|debug"       => \$opt_debug,

    "z|gz"          => \$opt_gzip,
    "j|bz"          => \$opt_bzip,

    "h|help"        => \$opt_help,
    "sudo"          => \$opt_sudo,
    "skip-pods"     => \$opt_skip_pods,
    "skip-manpages" => \$opt_skip_manpages,
    "dry"           => \$opt_dry,
    "x|extract"     => \$opt_extract,
);

$opt_verbose ||= $opt_very_verbose;

if( $opt_help ) {
    require Pod::Simple::Text;
    my $pod = Pod::Simple::Text->new;
    $pod->output_fh( *STDOUT );
    $pod->parse_file( __FILE__ );
    exit(0);
}


my $filename = shift;
unless( $filename ) {
    print STDERR "To show help message, please use -h option.\n";
}

if( $opt_installed ) {

bin/cpanbaker  view on Meta::CPAN

            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;
    }
    @libdirs = grep !/^\.$/,uniq sort @libdirs;

    if( $opt_verbose ) {
        $logger->info( "Perl lib paths:\n" );
        $logger->info( "\t" . $_ . "\n" ) for @libdirs;
    }
    return @libdirs;
}


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 );

    $logger->debug( "\t" . join(' ' , @paths ) . "\n" ) if $opt_debug;

    # use Data::Dumper; warn Dumper( $part , \@paths );

    push @tar_paths, @paths;
}

my $tarbin = 'tar';
my $taropts = 'cpf';
my $tarext = '.tar';
my $tarname = join(
        '-',"cpanbak", $^O ,DateTime->now->ymd('-'));

my $tarexclude = ' --exclude "*.log"';

if( $exclude_parts{perlbrew} ) {
    push @exclude_pattern , $ENV{PERLBREW_ROOT};
}

push @exclude_pattern, File::Spec->join( $ENV{HOME} , '.cpanm' , 'work' );
push @exclude_pattern, '*.pod' if $opt_skip_pods;
push @exclude_pattern, '*.pm3' if $opt_skip_manpages;

$tarexclude .= join ' ' ,map { qq| --exclude "$_"| } @exclude_pattern;

if ($opt_gzip) {
    $taropts .= 'z';
    $tarext .= '.gz';
}
elsif( $opt_bzip ) {
    $taropts .= 'j';
    $tarext .= '.bz2';
}

my $tarfilename = $filename || ($tarname . $tarext);

$taropts .= 'v' if( $opt_very_verbose || $opt_debug );

my @cmd = (
    $tarbin,
    $taropts,
    $tarfilename,
    $tarexclude,
    map { qq|"$_"| } @tar_paths,
);

unshift @cmd, 'sudo' if( $opt_sudo );

my $cmdstr = join ' ' , @cmd;

$logger->debug( "Executing: \$ " . 
        substr($cmdstr,0,90) . "...\n" ) if $opt_debug;

$logger->info( "Generating $tarfilename ...\n" );
system( $cmdstr ) unless $opt_dry;
$logger->info( "Done\n" );

# TODO:
#   * clean perlbrew , cpan, cpanm dir before backing up.
#   * 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



( run in 2.588 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )