diff options
author | Norbert Preining <preining@logic.at> | 2010-03-31 22:48:52 +0000 |
---|---|---|
committer | Norbert Preining <preining@logic.at> | 2010-03-31 22:48:52 +0000 |
commit | 010f9b8f9711d7393dfea00a88948d257af5acac (patch) | |
tree | 97c3b000a78a20c7959c825e83a47f3161d7af2b /Master/texmf | |
parent | 7d673020a0342d44ad1bf794091640447dc67d88 (diff) |
tlmgr: support tlmgr restore --all (restoring from all available backups the
latest one), and separating some functions for reusage in the GUI
git-svn-id: svn://tug.org/texlive/trunk@17643 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf')
-rwxr-xr-x | Master/texmf/scripts/texlive/tlmgr.pl | 160 |
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 |