]> Savannah Git Hosting - gnulib.git/commitdiff
gnulib-tool.py: Avoid errors when writing to a VFAT file system, part 2.
authorBruno Haible <bruno@clisp.org>
Wed, 3 Aug 2022 12:27:51 +0000 (14:27 +0200)
committerBruno Haible <bruno@clisp.org>
Wed, 3 Aug 2022 12:27:51 +0000 (14:27 +0200)
* pygnulib/constants.py (movefile): New function.
* pygnulib/*.py: Use it instead of shutil.

ChangeLog
pygnulib/GLFileSystem.py
pygnulib/GLImport.py
pygnulib/GLTestDir.py
pygnulib/constants.py

index fe8225b5df88a19fad9f6c92fa337104992a209e..aeec6717fc77ab382de1768f633808541483452b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2022-08-03  Bruno Haible  <bruno@clisp.org>
 
+       gnulib-tool.py: Avoid errors when writing to a VFAT file system, part 2.
+       * pygnulib/constants.py (movefile): New function.
+       * pygnulib/*.py: Use it instead of shutil.
+
        gnulib-tool.py: Avoid errors when writing to a VFAT file system.
        * pygnulib/constants.py (copyfile, copyfile2): New functions.
        * gnulib-tool.py: Use them instead of shutil.
index 5368f3c1b8353751baa40199044e609ca04a0300..1f7a9f23435b524bc33be322a3d1bea20ceb215a 100644 (file)
@@ -43,6 +43,7 @@ __copyright__ = constants.__copyright__
 DIRS = constants.DIRS
 joinpath = constants.joinpath
 copyfile = constants.copyfile
+movefile = constants.movefile
 isdir = os.path.isdir
 isfile = os.path.isfile
 
@@ -266,7 +267,7 @@ class GLFileAssistant(object):
                     lookedup, joinpath(destdir, rewritten))
             else:  # if any of these conditions is not met
                 try:  # Try to move file
-                    shutil.move(tmpfile, joinpath(destdir, rewritten))
+                    movefile(tmpfile, joinpath(destdir, rewritten))
                 except Exception as error:
                     raise GLError(17, original)
         else:  # if self.config['dryrun']
@@ -308,7 +309,7 @@ class GLFileAssistant(object):
                 if isfile(backuppath):
                     os.remove(backuppath)
                 try:  # Try to replace the given file
-                    shutil.move(basepath, backuppath)
+                    movefile(basepath, backuppath)
                 except Exception as error:
                     raise GLError(17, original)
                 if self.filesystem.shouldLink(original, lookedup) == CopyAction.Symlink \
@@ -405,8 +406,8 @@ class GLFileAssistant(object):
                 if not self.config['dryrun']:
                     if isfile(backuppath):
                         os.remove(backuppath)
-                    shutil.move(basepath, backuppath)
-                    shutil.move(tmpfile, basepath)
+                    movefile(basepath, backuppath)
+                    movefile(tmpfile, basepath)
                 else:  # if self.config['dryrun']
                     os.remove(tmpfile)
         else:  # if not isfile(basepath)
@@ -414,7 +415,7 @@ class GLFileAssistant(object):
             if not self.config['dryrun']:
                 if isfile(basepath):
                     os.remove(basepath)
-                shutil.move(tmpfile, basepath)
+                movefile(tmpfile, basepath)
             else:  # if self.config['dryrun']
                 os.remove(tmpfile)
         result = tuple([basename, backupname, result_flag])
index cbee0c4f3315abf994df92a9272ac17e7c1f0d97..046cf4745da8f2e2c91aecfdb1ff715778334142 100644 (file)
@@ -53,6 +53,7 @@ compiler = constants.compiler
 joinpath = constants.joinpath
 cleaner = constants.cleaner
 copyfile2 = constants.copyfile2
+movefile = constants.movefile
 isabs = os.path.isabs
 isdir = os.path.isdir
 isfile = os.path.isfile
@@ -1043,7 +1044,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
                     try:  # Try to move file
                         if os.path.exists(backup):
                             os.remove(backup)
-                        shutil.move(path, '%s~' % path)
+                        movefile(path, '%s~' % path)
                     except Exception as error:
                         raise GLError(14, file)
                 else:  # if self.config['dryrun']
@@ -1143,7 +1144,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
                 tmpfile = self.assistant.tmpfilename(joinpath(pobase, file))
                 path = joinpath('build-aux', 'po', file)
                 lookedup, flag = filesystem.lookup(path)
-                shutil.move(lookedup, tmpfile)
+                movefile(lookedup, tmpfile)
                 basename = joinpath(pobase, file)
                 filename, backup, flag = self.assistant.super_update(
                     basename, tmpfile)
index c230fbc744341fa7fd3ba83aea1524214e1e0057..9065e462fac772744f1964027cc99bc1261e63e3 100644 (file)
@@ -54,6 +54,7 @@ TESTS = constants.TESTS
 compiler = constants.compiler
 joinpath = constants.joinpath
 copyfile = constants.copyfile
+movefile = constants.movefile
 isdir = os.path.isdir
 isfile = os.path.isfile
 normpath = os.path.normpath
@@ -658,7 +659,7 @@ class GLTestDir(object):
                     dest = src[:-1]
                     if isfile(dest):
                         os.remove(dest)
-                    shutil.move(src, dest)
+                    movefile(src, dest)
         # libtoolize
         if libtool:
             args = [UTILS['libtoolize'], '--copy']
@@ -692,7 +693,7 @@ class GLTestDir(object):
                         dest = src[:-1]
                         if isfile(dest):
                             os.remove(dest)
-                        shutil.move(src, dest)
+                        movefile(src, dest)
             # aclocal
             args = [UTILS['aclocal'], '-I', joinpath('..', m4base)]
             constants.execute(args, verbose)
index cf6f05eb987bc20e3ce8bf524bb3f8811fad4d47..34c17aec4631eada5e1a183624bc85de69f54834 100644 (file)
@@ -325,6 +325,19 @@ def copyfile2(src, dest):
         pass
 
 
+def movefile(src, dest):
+    '''Move/rename file src to file dest. Like shutil.move, but gracefully
+    handle common errors.'''
+    try:
+        shutil.move(src, dest)
+    except PermissionError:
+        # shutil.move invokes os.rename, catches the resulting OSError for
+        # errno=EXDEV, attempts a copy instead, and encounters a PermissionError
+        # while doing that.
+        copyfile2(src, dest)
+        os.remove(src)
+
+
 def link_relative(src, dest):
     '''Like ln -s, except that src is given relative to the current directory
     (or absolute), not given relative to the directory of dest.'''