mirror of
https://chromium.googlesource.com/chromium/tools/depot_tools.git
synced 2026-01-11 18:51:29 +00:00
gclient: Sync CIPD deps before running hooks.
Bug: 882611 Change-Id: I72646544a164f557ea7d53e0ce0f16d663618a98 Reviewed-on: https://chromium-review.googlesource.com/c/1255446 Reviewed-by: Andrii Shyshkalov <tandrii@chromium.org> Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
This commit is contained in:
201
gclient.py
201
gclient.py
@@ -1563,6 +1563,103 @@ it or fix the checkout.
|
||||
patch_refs[patch_repo] = patch_ref
|
||||
return patch_refs, target_branches
|
||||
|
||||
def _RemoveUnversionedGitDirs(self):
|
||||
"""Remove directories that are no longer part of the checkout.
|
||||
|
||||
Notify the user if there is an orphaned entry in their working copy.
|
||||
Only delete the directory if there are no changes in it, and
|
||||
delete_unversioned_trees is set to true.
|
||||
"""
|
||||
|
||||
entries = [i.name for i in self.root.subtree(False) if i.url]
|
||||
full_entries = [os.path.join(self.root_dir, e.replace('/', os.path.sep))
|
||||
for e in entries]
|
||||
|
||||
for entry, prev_url in self._ReadEntries().iteritems():
|
||||
if not prev_url:
|
||||
# entry must have been overridden via .gclient custom_deps
|
||||
continue
|
||||
# Fix path separator on Windows.
|
||||
entry_fixed = entry.replace('/', os.path.sep)
|
||||
e_dir = os.path.join(self.root_dir, entry_fixed)
|
||||
# Use entry and not entry_fixed there.
|
||||
if (entry not in entries and
|
||||
(not any(path.startswith(entry + '/') for path in entries)) and
|
||||
os.path.exists(e_dir)):
|
||||
# The entry has been removed from DEPS.
|
||||
scm = gclient_scm.GitWrapper(
|
||||
prev_url, self.root_dir, entry_fixed, self.outbuf)
|
||||
|
||||
# Check to see if this directory is now part of a higher-up checkout.
|
||||
scm_root = None
|
||||
try:
|
||||
scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(scm.checkout_path)
|
||||
except subprocess2.CalledProcessError:
|
||||
pass
|
||||
if not scm_root:
|
||||
logging.warning('Could not find checkout root for %s. Unable to '
|
||||
'determine whether it is part of a higher-level '
|
||||
'checkout, so not removing.' % entry)
|
||||
continue
|
||||
|
||||
# This is to handle the case of third_party/WebKit migrating from
|
||||
# being a DEPS entry to being part of the main project.
|
||||
# If the subproject is a Git project, we need to remove its .git
|
||||
# folder. Otherwise git operations on that folder will have different
|
||||
# effects depending on the current working directory.
|
||||
if os.path.abspath(scm_root) == os.path.abspath(e_dir):
|
||||
e_par_dir = os.path.join(e_dir, os.pardir)
|
||||
if gclient_scm.scm.GIT.IsInsideWorkTree(e_par_dir):
|
||||
par_scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(e_par_dir)
|
||||
# rel_e_dir : relative path of entry w.r.t. its parent repo.
|
||||
rel_e_dir = os.path.relpath(e_dir, par_scm_root)
|
||||
if gclient_scm.scm.GIT.IsDirectoryVersioned(
|
||||
par_scm_root, rel_e_dir):
|
||||
save_dir = scm.GetGitBackupDirPath()
|
||||
# Remove any eventual stale backup dir for the same project.
|
||||
if os.path.exists(save_dir):
|
||||
gclient_utils.rmtree(save_dir)
|
||||
os.rename(os.path.join(e_dir, '.git'), save_dir)
|
||||
# When switching between the two states (entry/ is a subproject
|
||||
# -> entry/ is part of the outer project), it is very likely
|
||||
# that some files are changed in the checkout, unless we are
|
||||
# jumping *exactly* across the commit which changed just DEPS.
|
||||
# In such case we want to cleanup any eventual stale files
|
||||
# (coming from the old subproject) in order to end up with a
|
||||
# clean checkout.
|
||||
gclient_scm.scm.GIT.CleanupDir(par_scm_root, rel_e_dir)
|
||||
assert not os.path.exists(os.path.join(e_dir, '.git'))
|
||||
print(('\nWARNING: \'%s\' has been moved from DEPS to a higher '
|
||||
'level checkout. The git folder containing all the local'
|
||||
' branches has been saved to %s.\n'
|
||||
'If you don\'t care about its state you can safely '
|
||||
'remove that folder to free up space.') %
|
||||
(entry, save_dir))
|
||||
continue
|
||||
|
||||
if scm_root in full_entries:
|
||||
logging.info('%s is part of a higher level checkout, not removing',
|
||||
scm.GetCheckoutRoot())
|
||||
continue
|
||||
|
||||
file_list = []
|
||||
scm.status(self._options, [], file_list)
|
||||
modified_files = file_list != []
|
||||
if (not self._options.delete_unversioned_trees or
|
||||
(modified_files and not self._options.force)):
|
||||
# There are modified files in this entry. Keep warning until
|
||||
# removed.
|
||||
print(('\nWARNING: \'%s\' is no longer part of this client. '
|
||||
'It is recommended that you manually remove it.\n') %
|
||||
entry_fixed)
|
||||
else:
|
||||
# Delete the entry
|
||||
print('\n________ deleting \'%s\' in \'%s\'' % (
|
||||
entry_fixed, self.root_dir))
|
||||
gclient_utils.rmtree(e_dir)
|
||||
# record the current list of entries for next time
|
||||
self._SaveEntries()
|
||||
|
||||
def RunOnDeps(self, command, args, ignore_requirements=False, progress=True):
|
||||
"""Runs a command on each dependency in a client and its dependencies.
|
||||
|
||||
@@ -1624,103 +1721,7 @@ it or fix the checkout.
|
||||
if gn_args_dep and gn_args_dep.HasGNArgsFile():
|
||||
gn_args_dep.WriteGNArgsFile()
|
||||
|
||||
if not self._options.nohooks:
|
||||
if should_show_progress:
|
||||
pm = Progress('Running hooks', 1)
|
||||
self.RunHooksRecursively(self._options, pm)
|
||||
|
||||
if command == 'update':
|
||||
# Notify the user if there is an orphaned entry in their working copy.
|
||||
# Only delete the directory if there are no changes in it, and
|
||||
# delete_unversioned_trees is set to true.
|
||||
entries = [i.name for i in self.root.subtree(False) if i.url]
|
||||
full_entries = [os.path.join(self.root_dir, e.replace('/', os.path.sep))
|
||||
for e in entries]
|
||||
|
||||
for entry, prev_url in self._ReadEntries().iteritems():
|
||||
if not prev_url:
|
||||
# entry must have been overridden via .gclient custom_deps
|
||||
continue
|
||||
# Fix path separator on Windows.
|
||||
entry_fixed = entry.replace('/', os.path.sep)
|
||||
e_dir = os.path.join(self.root_dir, entry_fixed)
|
||||
# Use entry and not entry_fixed there.
|
||||
if (entry not in entries and
|
||||
(not any(path.startswith(entry + '/') for path in entries)) and
|
||||
os.path.exists(e_dir)):
|
||||
# The entry has been removed from DEPS.
|
||||
scm = gclient_scm.GitWrapper(
|
||||
prev_url, self.root_dir, entry_fixed, self.outbuf)
|
||||
|
||||
# Check to see if this directory is now part of a higher-up checkout.
|
||||
scm_root = None
|
||||
try:
|
||||
scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(scm.checkout_path)
|
||||
except subprocess2.CalledProcessError:
|
||||
pass
|
||||
if not scm_root:
|
||||
logging.warning('Could not find checkout root for %s. Unable to '
|
||||
'determine whether it is part of a higher-level '
|
||||
'checkout, so not removing.' % entry)
|
||||
continue
|
||||
|
||||
# This is to handle the case of third_party/WebKit migrating from
|
||||
# being a DEPS entry to being part of the main project.
|
||||
# If the subproject is a Git project, we need to remove its .git
|
||||
# folder. Otherwise git operations on that folder will have different
|
||||
# effects depending on the current working directory.
|
||||
if os.path.abspath(scm_root) == os.path.abspath(e_dir):
|
||||
e_par_dir = os.path.join(e_dir, os.pardir)
|
||||
if gclient_scm.scm.GIT.IsInsideWorkTree(e_par_dir):
|
||||
par_scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(e_par_dir)
|
||||
# rel_e_dir : relative path of entry w.r.t. its parent repo.
|
||||
rel_e_dir = os.path.relpath(e_dir, par_scm_root)
|
||||
if gclient_scm.scm.GIT.IsDirectoryVersioned(
|
||||
par_scm_root, rel_e_dir):
|
||||
save_dir = scm.GetGitBackupDirPath()
|
||||
# Remove any eventual stale backup dir for the same project.
|
||||
if os.path.exists(save_dir):
|
||||
gclient_utils.rmtree(save_dir)
|
||||
os.rename(os.path.join(e_dir, '.git'), save_dir)
|
||||
# When switching between the two states (entry/ is a subproject
|
||||
# -> entry/ is part of the outer project), it is very likely
|
||||
# that some files are changed in the checkout, unless we are
|
||||
# jumping *exactly* across the commit which changed just DEPS.
|
||||
# In such case we want to cleanup any eventual stale files
|
||||
# (coming from the old subproject) in order to end up with a
|
||||
# clean checkout.
|
||||
gclient_scm.scm.GIT.CleanupDir(par_scm_root, rel_e_dir)
|
||||
assert not os.path.exists(os.path.join(e_dir, '.git'))
|
||||
print(('\nWARNING: \'%s\' has been moved from DEPS to a higher '
|
||||
'level checkout. The git folder containing all the local'
|
||||
' branches has been saved to %s.\n'
|
||||
'If you don\'t care about its state you can safely '
|
||||
'remove that folder to free up space.') %
|
||||
(entry, save_dir))
|
||||
continue
|
||||
|
||||
if scm_root in full_entries:
|
||||
logging.info('%s is part of a higher level checkout, not removing',
|
||||
scm.GetCheckoutRoot())
|
||||
continue
|
||||
|
||||
file_list = []
|
||||
scm.status(self._options, [], file_list)
|
||||
modified_files = file_list != []
|
||||
if (not self._options.delete_unversioned_trees or
|
||||
(modified_files and not self._options.force)):
|
||||
# There are modified files in this entry. Keep warning until
|
||||
# removed.
|
||||
print(('\nWARNING: \'%s\' is no longer part of this client. '
|
||||
'It is recommended that you manually remove it.\n') %
|
||||
entry_fixed)
|
||||
else:
|
||||
# Delete the entry
|
||||
print('\n________ deleting \'%s\' in \'%s\'' % (
|
||||
entry_fixed, self.root_dir))
|
||||
gclient_utils.rmtree(e_dir)
|
||||
# record the current list of entries for next time
|
||||
self._SaveEntries()
|
||||
self._RemoveUnversionedGitDirs()
|
||||
|
||||
# Sync CIPD dependencies once removed deps are deleted. In case a git
|
||||
# dependency was moved to CIPD, we want to remove the old git directory
|
||||
@@ -1728,6 +1729,12 @@ it or fix the checkout.
|
||||
if self._cipd_root:
|
||||
self._cipd_root.run(command)
|
||||
|
||||
if not self._options.nohooks:
|
||||
if should_show_progress:
|
||||
pm = Progress('Running hooks', 1)
|
||||
self.RunHooksRecursively(self._options, pm)
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
def PrintRevInfo(self):
|
||||
|
||||
@@ -756,7 +756,12 @@ deps = {
|
||||
],
|
||||
'dep_type': 'cipd',
|
||||
},
|
||||
}""",
|
||||
}
|
||||
hooks = [{
|
||||
# make sure src/repo12 exists and is a CIPD dir.
|
||||
'action': ['python', '-c', 'with open("src/repo12/_cipd"): pass'],
|
||||
}]
|
||||
""",
|
||||
'origin': 'git/repo_13@3\n'
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user