Commit d4218d4d authored by scottmg@chromium.org's avatar scottmg@chromium.org

Attempt at making git-drover work on Windows

BUG=404755
R=sammc@chromium.org

Review URL: https://codereview.chromium.org/1387223002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@297055 0039d316-1c4b-4281-b951-d872f2087c98
parent 64f2fc3b
......@@ -821,10 +821,12 @@ def get_branches_info(include_tracking_status):
def make_workdir_common(repository, new_workdir, files_to_symlink,
files_to_copy):
files_to_copy, symlink=None):
if not symlink:
symlink = os.symlink
os.makedirs(new_workdir)
for entry in files_to_symlink:
clone_file(repository, new_workdir, entry, os.symlink)
clone_file(repository, new_workdir, entry, symlink)
for entry in files_to_copy:
clone_file(repository, new_workdir, entry, shutil.copy)
......
......@@ -20,6 +20,27 @@ class Error(Exception):
pass
if os.name == 'nt':
# This is a just-good-enough emulation of os.symlink for drover to work on
# Windows. It uses junctioning of directories (most of the contents of
# the .git directory), but copies files. Note that we can't use
# CreateSymbolicLink or CreateHardLink here, as they both require elevation.
# Creating reparse points is what we want for the directories, but doing so
# is a relatively messy set of DeviceIoControl work at the API level, so we
# simply shell to `mklink /j` instead.
def emulate_symlink_windows(source, link_name):
if os.path.isdir(source):
subprocess.check_call(['mklink', '/j',
link_name.replace('/', '\\'),
source.replace('/', '\\')],
shell=True)
else:
shutil.copy(source, link_name)
mk_symlink = emulate_symlink_windows
else:
mk_symlink = os.symlink
class _Drover(object):
def __init__(self, branch, revision, parent_repo, dry_run):
......@@ -72,7 +93,11 @@ class _Drover(object):
self._run_git_command(['branch', '-D', self._branch_name])
if self._workdir:
logging.debug('Deleting %s', self._workdir)
shutil.rmtree(self._workdir)
if os.name == 'nt':
# Use rmdir to properly handle the junctions we created.
subprocess.check_call(['rmdir', '/s', '/q', self._workdir], shell=True)
else:
shutil.rmtree(self._workdir)
self._dev_null_file.close()
@staticmethod
......@@ -95,8 +120,6 @@ class _Drover(object):
if not os.path.isdir(self._parent_repo):
raise Error('Invalid parent repo path %r' % self._parent_repo)
if not hasattr(os, 'symlink'):
raise Error('Symlink support is required')
self._run_git_command(['--help'], error_message='Unable to run git')
self._run_git_command(['status'],
......@@ -140,7 +163,7 @@ class _Drover(object):
logging.debug('Creating checkout in %s', self._workdir)
git_dir = os.path.join(self._workdir, '.git')
git_common.make_workdir_common(parent_git_dir, git_dir, self.FILES_TO_LINK,
self.FILES_TO_COPY)
self.FILES_TO_COPY, mk_symlink)
self._run_git_command(['config', 'core.sparsecheckout', 'true'])
with open(os.path.join(git_dir, 'info', 'sparse-checkout'), 'w') as f:
f.write('codereview.settings')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment