Add support for long paths
* Add more file i/o wrappers in platform_utils to allow using
long paths (length > MAX_PATH) on Windows.
* Paths using the long path syntax ("\\?\" prefix) should never
escape the platform_utils API surface area, so that this
specific syntax is not visible to the rest of the repo code base.
* Forward many calls from os.xxx to platform_utils.xxx in various place
to ensure long paths support, specifically when repo decides to delete
obsolete directories.
* There are more places that need to be converted to support long paths,
this commit is an initial effort to unblock a few common use cases.
* Also, fix remove function to handle directory symlinks
Change-Id: If82ccc408e516e96ff7260be25f8fd2fe3f9571a
diff --git a/subcmds/status.py b/subcmds/status.py
index b47c873..773f22d 100644
--- a/subcmds/status.py
+++ b/subcmds/status.py
@@ -26,6 +26,7 @@
import os
from color import Coloring
+import platform_utils
class Status(PagedCommand):
common = True
@@ -115,7 +116,7 @@
"""find 'dirs' that are present in 'proj_dirs_parents' but not in 'proj_dirs'"""
status_header = ' --\t'
for item in dirs:
- if not os.path.isdir(item):
+ if not platform_utils.isdir(item):
outstring.append(''.join([status_header, item]))
continue
if item in proj_dirs:
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 943a026..f6bd983 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -474,8 +474,8 @@
# so rmtree works.
try:
platform_utils.rmtree(os.path.join(path, '.git'))
- except OSError:
- print('Failed to remove %s' % os.path.join(path, '.git'), file=sys.stderr)
+ except OSError as e:
+ print('Failed to remove %s (%s)' % (os.path.join(path, '.git'), str(e)), file=sys.stderr)
print('error: Failed to delete obsolete path %s' % path, file=sys.stderr)
print(' remove manually, then run sync again', file=sys.stderr)
return -1
@@ -484,12 +484,12 @@
# another git project
dirs_to_remove = []
failed = False
- for root, dirs, files in os.walk(path):
+ for root, dirs, files in platform_utils.walk(path):
for f in files:
try:
platform_utils.remove(os.path.join(root, f))
- except OSError:
- print('Failed to remove %s' % os.path.join(root, f), file=sys.stderr)
+ except OSError as e:
+ print('Failed to remove %s (%s)' % (os.path.join(root, f), str(e)), file=sys.stderr)
failed = True
dirs[:] = [d for d in dirs
if not os.path.lexists(os.path.join(root, d, '.git'))]
@@ -499,14 +499,14 @@
if platform_utils.islink(d):
try:
platform_utils.remove(d)
- except OSError:
- print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr)
+ except OSError as e:
+ print('Failed to remove %s (%s)' % (os.path.join(root, d), str(e)), file=sys.stderr)
failed = True
- elif len(os.listdir(d)) == 0:
+ elif len(platform_utils.listdir(d)) == 0:
try:
- os.rmdir(d)
- except OSError:
- print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr)
+ platform_utils.rmdir(d)
+ except OSError as e:
+ print('Failed to remove %s (%s)' % (os.path.join(root, d), str(e)), file=sys.stderr)
failed = True
continue
if failed:
@@ -517,8 +517,8 @@
# Try deleting parent dirs if they are empty
project_dir = path
while project_dir != self.manifest.topdir:
- if len(os.listdir(project_dir)) == 0:
- os.rmdir(project_dir)
+ if len(platform_utils.listdir(project_dir)) == 0:
+ platform_utils.rmdir(project_dir)
else:
break
project_dir = os.path.dirname(project_dir)