summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xMaster/texmf/scripts/texlive/tlmgr.pl395
1 files changed, 207 insertions, 188 deletions
diff --git a/Master/texmf/scripts/texlive/tlmgr.pl b/Master/texmf/scripts/texlive/tlmgr.pl
index a11cedc2740..f0daffa7810 100755
--- a/Master/texmf/scripts/texlive/tlmgr.pl
+++ b/Master/texmf/scripts/texlive/tlmgr.pl
@@ -2054,14 +2054,21 @@ sub action_update {
#
- # UPDATES
+ # UPDATES AND NEW PACKAGES
#
+ # order:
+ # - update normal packages
+ # - install new normal packages
+ # - update collections
+ # - install new collections
+ # - update schemes
+ # - install new schemes (? will not happen?)
#
- # update order of packages:
- # first all normal packages, then collections, then schemes
- # this way if installation breaks off and a new package in a collection
- # isn't already installed, but the collection already updated, it will
- # be reported as forcibly removed.
+ # this makes sure that only if all depending packages are installed
+ # the collection is updated, which in turn makes sure that
+ # if the installation of a new package does break it will not be
+ # counted as forcibly removed later on.
+ #
my @inst_packs;
my @inst_colls;
my @inst_schemes;
@@ -2077,165 +2084,6 @@ sub action_update {
}
@inst_packs = sort packagecmp @inst_packs;
- #
- foreach my $pkg (@inst_packs, @inst_colls, @inst_schemes) {
- # skip this loop if infra update on w32
- next if ($pkg =~ m/^00texlive/);
- my $tlp = $localtlpdb->get_package($pkg);
- # we checked already that this package is present!
- # but our checks seem to be wrong, no idea why
- if (!defined($tlp)) {
- tlwarn("tlmgr: tlp for package $pkg cannot be found, please report.\n");
- next;
- }
- my $unwind_package;
- my $remove_unwind_container = 0;
- my $rev = $tlp->revision;
- my $mediatlp = $tlmediatlpdb->get_package($pkg);
- if (!defined($mediatlp)) {
- debug("$pkg cannot be found in $location\n");
- next;
- }
- my $mediarev = $mediatlp->revision;
- $nrupdated++;
- if ($opts{"list"}) {
- if ($::machinereadable) {
- machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg});
- } else {
- my $kb = int($sizes{$pkg} / 1024) + 1;
- info("$pkg [${kb}k]: local: $rev, source: $mediarev (update)\n");
- }
- $updated{$pkg} = 1;
- next;
- } elsif (win32() && ($pkg =~ m/$CriticalPackagesRegexp/)) {
- # we pretend that the update happened
- # in order to calculate file changes properly
- $updated{$pkg} = 1;
- next;
- }
-
- # older tlmgr forgot to clear the relocated bit when saving a tlpobj
- # into the local tlpdb, although the paths were rewritten.
- # We have to clear this bit otherwise the make_container calls below
- # for creating an unwind container will create some rubbish
- # TODO for user mode we should NOT clear this bit!
- if ($tlp->relocated) {
- debug("tlmgr: warn, relocated bit set for $pkg, but that is wrong!\n");
- $tlp->relocated(0);
- }
-
- if ($opts{"backup"} && !$opts{"dry-run"}) {
- $tlp->make_container("xz", $root,
- $opts{"backupdir"}, "${pkg}.r" . $tlp->revision,
- $tlp->relocated);
- $unwind_package =
- "$opts{'backupdir'}/${pkg}.r" . $tlp->revision . ".tar.xz";
-
- if ($autobackup) {
- # in case we do auto backups we remove older backups
- clear_old_backups($pkg, $opts{"backupdir"}, $autobackup);
- }
- }
-
- my ($estrem, $esttot);
- if (!$opts{"list"}) {
- ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
- $donesize, $starttime);
- }
-
- if ($::machinereadable) {
- machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, $estrem, $esttot);
- } else {
- my $kb = int ($sizes{$pkg} / 1024) + 1;
- info("[$currnr/$totalnr, $estrem/$esttot] update: $pkg [${kb}k] ($rev -> $mediarev)");
- }
- $donesize += $sizes{$pkg};
- $currnr++;
-
- if ($opts{"dry-run"}) {
- info("\n") unless $::machinereadable;
- $updated{$pkg} = 1;
- next;
- } else {
- info(" ... ") unless $::machinereadable; # more to come
- }
-
- if (!$unwind_package) {
- # no backup was made, so let us create a temporary .tar file
- # of the package
- my $tlp = $localtlpdb->get_package($pkg);
- my ($s, $m, $fullname) = $tlp->make_container("tar", $root, $temp,
- "__BACKUP_${pkg}.r" . $tlp->revision,
- $tlp->relocated);
- if ($s <= 0) {
- tlwarn("\n$0: Creation of backup container of $pkg failed.\n");
- tlwarn("Continuing to update other packages, please retry...\n");
- # we should try to update other packages at least
- next;
- }
- $remove_unwind_container = 1;
- $unwind_package = "$fullname";
- }
- # first remove the package, then reinstall it
- # this way we get rid of useless files
- # force the deinstallation since we will reinstall it
- #
- # the remove_package should also remove empty dirs in case
- # a dir is changed into a file
- if ($pkg =~ m/$CriticalPackagesRegexp/) {
- debug("Not removing critical package $pkg\n");
- } else {
- $localtlmedia->remove_package($pkg);
- }
- if ($tlmediasrc->install_package($pkg, $localtlpdb)) {
- # installation succeeded because we got a reference
- logpackage("update: $pkg ($rev -> $mediarev)");
- unlink($unwind_package) if $remove_unwind_container;
- # remember successful update
- $updated{$pkg} = 1;
- } else {
- # install_package returned a scalar, so error.
- # now in fact we should do some cleanup, removing files and
- # dirs from the new package before re-installing the old one.
- # TODO
- logpackage("failed update: $pkg ($rev -> $mediarev)");
- tlwarn("\n\nInstallation of new version of $pkg did fail, trying to unwind.\n");
- if (win32()) {
- # w32 is notorious for not releasing a file immediately
- # we experienced permission denied errors
- my $newname = $unwind_package;
- $newname =~ s/__BACKUP/___BACKUP/;
- copy ("-f", $unwind_package, $newname);
- # try to remove the file if has been created by us
- unlink($unwind_package) if $remove_unwind_container;
- # and make sure that the temporary file is removed in any case
- $remove_unwind_container = 1;
- $unwind_package = $newname;
- }
- my $instret = TeXLive::TLMedia->_install_package("$unwind_package", 0,
- [], $localtlpdb);
- if ($instret) {
- # now we have to include the tlpobj
- my $tlpobj = TeXLive::TLPOBJ->new;
- $tlpobj->from_file($root . "/tlpkg/tlpobj/$pkg.tlpobj");
- $localtlpdb->add_tlpobj($tlpobj);
- $localtlpdb->save;
- logpackage("restore: $pkg ($rev)");
- tlwarn("Restoring old package state succeeded.\n");
- } else {
- logpackage("failed restore: $pkg ($rev)");
- tlwarn("Restoring of old package did NOT succeed.\n");
- tlwarn("Most likely repair: run tlmgr install $pkg and hope.\n");
- }
- unlink($unwind_package) if $remove_unwind_container;
- }
- info("done\n") unless $::machinereadable;
- }
-
-
- #
- # NEW PACKAGES
- #
my @new_packs;
my @new_colls;
my @new_schemes;
@@ -2250,46 +2098,217 @@ sub action_update {
}
}
@new_packs = sort packagecmp @new_packs;
+ my %is_new;
for my $pkg (@new_packs, @new_colls, @new_schemes) {
- if ($opts{"no-auto-install"}) {
- info("not auto-installing $pkg due to -no-auto-install (new on server)\n")
- unless $::machinereadable;
- } else {
- # install new packages
+ $is_new{$pkg} = 1;
+ }
+
+ #
+ # TODO idea
+ # currently this big loop contains a long if then for new packages
+ # and updated package. That *could* be merged into one so that
+ # some things like the logging has not been written two times.
+ # OTOH, the control flow in the "new package" part is much simpler
+ # and following it after the change would make it much harder
+ #
+ foreach my $pkg (@inst_packs, @new_packs, @inst_colls, @new_colls, @inst_schemes, @new_schemes) {
+
+ if (!$is_new{$pkg}) {
+ # skip this loop if infra update on w32
+ next if ($pkg =~ m/^00texlive/);
+ my $tlp = $localtlpdb->get_package($pkg);
+ # we checked already that this package is present!
+ # but our checks seem to be wrong, no idea why
+ if (!defined($tlp)) {
+ tlwarn("tlmgr: tlp for package $pkg cannot be found, please report.\n");
+ next;
+ }
+ my $unwind_package;
+ my $remove_unwind_container = 0;
+ my $rev = $tlp->revision;
my $mediatlp = $tlmediatlpdb->get_package($pkg);
if (!defined($mediatlp)) {
- tlwarn("\nShould not happen: $pkg not found in $location");
+ debug("$pkg cannot be found in $location\n");
next;
}
my $mediarev = $mediatlp->revision;
+ $nrupdated++;
+ if ($opts{"list"}) {
+ if ($::machinereadable) {
+ machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg});
+ } else {
+ my $kb = int($sizes{$pkg} / 1024) + 1;
+ info("$pkg [${kb}k]: local: $rev, source: $mediarev (update)\n");
+ }
+ $updated{$pkg} = 1;
+ next;
+ } elsif (win32() && ($pkg =~ m/$CriticalPackagesRegexp/)) {
+ # we pretend that the update happened
+ # in order to calculate file changes properly
+ $updated{$pkg} = 1;
+ next;
+ }
+
+ # older tlmgr forgot to clear the relocated bit when saving a tlpobj
+ # into the local tlpdb, although the paths were rewritten.
+ # We have to clear this bit otherwise the make_container calls below
+ # for creating an unwind container will create some rubbish
+ # TODO for user mode we should NOT clear this bit!
+ if ($tlp->relocated) {
+ debug("tlmgr: warn, relocated bit set for $pkg, but that is wrong!\n");
+ $tlp->relocated(0);
+ }
+
+ if ($opts{"backup"} && !$opts{"dry-run"}) {
+ $tlp->make_container("xz", $root,
+ $opts{"backupdir"}, "${pkg}.r" . $tlp->revision,
+ $tlp->relocated);
+ $unwind_package =
+ "$opts{'backupdir'}/${pkg}.r" . $tlp->revision . ".tar.xz";
+
+ if ($autobackup) {
+ # in case we do auto backups we remove older backups
+ clear_old_backups($pkg, $opts{"backupdir"}, $autobackup);
+ }
+ }
+
my ($estrem, $esttot);
if (!$opts{"list"}) {
($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
- $donesize, $starttime);
+ $donesize, $starttime);
}
+
if ($::machinereadable) {
- my @maargs = ($pkg, $FLAG_AUTOINSTALL, "-", $mediatlp->revision, $sizes{$pkg});
- if (!$opts{"list"}) {
- push @maargs, $estrem, $esttot;
- }
- machine_line(@maargs);
+ machine_line($pkg, $FLAG_UPDATE, $rev, $mediarev, $sizes{$pkg}, $estrem, $esttot);
} else {
- my $kb = int($sizes{$pkg} / 1024) + 1;
- if ($opts{"list"}) {
- info("$pkg [${kb}k]: local: <absent>, source: " . $mediatlp->revision . " (auto-install)\n");
- } else {
- info("[$currnr/$totalnr, $estrem/$esttot] auto-install: $pkg [${kb}k]\n");
- }
+ my $kb = int ($sizes{$pkg} / 1024) + 1;
+ info("[$currnr/$totalnr, $estrem/$esttot] update: $pkg [${kb}k] ($rev -> $mediarev)");
}
- $currnr++;
$donesize += $sizes{$pkg};
- next if ($opts{"dry-run"} || $opts{"list"});
+ $currnr++;
+
+ if ($opts{"dry-run"}) {
+ info("\n") unless $::machinereadable;
+ $updated{$pkg} = 1;
+ next;
+ } else {
+ info(" ... ") unless $::machinereadable; # more to come
+ }
+
+ if (!$unwind_package) {
+ # no backup was made, so let us create a temporary .tar file
+ # of the package
+ my $tlp = $localtlpdb->get_package($pkg);
+ my ($s, $m, $fullname) = $tlp->make_container("tar", $root, $temp,
+ "__BACKUP_${pkg}.r" . $tlp->revision,
+ $tlp->relocated);
+ if ($s <= 0) {
+ tlwarn("\n$0: Creation of backup container of $pkg failed.\n");
+ tlwarn("Continuing to update other packages, please retry...\n");
+ # we should try to update other packages at least
+ next;
+ }
+ $remove_unwind_container = 1;
+ $unwind_package = "$fullname";
+ }
+ # first remove the package, then reinstall it
+ # this way we get rid of useless files
+ # force the deinstallation since we will reinstall it
+ #
+ # the remove_package should also remove empty dirs in case
+ # a dir is changed into a file
+ if ($pkg =~ m/$CriticalPackagesRegexp/) {
+ debug("Not removing critical package $pkg\n");
+ } else {
+ $localtlmedia->remove_package($pkg);
+ }
if ($tlmediasrc->install_package($pkg, $localtlpdb)) {
# installation succeeded because we got a reference
- logpackage("auto-install new: $pkg ($mediarev)");
- $nrupdated++;
+ logpackage("update: $pkg ($rev -> $mediarev)");
+ unlink($unwind_package) if $remove_unwind_container;
+ # remember successful update
+ $updated{$pkg} = 1;
} else {
- tlwarn("$0: couldn't install new package $pkg\n");
+ # install_package returned a scalar, so error.
+ # now in fact we should do some cleanup, removing files and
+ # dirs from the new package before re-installing the old one.
+ # TODO
+ logpackage("failed update: $pkg ($rev -> $mediarev)");
+ tlwarn("\n\nInstallation of new version of $pkg did fail, trying to unwind.\n");
+ if (win32()) {
+ # w32 is notorious for not releasing a file immediately
+ # we experienced permission denied errors
+ my $newname = $unwind_package;
+ $newname =~ s/__BACKUP/___BACKUP/;
+ copy ("-f", $unwind_package, $newname);
+ # try to remove the file if has been created by us
+ unlink($unwind_package) if $remove_unwind_container;
+ # and make sure that the temporary file is removed in any case
+ $remove_unwind_container = 1;
+ $unwind_package = $newname;
+ }
+ my $instret = TeXLive::TLMedia->_install_package("$unwind_package", 0,
+ [], $localtlpdb);
+ if ($instret) {
+ # now we have to include the tlpobj
+ my $tlpobj = TeXLive::TLPOBJ->new;
+ $tlpobj->from_file($root . "/tlpkg/tlpobj/$pkg.tlpobj");
+ $localtlpdb->add_tlpobj($tlpobj);
+ $localtlpdb->save;
+ logpackage("restore: $pkg ($rev)");
+ tlwarn("Restoring old package state succeeded.\n");
+ } else {
+ logpackage("failed restore: $pkg ($rev)");
+ tlwarn("Restoring of old package did NOT succeed.\n");
+ tlwarn("Most likely repair: run tlmgr install $pkg and hope.\n");
+ }
+ unlink($unwind_package) if $remove_unwind_container;
+ }
+ info("done\n") unless $::machinereadable;
+ } else { # $is_new{$pkg} is true!!!
+ #
+ # NEW PACKAGES
+ #
+ if ($opts{"no-auto-install"}) {
+ info("not auto-installing $pkg due to -no-auto-install (new on server)\n")
+ unless $::machinereadable;
+ } else {
+ # install new packages
+ my $mediatlp = $tlmediatlpdb->get_package($pkg);
+ if (!defined($mediatlp)) {
+ tlwarn("\nShould not happen: $pkg not found in $location");
+ next;
+ }
+ my $mediarev = $mediatlp->revision;
+ my ($estrem, $esttot);
+ if (!$opts{"list"}) {
+ ($estrem, $esttot) = TeXLive::TLUtils::time_estimate($totalsize,
+ $donesize, $starttime);
+ }
+ if ($::machinereadable) {
+ my @maargs = ($pkg, $FLAG_AUTOINSTALL, "-", $mediatlp->revision, $sizes{$pkg});
+ if (!$opts{"list"}) {
+ push @maargs, $estrem, $esttot;
+ }
+ machine_line(@maargs);
+ } else {
+ my $kb = int($sizes{$pkg} / 1024) + 1;
+ if ($opts{"list"}) {
+ info("$pkg [${kb}k]: local: <absent>, source: " . $mediatlp->revision . " (auto-install)\n");
+ } else {
+ info("[$currnr/$totalnr, $estrem/$esttot] auto-install: $pkg [${kb}k]\n");
+ }
+ }
+ $currnr++;
+ $donesize += $sizes{$pkg};
+ next if ($opts{"dry-run"} || $opts{"list"});
+ if ($tlmediasrc->install_package($pkg, $localtlpdb)) {
+ # installation succeeded because we got a reference
+ logpackage("auto-install new: $pkg ($mediarev)");
+ $nrupdated++;
+ } else {
+ tlwarn("$0: couldn't install new package $pkg\n");
+ }
}
}
}