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 )