From 63837bacb6151e1ebb15829e6e559fcd2389cd1c Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Fri, 15 Sep 2023 22:08:36 +0900 Subject: tlmgr: on update test that we can remove files (deal with ro dirs) --- Master/texmf-dist/scripts/texlive/tlmgr.pl | 9 ++-- Master/tlpkg/TeXLive/TLPDB.pm | 23 ++++++++-- Master/tlpkg/TeXLive/TLUtils.pm | 73 +++++++++++++++++++++--------- 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 - 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 { © &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 - -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 -=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 + +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 + +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 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: # -- cgit v1.2.3