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 )