summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-09-15 22:08:36 +0900
committerNorbert Preining <norbert@preining.info>2023-09-15 22:08:36 +0900
commit63837bacb6151e1ebb15829e6e559fcd2389cd1c (patch)
treefe252dd4a9159e5b0b1f3e34f19eb8e74e9ab68e
parent6701ce2c59ac18347d73a7252042ae9ba58ab082 (diff)
tlmgr: on update test that we can remove files (deal with ro dirs)dev/check-dir-before-remove
-rwxr-xr-xMaster/texmf-dist/scripts/texlive/tlmgr.pl9
-rw-r--r--Master/tlpkg/TeXLive/TLPDB.pm23
-rw-r--r--Master/tlpkg/TeXLive/TLUtils.pm73
3 files changed, 76 insertions, 29 deletions
diff --git a/Master/texmf-dist/scripts/texlive/tlmgr.pl b/Master/texmf-dist/scripts/texlive/tlmgr.pl
index d0d4456bce1..db5753c0efa 100755
--- a/Master/texmf-dist/scripts/texlive/tlmgr.pl
+++ b/Master/texmf-dist/scripts/texlive/tlmgr.pl
@@ -3371,8 +3371,11 @@ sub action_update {
if ($pkg =~ m/$CriticalPackagesRegexp/) {
debug("Not removing critical package $pkg\n");
} else {
- $localtlpdb->remove_package($pkg,
- "remove-warn-files" => \%do_warn_on_move);
+ if (! $localtlpdb->remove_package($pkg,
+ "remove-warn-files" => \%do_warn_on_move)) {
+ info("aborted\n") unless $::machinereadable;
+ next;
+ }
}
if ($remotetlpdb->install_package($pkg, $localtlpdb)) {
# installation succeeded because we got a reference
@@ -10253,4 +10256,4 @@ $Id$
### tab-width: 2
### indent-tabs-mode: nil
### End:
-# vim:set tabstop=2 expandtab: #
+# vim:set tabstop=2 shiftwidth=2 expandtab: #
diff --git a/Master/tlpkg/TeXLive/TLPDB.pm b/Master/tlpkg/TeXLive/TLPDB.pm
index 1c02039e4ab..3d72e4c2b71 100644
--- a/Master/tlpkg/TeXLive/TLPDB.pm
+++ b/Master/tlpkg/TeXLive/TLPDB.pm
@@ -2107,14 +2107,27 @@ sub remove_package {
0, # tlpdbopt_desktop_integration, desktop part
$localtlpdb->option("post_code"));
}
- #
- my @removals = &TeXLive::TLUtils::removed_dirs (@goodfiles);
+ # we want to check whether we can actually remove files
+ # there might be various reasons that this fails, like texmf-dist
+ # directory suddently becoming ro (for whatever definition of
+ # suddenly).
+ my (%by_dirs, %removed_dirs) = &TeXLive::TLUtils::all_dirs_and_removed_dirs (@goodfiles);
+ my @removals = keys %removed_dirs;
+
+ # we have already check for the existence of the dirs returned
+ for my $d (keys %by_dirs) {
+ if (! &TeXLive::TLUtils::dir_writable($d)) {
+ tlwarn("TLPDB: directories are not writable, cannot remove files: $d\n");
+ return 0;
+ }
+ }
+
# now do the removal
for my $entry (@goodfiles) {
- unlink $entry;
+ unlink $entry or tlwarn("Could not unlink $entry: $!\n");
}
for my $d (@removals) {
- rmdir $d;
+ rmdir $d or tlwarn("Could not remove directory $d: $!\n")
}
$localtlpdb->remove_tlpobj($pkg);
TeXLive::TLUtils::announce_execute_actions("disable", $tlp);
@@ -3000,4 +3013,4 @@ GNU General Public License Version 2 or later.
### tab-width: 2
### indent-tabs-mode: nil
### End:
-# vim:set tabstop=2 expandtab autoindent: #
+# vim:set tabstop=2 shiftwidth=2 expandtab autoindent: #
diff --git a/Master/tlpkg/TeXLive/TLUtils.pm b/Master/tlpkg/TeXLive/TLUtils.pm
index cc4d49f1ecc..69566bc33b2 100644
--- a/Master/tlpkg/TeXLive/TLUtils.pm
+++ b/Master/tlpkg/TeXLive/TLUtils.pm
@@ -59,6 +59,8 @@ C<TeXLive::TLUtils> - TeX Live infrastructure miscellany
TeXLive::TLUtils::copy($file, $target_dir);
TeXLive::TLUtils::touch(@files);
TeXLive::TLUtils::collapse_dirs(@files);
+ TeXLive::TLUtils::all_dirs_and_removed_dirs(@files);
+ TeXLive::TLUtils::dirs_of_files(@files);
TeXLive::TLUtils::removed_dirs(@files);
TeXLive::TLUtils::download_file($path, $destination);
TeXLive::TLUtils::setup_programs($bindir, $platform);
@@ -210,6 +212,8 @@ BEGIN {
&copy
&touch
&collapse_dirs
+ &all_dirs_and_removed_dirs
+ &dirs_of_files
&removed_dirs
&install_package
&install_packages
@@ -1614,30 +1618,14 @@ sub collapse_dirs {
return @ret;
}
-=item C<removed_dirs(@files)>
-
-Returns all the directories from which all content will be removed.
-
-Here is the idea:
-
-=over 4
-
-=item create a hashes by_dir listing all files that should be removed
- by directory, i.e., key = dir, value is list of files
-
-=item for each of the dirs (keys of by_dir and ordered deepest first)
- check that all actually contained files are removed
- and all the contained dirs are in the removal list. If this is the
- case put that directory into the removal list
-
-=item return this removal list
+=item C<dirs_of_files(@files)>
-=back
+Returns all the directories in which at least one of the given
+files reside.
=cut
-sub removed_dirs {
+sub dirs_of_files {
my (@files) = @_;
- my %removed_dirs;
my %by_dir;
# construct hash of all directories mentioned, values are lists of the
@@ -1663,6 +1651,21 @@ sub removed_dirs {
$by_dir{$d} = \@a;
}
+ return %by_dir;
+}
+
+=item C<all_dirs_and_removed_dirs(@files)>
+
+Returns all the directories for files and those from which all
+content will be removed.
+
+=cut
+
+sub all_dirs_and_removed_dirs {
+ my (@files) = @_;
+ my %removed_dirs;
+ my %by_dir = dirs_of_files(@files);
+
# for each of our directories, see if we are removing everything in
# the directory. if so, return the directory; else return the
# individual files.
@@ -1698,9 +1701,37 @@ sub removed_dirs {
$removed_dirs{$d} = 1;
}
}
+ return (%by_dir, %removed_dirs);
+}
+
+=item C<removed_dirs(@files)>
+
+Returns all the directories from which all content will be removed.
+
+Here is the idea:
+
+=over 4
+
+=item create a hashes by_dir listing all files that should be removed
+ by directory, i.e., key = dir, value is list of files
+
+=item for each of the dirs (keys of by_dir and ordered deepest first)
+ check that all actually contained files are removed
+ and all the contained dirs are in the removal list. If this is the
+ case put that directory into the removal list
+
+=item return this removal list
+
+=back
+=cut
+
+sub removed_dirs {
+ my (@files) = @_;
+ my (%by_dir, %removed_dirs) = all_dirs_and_removed_dirs(@files);
return keys %removed_dirs;
}
+
=item C<time_estimate($totalsize, $donesize, $starttime)>
Returns the current running time and the estimated total time
@@ -5275,4 +5306,4 @@ GNU General Public License Version 2 or later.
### tab-width: 2
### indent-tabs-mode: nil
### End:
-# vim:set tabstop=2 expandtab: #
+# vim:set tabstop=2 shiftwidth=2 expandtab: #