[jhbuild] use own rename() function that replaces existing files also on Windows



commit 89fc1a270965c83bd707ae0282cb8f6f135ac620
Author: Marcin Wojdyr <wojdyr gmail com>
Date:   Wed Feb 22 10:55:53 2012 +0000

    use own rename() function that replaces existing files also on Windows
    
    os.rename(src, dst) works differently on Unix and Windows.  On Unix, if
    dst exists and is a file, it will be replaced silently if the user has
    permission.  On Windows, if dst already exists, OSError will be raised.
    
    All calls to os.rename() has been replaced with fileutils.rename(),
    which tries to unlink the dst file, if exists, also on Windows.
    Fixes Bug 670225.

 jhbuild/modtypes/__init__.py |    4 ++--
 jhbuild/moduleset.py         |    3 ++-
 jhbuild/utils/fileutils.py   |   18 ++++++++++++++++++
 jhbuild/utils/packagedb.py   |    6 +++---
 jhbuild/utils/unpack.py      |    5 +++--
 5 files changed, 28 insertions(+), 8 deletions(-)
---
diff --git a/jhbuild/modtypes/__init__.py b/jhbuild/modtypes/__init__.py
index 5049d7b..62bd9aa 100644
--- a/jhbuild/modtypes/__init__.py
+++ b/jhbuild/modtypes/__init__.py
@@ -229,7 +229,7 @@ them into the prefix."""
             else:
                 num_copied += 1
                 try:
-                    os.rename(src_path, dest_path)
+                    fileutils.rename(src_path, dest_path)
                 except OSError, e:
                     logging.error(_('Failed to rename %(src)r to %(dest)r: %(msg)s') %
                                   {'src': src_path,
@@ -293,7 +293,7 @@ them into the prefix."""
             if os.path.exists(broken_name):
                 assert broken_name.startswith(buildscript.config.top_builddir)
                 shutil.rmtree(broken_name)
-            os.rename(destdir, broken_name)
+            fileutils.rename(destdir, broken_name)
         else:
             assert destdir.startswith(buildscript.config.prefix)
             os.rmdir(destdir)
diff --git a/jhbuild/moduleset.py b/jhbuild/moduleset.py
index 9f99e84..2119eee 100644
--- a/jhbuild/moduleset.py
+++ b/jhbuild/moduleset.py
@@ -41,6 +41,7 @@ from jhbuild.utils.cmds import compare_version, get_output
 from jhbuild.modtypes.testmodule import TestModule
 from jhbuild.versioncontrol.tarball import TarballBranch
 from jhbuild.utils import systeminstall
+from jhbuild.utils import fileutils
 
 __all__ = ['load', 'load_tests', 'get_default_repo']
 
@@ -57,7 +58,7 @@ class ModuleSet:
             legacy_pkgdb_path = os.path.join(self.config.prefix, 'share', 'jhbuild', 'packagedb.xml')
             new_pkgdb_path = os.path.join(self.config.top_builddir, 'packagedb.xml')
             if os.path.isfile(legacy_pkgdb_path):
-                os.rename(legacy_pkgdb_path, new_pkgdb_path)
+                fileutils.rename(legacy_pkgdb_path, new_pkgdb_path)
             self.packagedb = packagedb.PackageDB(new_pkgdb_path, config)
         else:
             self.packagedb = db
diff --git a/jhbuild/utils/fileutils.py b/jhbuild/utils/fileutils.py
index 1ef4e26..1af5724 100644
--- a/jhbuild/utils/fileutils.py
+++ b/jhbuild/utils/fileutils.py
@@ -21,6 +21,7 @@
 
 import os
 import sys
+import errno
 
 def _accumulate_dirtree_contents_recurse(path, contents):
     names = os.listdir(path)
@@ -89,3 +90,20 @@ def filter_files_by_prefix(config, file_paths):
         result.append(path)
     return result
 
+# Modified rename from http://selenic.com/repo/hg/file/tip/mercurial/windows.py
+def _windows_rename(src, dst):
+    '''atomically rename file src to dst, replacing dst if it exists'''
+    try:
+        os.rename(src, dst)
+    except OSError, e:
+        if e.errno != errno.EEXIST:
+            raise
+        # Windows does not allow to unlink open file.
+        # Unlike in Mercurial, we don't try any workaround here.
+        os.unlink(dst)
+        os.rename(src, dst)
+
+if os.name == 'nt':
+    rename = _windows_rename
+else:
+    rename = os.rename
diff --git a/jhbuild/utils/packagedb.py b/jhbuild/utils/packagedb.py
index a649592..4fa044d 100644
--- a/jhbuild/utils/packagedb.py
+++ b/jhbuild/utils/packagedb.py
@@ -115,8 +115,8 @@ class PackageEntry:
             else:
                 os.fsync(fd.fileno())
             fd.close()
-            os.rename(os.path.join(self.manifests_dir, self.package + '.tmp'),
-                      os.path.join(self.manifests_dir, self.package))
+            fileutils.rename(os.path.join(self.manifests_dir, self.package + '.tmp'),
+                             os.path.join(self.manifests_dir, self.package))
         return entry_node
 
 class PackageDB:
@@ -196,7 +196,7 @@ class PackageDB:
         tmp_dbfile.flush()
         os.fsync(tmp_dbfile.fileno())
         tmp_dbfile.close()
-        os.rename(tmp_dbfile_path, self.dbfile)
+        fileutils.rename(tmp_dbfile_path, self.dbfile)
         # Ensure we don't reread what we already have cached
         self._entries_stat = os.stat(self.dbfile)
 
diff --git a/jhbuild/utils/unpack.py b/jhbuild/utils/unpack.py
index 1aeddce..350ebf4 100644
--- a/jhbuild/utils/unpack.py
+++ b/jhbuild/utils/unpack.py
@@ -24,6 +24,7 @@ import tempfile
 
 from jhbuild.utils.cmds import has_command
 from jhbuild.errors import CommandError
+from jhbuild.utils import fileutils
 
 
 def unpack_tar_file(localfile, target_directory):
@@ -153,8 +154,8 @@ def unpack_archive(buildscript, localfile, target_directory, checkoutdir=None):
         if len(os.listdir(target_directory)) == 1:
             # a single directory, just move it
             tmpdirname = os.path.join(target_directory, os.listdir(target_directory)[0])
-            os.rename(tmpdirname, os.path.join(final_target_directory, checkoutdir))
+            fileutils.rename(tmpdirname, os.path.join(final_target_directory, checkoutdir))
             os.rmdir(target_directory)
         else:
             # more files, just rename the temporary directory to the final name
-            os.rename(target_directory, os.path.join(final_target_directory, checkoutdir))
+            fileutils.rename(target_directory, os.path.join(final_target_directory, checkoutdir))



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]