summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
Diffstat (limited to 'Master')
-rwxr-xr-xMaster/texmf/scripts/texlive/tlmgr.pl160
1 files changed, 118 insertions, 42 deletions
diff --git a/Master/texmf/scripts/texlive/tlmgr.pl b/Master/texmf/scripts/texlive/tlmgr.pl
index 5e49d4185ba..c64f7e01da5 100755
--- a/Master/texmf/scripts/texlive/tlmgr.pl
+++ b/Master/texmf/scripts/texlive/tlmgr.pl
@@ -140,6 +140,7 @@ sub main {
"file" => 1 },
"restore" => { "backupdir" => "=s",
"dry-run|n" => 1,
+ "all" => 1,
"force" => 1 },
"backup" => { "backupdir" => "=s",
"clean" => ":-99",
@@ -1128,59 +1129,134 @@ sub action_search {
# RESTORE
#
-sub action_restore {
- # tlmgr restore --backupdir dir
- # lists all packages with all revisions
- # tlmgr restore --backupdir dir pkg
- # lists all revisions of pkg
- # tlmgr restore --backupdir dir pkg rev
- # restores pkg to revision rev
- # check the backup dir argument
+
+# read the directory and check what files/package/rev are available
+# for restore
+sub get_available_backups {
+ my $bd = shift;
+ # initialize the hash(packages) of hash(revisions)
+ my %backups;
+ opendir (DIR, $bd) || die "opendir($bd) failed: $!";
+ my @dirents = readdir (DIR);
+ closedir (DIR) || warn "closedir($bd) failed: $!";
+ for my $dirent (@dirents) {
+ next if (-d $dirent);
+ next if ($dirent !~ m/^(.*)\.r([0-9]+)\.tar\.xz$/);
+ $backups{$1}->{$2} = 1;
+ }
+ return %backups;
+}
+
+sub restore_one_package {
+ my ($pkg, $rev, $bd) = @_;
+ # first remove the package, then reinstall it
+ # this way we get rid of useless files
+ my $restore_file = "$bd/${pkg}.r${rev}.tar.xz";
+ if (! -r $restore_file) {
+ tlwarn("Cannot read $restore_file, no action taken\n");
+ return;
+ }
+ $localtlmedia->remove_package($pkg);
+ TeXLive::TLMedia->_install_package($restore_file , 0, [] ,$localtlpdb);
+ logpackage("restore: $pkg ($rev)");
+ # now we have to read the .tlpobj file and add it to the DB
+ my $tlpobj = TeXLive::TLPOBJ->new;
+ $tlpobj->from_file($localtlpdb->root . "/tlpkg/tlpobj/$pkg.tlpobj");
+ $localtlpdb->add_tlpobj($tlpobj);
+ TeXLive::TLUtils::announce_execute_actions("enable",
+ $localtlpdb->get_package($pkg));
+ $localtlpdb->save;
+}
+
+sub check_backupdir_selection {
+ my $warntext = "";
if ($opts{"backupdir"}) {
my $ob = abs_path($opts{"backupdir"});
$ob && ($opts{"backupdir"} = $ob);
if (! -d $opts{"backupdir"}) {
- tlwarn ("tlmgr: backupdir argument $opts{'backupdir'} is not a directory.\n");
- tlwarn ("Don't know from where to restore backups, goodbye.\n");
- exit 1;
+ $warntext .= "tlmgr: backupdir argument $opts{'backupdir'} is not a directory.\n";
+ $warntext .= "Don't know from where to restore backups.\n";
+ return (0, $warntext);
}
} else {
# no argument, check for presence in TLPDB
init_local_db(1);
$opts{"backupdir"} = $localtlpdb->option("backupdir");
if (!$opts{"backupdir"}) {
- tlwarn ("Don't know from where to restore backups, terminating.\n");
- exit 1;
+ return (0, "Don't know from where to restore backups.\n");
}
- # we are stil here, there is something set in tlpdb
+ # we are still here, there is something set in tlpdb
my $ob = abs_path($opts{"backupdir"});
$ob && ($opts{"backupdir"} = $ob);
if (! -d $opts{"backupdir"}) {
- tlwarn ("backupdir as set in tlpdb $opts{'backupdir'} is not a directory.\n");
- tlwarn ("Don't know from where to restore backups, terminating.\n");
- exit 1;
+ $warntext = "backupdir as set in tlpdb $opts{'backupdir'} is not a directory.\n";
+ $warntext .= "Don't know from where to restore backups.\n";
+ return (0, $warntext);
}
}
+ return 1;
+}
+sub action_restore {
+ # tlmgr restore [--backupdir dir] --all
+ # restores of all packages found in backupdir the latest version
+ # tlmgr restore --backupdir dir
+ # lists all packages with all revisions
+ # tlmgr restore --backupdir dir pkg
+ # lists all revisions of pkg
+ # tlmgr restore --backupdir dir pkg rev
+ # restores pkg to revision rev
+ # check the backup dir argument
+
+ {
+ my ($a, $b) = check_backupdir_selection();
+ if (!$a) {
+ # in all these cases we want to terminate in the non-gui mode
+ tlwarn($b);
+ tlwarn("Exiting.\n");
+ exit 1;
+ }
+ }
info("restore: dry run, no changes will be made\n") if $opts{"dry"};
# initialize the hash(packages) of hash(revisions)
- my %backups;
- opendir (DIR, $opts{"backupdir"}) || die "opendir($opts{'backupdir'}) failed: $!";
- my @dirents = readdir (DIR);
- closedir (DIR) || warn "closedir($opts{'backupdir'}) failed: $!";
- for my $dirent (@dirents) {
- next if (-d $dirent);
- next if ($dirent !~ m/^(.*)\.r([0-9]+)\.tar\.xz$/);
- $backups{$1}->{$2} = 1;
- }
+ my %backups = get_available_backups($opts{"backupdir"});
my ($pkg, $rev) = @ARGV;
+ if (defined($pkg) && $opts{"all"}) {
+ tlwarn("Do you want to restore all packages or only $pkg?\n");
+ tlwarn("Terminating.\n");
+ exit 1;
+ }
+ if ($opts{"all"}) {
+ init_local_db(1);
+ return if !check_on_writable();
+ if (!$opts{"force"}) {
+ print "Do you really want to restore all packages to the latest revision found in\n\t$opts{'backupdir'}\n===> (y/N): ";
+ my $yesno = <STDIN>;
+ if ($yesno !~ m/^y(es)?$/i) {
+ print "Ok, cancelling the restore!\n";
+ finish(0);
+ }
+ }
+ for my $p (sort keys %backups) {
+ my @tmp = sort {$b <=> $a} (keys %{$backups{$p}});
+ my $rev = $tmp[0];
+ print "Restoring $p, $rev from $opts{'backupdir'}/${p}.r${rev}.tar.xz\n";
+ if (!$opts{"dry"}) {
+ # first remove the package, then reinstall it
+ # this way we get rid of useless files
+ restore_one_package($p, $rev, $opts{"backupdir"});
+ }
+ }
+ # localtlpdb already saved, so we are finished
+ return;
+ }
if (!defined($pkg)) {
if (keys %backups) {
print "Available backups:\n";
foreach my $p (sort keys %backups) {
print "$p: ";
- my @rs = sort (keys %{$backups{$p}});
+ my @rs = sort {$b <=> $a} (keys %{$backups{$p}});
print "@rs\n";
}
} else {
@@ -1210,17 +1286,7 @@ sub action_restore {
init_local_db(1);
# first remove the package, then reinstall it
# this way we get rid of useless files
- $opts{"backupdir"} = abs_path($opts{"backupdir"});
- $localtlmedia->remove_package($pkg);
- TeXLive::TLMedia->_install_package("$opts{'backupdir'}/${pkg}.r${rev}.tar.xz" , 0, [] ,$localtlpdb);
- logpackage("restore: $pkg ($rev)");
- # now we have to read the .tlpobj file and add it to the DB
- my $tlpobj = TeXLive::TLPOBJ->new;
- $tlpobj->from_file($localtlpdb->root . "/tlpkg/tlpobj/$pkg.tlpobj");
- $localtlpdb->add_tlpobj($tlpobj);
- TeXLive::TLUtils::announce_execute_actions("enable",
- $localtlpdb->get_package($pkg));
- $localtlpdb->save;
+ restore_one_package($pkg, $rev, $opts{"backupdir"});
}
} else {
print "revision $rev for $pkg is not present in $opts{'backupdir'}\n";
@@ -1320,7 +1386,7 @@ sub action_backup {
} else {
my $tlp = $localtlpdb->get_package($pkg);
info("saving current status of $pkg to $opts{'backupdir'}/${pkg}.r" .
- $tlp->revision . "tar.xz\n");
+ $tlp->revision . ".tar.xz\n");
if (!$opts{"dry-run"}) {
$tlp->make_container("xz", $localtlpdb->root,
$opts{"backupdir"}, "${pkg}.r" . $tlp->revision);
@@ -4719,11 +4785,14 @@ performed are written to the terminal.
=back
-=head2 restore --backupdir I<dir> [I<pkg> [I<rev>]
+=head2 restore [--backupdir I<dir>] [--all | I<pkg> [I<rev>]]
Restore a package from a previously-made backup.
-If neither I<pkg> nor I<rev> are given, list the available backup
+If C<--all> is given, try to restore the latest revision of all
+package backups found in the backup directory.
+
+Otherwise, if neither I<pkg> nor I<rev> are given, list the available backup
revisions for all packages.
With I<pkg> given but no I<rev>, list all available backup revisions of
@@ -4743,7 +4812,14 @@ written to the terminal.
=item B<--backupdir> I<directory>
-Specify the directory where the backups are to be found.
+Specify the directory where the backups are to be found. If not given
+it will be taken from the configuration setting in the TLPDB.
+
+=item B<--all>
+
+Try to restore the latest revision of all
+package backups found in the backup directory. Additional non-option
+arguments (like I<pkg>) are not allowed.
=back