From 010fed771183c23c0e7d04a4e7292782f68de9db Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Fri, 11 Nov 2016 14:25:29 -0800 Subject: Replace all os.remove calls os.remove raises an exception when deleting read-only files on Windows. Replace all calls with calls to platform_utils.remove, which deals with deals with that issue. Change-Id: I4dc9e0c9a36b4238880520c69f5075eca40f3e66 --- editor.py | 3 ++- git_config.py | 7 ++++--- manifest_xml.py | 2 +- platform_utils.py | 17 +++++++++++++++++ project.py | 28 ++++++++++++++-------------- subcmds/sync.py | 10 +++++----- 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/editor.py b/editor.py index 883a1a83..96d7ce4c 100644 --- a/editor.py +++ b/editor.py @@ -21,6 +21,7 @@ import subprocess import tempfile from error import EditorError +import platform_utils class Editor(object): """Manages the user's preferred text editor.""" @@ -107,4 +108,4 @@ least one of these before using this command.""", file=sys.stderr) finally: if fd: os.close(fd) - os.remove(path) + platform_utils.remove(path) diff --git a/git_config.py b/git_config.py index 9d5874a2..3ba9dbd1 100644 --- a/git_config.py +++ b/git_config.py @@ -42,6 +42,7 @@ else: from signal import SIGTERM from error import GitError, UploadError +import platform_utils from trace import Trace if is_python3(): from http.client import HTTPException @@ -268,7 +269,7 @@ class GitConfig(object): try: if os.path.getmtime(self._json) \ <= os.path.getmtime(self.file): - os.remove(self._json) + platform_utils.remove(self._json) return None except OSError: return None @@ -280,7 +281,7 @@ class GitConfig(object): finally: fd.close() except (IOError, ValueError): - os.remove(self._json) + platform_utils.remove(self._json) return None def _SaveJson(self, cache): @@ -292,7 +293,7 @@ class GitConfig(object): fd.close() except (IOError, TypeError): if os.path.exists(self._json): - os.remove(self._json) + platform_utils.remove(self._json) def _ReadGit(self): """ diff --git a/manifest_xml.py b/manifest_xml.py index 05651c6c..9b5d7847 100644 --- a/manifest_xml.py +++ b/manifest_xml.py @@ -166,7 +166,7 @@ class XmlManifest(object): try: if os.path.lexists(self.manifestFile): - os.remove(self.manifestFile) + platform_utils.remove(self.manifestFile) platform_utils.symlink(os.path.join('manifests', name), self.manifestFile) except OSError as e: raise ManifestParseError('cannot link manifest %s: %s' % (name, str(e))) diff --git a/platform_utils.py b/platform_utils.py index 2ad56490..33cb2ec3 100644 --- a/platform_utils.py +++ b/platform_utils.py @@ -244,6 +244,23 @@ def rename(src, dst): os.rename(src, dst) +def remove(path): + """Remove (delete) the file path. This is a replacement for os.remove, but + allows deleting read-only files on Windows. + """ + if isWindows(): + try: + os.remove(path) + except OSError as e: + if e.errno == errno.EACCES: + os.chmod(path, stat.S_IWRITE) + os.remove(path) + else: + raise + else: + os.remove(path) + + def islink(path): """Test whether a path is a symbolic link. diff --git a/project.py b/project.py index 655b2024..338ce93c 100644 --- a/project.py +++ b/project.py @@ -65,7 +65,7 @@ def _lwrite(path, content): try: platform_utils.rename(lock, path) except OSError: - os.remove(lock) + platform_utils.remove(lock) raise @@ -250,7 +250,7 @@ class _CopyFile(object): try: # remove existing file first, since it might be read-only if os.path.exists(dest): - os.remove(dest) + platform_utils.remove(dest) else: dest_dir = os.path.dirname(dest) if not os.path.isdir(dest_dir): @@ -279,7 +279,7 @@ class _LinkFile(object): try: # remove existing file first, since it might be read-only if os.path.lexists(absDest): - os.remove(absDest) + platform_utils.remove(absDest) else: dest_dir = os.path.dirname(absDest) if not os.path.isdir(dest_dir): @@ -1242,7 +1242,7 @@ class Project(object): if not self._ExtractArchive(tarpath, path=topdir): return False try: - os.remove(tarpath) + platform_utils.remove(tarpath) except OSError as e: _warn("Cannot remove archive %s: %s", tarpath, str(e)) self._CopyAndLinkFiles() @@ -1302,7 +1302,7 @@ class Project(object): else: self._InitMirrorHead() try: - os.remove(os.path.join(self.gitdir, 'FETCH_HEAD')) + platform_utils.remove(os.path.join(self.gitdir, 'FETCH_HEAD')) except OSError: pass return True @@ -1812,7 +1812,7 @@ class Project(object): except GitError: return [], [] finally: - os.remove(temp_gitmodules_path) + platform_utils.remove(temp_gitmodules_path) names = set() paths = {} @@ -2104,7 +2104,7 @@ class Project(object): if old_packed != '': _lwrite(packed_refs, old_packed) else: - os.remove(packed_refs) + platform_utils.remove(packed_refs) self.bare_git.pack_refs('--all', '--prune') if is_sha1 and current_branch_only: @@ -2166,14 +2166,14 @@ class Project(object): ok = GitCommand(self, cmd, bare=True).Wait() == 0 if os.path.exists(bundle_dst): - os.remove(bundle_dst) + platform_utils.remove(bundle_dst) if os.path.exists(bundle_tmp): - os.remove(bundle_tmp) + platform_utils.remove(bundle_tmp) return ok def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet): if os.path.exists(dstPath): - os.remove(dstPath) + platform_utils.remove(dstPath) cmd = ['curl', '--fail', '--output', tmpPath, '--netrc', '--location'] if quiet: @@ -2183,7 +2183,7 @@ class Project(object): if size >= 1024: cmd += ['--continue-at', '%d' % (size,)] else: - os.remove(tmpPath) + platform_utils.remove(tmpPath) if 'http_proxy' in os.environ and 'darwin' == sys.platform: cmd += ['--proxy', os.environ['http_proxy']] with GetUrlCookieFile(srcUrl, quiet) as (cookiefile, _proxy): @@ -2217,7 +2217,7 @@ class Project(object): platform_utils.rename(tmpPath, dstPath) return True else: - os.remove(tmpPath) + platform_utils.remove(tmpPath) return False else: return False @@ -2390,7 +2390,7 @@ class Project(object): continue if os.path.exists(dst): if filecmp.cmp(stock_hook, dst, shallow=False): - os.remove(dst) + platform_utils.remove(dst) else: _warn("%s: Not replacing locally modified %s hook", self.relpath, name) @@ -2508,7 +2508,7 @@ class Project(object): # file doesn't either. if name in symlink_files and not os.path.lexists(src): try: - os.remove(dst) + platform_utils.remove(dst) except OSError: pass diff --git a/subcmds/sync.py b/subcmds/sync.py index 93fea23b..cda47fdd 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -489,7 +489,7 @@ later is required to fix a server side protocol bug. for root, dirs, files in os.walk(path): for f in files: try: - os.remove(os.path.join(root, f)) + platform_utils.remove(os.path.join(root, f)) except OSError: print('Failed to remove %s' % os.path.join(root, f), file=sys.stderr) failed = True @@ -500,7 +500,7 @@ later is required to fix a server side protocol bug. for d in reversed(dirs_to_remove): if platform_utils.islink(d): try: - os.remove(d) + platform_utils.remove(d) except OSError: print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr) failed = True @@ -712,7 +712,7 @@ later is required to fix a server side protocol bug. else: # Not smart sync or smart tag mode if os.path.isfile(smart_sync_manifest_path): try: - os.remove(smart_sync_manifest_path) + platform_utils.remove(smart_sync_manifest_path) except OSError as e: print('error: failed to remove existing smart sync override manifest: %s' % e, file=sys.stderr) @@ -956,7 +956,7 @@ class _FetchTimes(object): f.close() except (IOError, ValueError): try: - os.remove(self._path) + platform_utils.remove(self._path) except OSError: pass self._times = {} @@ -980,7 +980,7 @@ class _FetchTimes(object): f.close() except (IOError, TypeError): try: - os.remove(self._path) + platform_utils.remove(self._path) except OSError: pass -- cgit v1.2.3-54-g00ecf