App-BorgRestore
view release on metacpan or search on metacpan
script/borg-restore.pl view on Meta::CPAN
use v5.14;
use App::BorgRestore;
use App::BorgRestore::Borg;
use App::BorgRestore::DB;
use App::BorgRestore::Helper;
use App::BorgRestore::Settings;
use autodie;
use Cwd qw(abs_path);
use File::Basename;
use Function::Parameters;
use Getopt::Long;
use JSON;
use Log::Any qw($log);
use Log::Any::Adapter;
use Log::Log4perl;
use Log::Log4perl::Appender::Screen;
use Log::Log4perl::Appender::ScreenColoredLevels;
use Log::Log4perl::Layout::PatternLayout;
use Log::Log4perl::Level;
use Pod::Usage;
my $app;
fun print_archive_list ($archives, $show_counter=1) {
my $counter = 0;
for my $archive (@$archives) {
printf "\e[0;33m%3d: ", $counter if $show_counter;
printf "\e[1;33m%s\e[0m %s\n", App::BorgRestore::Helper::format_timestamp($archive->{modification_time}), $archive->{archive};
$counter++;
}
}
fun user_select_archive ($archives) {
my $selected_archive;
if (!@$archives) {
return;
}
print_archive_list($archives);
printf "\e[0;34m%s: \e[0m", "Enter ID to restore (Enter to skip)";
my $selection = <STDIN>;
return if !defined($selection);
chomp $selection;
return unless ($selection =~ /^\d+$/ && defined(${$archives}[$selection]));
return ${$archives}[$selection];
}
sub logger_setup {
my $appender = "Screen";
$appender = "ScreenColoredLevels" if -t STDERR; ## no critic (InputOutput::ProhibitInteractiveTest)
my $conf = "
log4perl.rootLogger = INFO, screenlog
log4perl.appender.screenlog = Log::Log4perl::Appender::$appender
log4perl.appender.screenlog.stderr = 1
log4perl.appender.screenlog.layout = Log::Log4perl::Layout::PatternLayout
log4perl.appender.screenlog.layout.ConversionPattern = %p %m%n
log4perl.PatternLayout.cspec.U = sub {my \@c = caller(\$_[4]); \$c[0] =~ s/::/./g; return sprintf('%s:%s', \$c[0], \$c[2]);}
";
Log::Log4perl::init( \$conf );
Log::Any::Adapter->set('Log4perl');
$SIG{__WARN__} = sub {
local $Log::Log4perl::caller_depth =
$Log::Log4perl::caller_depth + 1;
Log::Log4perl->get_logger()->warn(@_);
};
$SIG{__DIE__} = sub {
# ignore eval blocks
return if($^S);
local $Log::Log4perl::caller_depth =
$Log::Log4perl::caller_depth + 1;
Log::Log4perl->get_logger()->fatal("Uncaught exception: ".$_[0], @_[1..$#_]);
exit(2);
};
}
sub main {
logger_setup();
my %opts;
# untaint PATH because we do not expect this to be run across user boundaries
$ENV{PATH} = App::BorgRestore::Helper::untaint($ENV{PATH}, qr(.*));
Getopt::Long::Configure ("bundling");
GetOptions(\%opts, "help|h", "debug", "update-cache|u", "destination|d=s", "time|t=s", "adhoc", "version", "list", "quiet", "detail", "json") or pod2usage(2);
pod2usage(0) if $opts{help};
if ($opts{version}) {
printf "Version: %s\n", $App::BorgRestore::VERSION;
return 0;
}
pod2usage(-verbose => 0) if (@ARGV== 0 and !$opts{"update-cache"} and !$opts{"list"});
if ($opts{quiet}) {
my $logger = Log::Log4perl->get_logger('');
$logger->level($WARN);
}
if ($opts{debug}) {
my $logger = Log::Log4perl->get_logger('');
$logger->level($DEBUG);
Log::Log4perl->appenders()->{"screenlog"}->layout(
Log::Log4perl::Layout::PatternLayout->new("%d %8r [%-30U] %p %m%n"));
}
$app = App::BorgRestore->new();
if ($opts{"update-cache"}) {
$app->update_cache();
return 0;
}
( run in 1.212 second using v1.01-cache-2.11-cpan-39bf76dae61 )