diff options
-rw-r--r-- | Makefile.PL | 2 | ||||
-rwxr-xr-x | beam | 69 | ||||
-rw-r--r-- | lib/App/Beam/Backup.pm | 44 | ||||
-rw-r--r-- | lib/App/Beam/List.pm | 59 |
4 files changed, 164 insertions, 10 deletions
diff --git a/Makefile.PL b/Makefile.PL index 0d99cd8..c2d901a 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,7 +3,7 @@ use ExtUtils::MakeMaker; use Module::Metadata; WriteMakefile(NAME => 'App::Beam', - VERSION => '1.6.90', + VERSION_FROM => 'beam', AUTHOR => 'Sergey Poznyakoff <gray@gnu.org>', LICENSE => 'gpl_3', ABSTRACT => 'Backup tool', @@ -3,8 +3,9 @@ use strict; use Pod::Usage; use Pod::Man; +use Pod::Find qw(pod_where); use File::Basename; -use Getopt::Long qw(:config gnu_getopt no_ignore_case require_order); +use Getopt::Long qw(:config gnu_getopt no_ignore_case require_order auto_version); use Unix::Sysexits; use Data::Dumper; @@ -12,8 +13,46 @@ my $progname = basename($0); my $progdescr = 'backup manager'; my %args; +our $VERSION = '1.6.90'; + +=head1 NAME + +beam - backup manager + +=head1 SYNOPSIS + +B<beam> +[B<-dn>] +[B<-f> I<FILE>] +[B<--config-file=>I<FILE> +[B<--debug>] +[B<--dry-run>] +I<COMMAND> [I<ARGS>] + +B<beam> B<-h> | B<--help> | B<--usage> | B<--version> + +=cut + +sub pod_usage_msg { + my ($obj) = @_; + my %args; + open my $fd, '>', \my $msg; + + $args{-input} = pod_where({-inc => 1}, ref($obj)) if defined $obj; + pod2usage(-verbose => 99, + -sections => 'NAME', + -output => $fd, + -exitval => 'NOEXIT', + %args); + my @a = split /\n/, $msg; + $msg = $a[1]; + $msg =~ s/^\s+//; + $msg =~ s/ - /: /; + return $msg; +} + GetOptions("h" => sub { - pod2usage(-message => "$progname: $progdescr", + pod2usage(-message => pod_usage_msg(), -exitstatus => EX_OK); }, "help" => sub { @@ -43,11 +82,33 @@ my %ctab = ( } ); -unless (defined($ctab{$ARGV[0]})) { +my $command = shift; + +unless (defined($ctab{$command})) { print STDERR "$progname: no such command\n"; exit(EX_USAGE); } -my $beam = $ctab{$ARGV[0]}(%args); + +my $beam = $ctab{$command}(%args); + +Getopt::Long::Configure('pass_through'); +GetOptions("h" => sub { + pod2usage(-message => pod_usage_msg($beam), + -input => pod_where({-inc => 1}, ref($beam)), + -exitstatus => EX_OK); + }, + "help" => sub { + pod2usage(-input => pod_where({-inc => 1}, ref($beam)), + -exitstatus => EX_OK, + -verbose => 2); + }, + "usage" => sub { + pod2usage(-input => pod_where({-inc => 1}, ref($beam)), + -exitstatus => EX_OK, + -verbose => 0); + }); +Getopt::Long::Configure('no_pass_through'); + $beam->begin; $beam->run(@ARGV); $beam->end; diff --git a/lib/App/Beam/Backup.pm b/lib/App/Beam/Backup.pm index 78e62f4..ed8953b 100644 --- a/lib/App/Beam/Backup.pm +++ b/lib/App/Beam/Backup.pm @@ -8,14 +8,52 @@ our @ISA = qw(App::Beam); use Unix::Sysexits; +=head1 NAME + +beam backup - create new backup + +=head1 SYNOPSIS + +B<beam> [I<OPTIONS>] B<backup> + +=head1 DESCRIPTION + +=head1 OPTIONS + +=over 4 + +=item B<-h> + +Print a short help summary. + +=item B<--help> + +Display manpage. + +=item B<--usage> + +Print a short command line usage reminder. + +=back + +=cut + sub run { my $self = shift; - shift; # Skip subcommand name - $self->abend(EX_USAGE, "bad number of arguments") if @_; + #GetOptionsFromArray(\@_, ...); + my @items = split /\s+/, $self->get('core.items'); + if (@_) { + push @items, $self->names_of('item'); + foreach my $item (@_) { + $self->abend(EX_USAGE, "$item: no such item defined") + unless grep { $item eq $_ } @items; + } + @items = @_; + } $self->lock(); - foreach my $item (split /\s+/, $self->get('core.items')) { + foreach my $item (@items) { my $backend = $self->{backend}{$self->get("item.$item.backend")}; $backend->backup($item); } diff --git a/lib/App/Beam/List.pm b/lib/App/Beam/List.pm index ac7031f..b786e3f 100644 --- a/lib/App/Beam/List.pm +++ b/lib/App/Beam/List.pm @@ -5,6 +5,8 @@ use Carp; use POSIX qw(strftime); use Unix::Sysexits; use Getopt::Long qw(GetOptionsFromArray); +use Pod::Usage; +use Pod::Man; use App::Beam qw(:result); our @ISA = qw(App::Beam); @@ -15,18 +17,71 @@ my %result_string = ( RESULT_FAILURE() => 'FAILURE' ); +=head1 NAME + +beam list - list existing backups + +=head1 SYNOPSIS + +B<beam> +[I<OPTIONS>] +B<list> +[B<-v>] +[B<--verbose>] +[I<ITEM>...] + +B<beam list> B<-h> | B<--help> | B<--usage> | B<--version> + +=head1 DESCRIPTION + +Lists existing backups. + +=head1 OPTIONS + +=over 4 + +=item B<-v>, B<--verbose> + +Verbosely lists each backup item. + +=back + +Informational options: + +=over 4 + +=item B<-h> + +Print a short help summary. + +=item B<--help> + +Display manpage. + +=item B<--usage> + +Print a short command line usage reminder. + +=back + +=cut + sub run { my $self = shift; my $verbose; - shift; - GetOptionsFromArray(\@_, "verbose|v" => \$verbose); + GetOptionsFromArray(\@_, + "verbose|v" => \$verbose); + $self->abend(EX_USAGE, "bad number of arguments") if @_; $self->lock(); my @stat = @{$self->{status}}; shift @stat; + my $i = 0; foreach my $ent (@stat) { + ++$i; + printf("%3d ", $i); print strftime "%c ", localtime $ent->{timestamp}; printf("% 3d% 3d% 3d %s", $ent->{cycle}, $ent->{round}, $ent->{level}, $result_string{$ent->{result}}); |