Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Unified Diff: gclient.py

Issue 2474543002: Implement a first pass of `gclient flatten`. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gclient.py
diff --git a/gclient.py b/gclient.py
index 3e8a7962290a3b63832adc2ad3469ae7ad2d6a53..6676a46d3d2cedc14de3fbffc9aa60cfcb1a57ec 100755
--- a/gclient.py
+++ b/gclient.py
@@ -761,7 +761,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
# When running runhooks, there's no need to consult the SCM.
# All known hooks are expected to run unconditionally regardless of working
# copy state, so skip the SCM status check.
- run_scm = command not in ('runhooks', 'recurse', None)
+ run_scm = command not in ('flatten', 'runhooks', 'recurse', None)
parsed_url = self.LateOverride(self.url)
file_list = [] if not options.nohooks else None
revision_override = revision_overrides.pop(self.name, None)
@@ -1655,6 +1655,98 @@ def CMDrecurse(parser, args):
progress=not options.no_progress)
+@subcommand.usage('[command] [--verify] [args ...]')
+def CMDflatten(parser, args):
+ """Flattens the solutions into a single DEPS file."""
+ # Stop parsing at the first non-arg so that these go through to the command
+ parser.add_option('--verify', action='store_true',
+ help='Verifies that each dependencies is pinned at a '
+ 'specific revision.')
agable 2016/11/02 17:53:26 And that the .gclient_entries file matches what's
Dirk Pranke 2016/11/02 19:01:22 I'm not sure how useful that is, but I'm not actua
Michael Moss 2016/11/02 20:50:30 Assuming --verify ends up using gitiles requests,
+ options, args = parser.parse_args(args)
+ root_and_entries = gclient_utils.GetGClientRootAndEntries()
+ if not root_and_entries:
+ print(
+ 'You need to run gclient sync at least once to use \'flatten\'.\n'
+ 'This is because .gclient_entries needs to exist and be up to date.',
+ file=sys.stderr)
+ return 1
+
+ options.nohooks = True
+ client = GClient.LoadCurrentConfig(options)
+ res = client.RunOnDeps('flatten', args, ignore_requirements=True,
+ progress=False)
+ if res:
+ return res
+
+ deps = {}
+ hooks = []
+ unpinned_deps = {}
+
+ for solution in client.dependencies:
+ _FlattenSolution(solution, deps, hooks, unpinned_deps)
+
+ if options.verify and unpinned_deps:
+ for name in unpinned_deps:
+ print("'%s' is not pinned to a Git revision" % name)
+ return 1
+
+ flattened_deps = ('%s\n%s\n' %
+ (_DepsToVarString(deps), _HooksToVarString(hooks)))
+ print(flattened_deps)
+ return 0
+
+
+def _FlattenSolution(solution, deps, hooks, unpinned_deps):
+ _AddDep(solution, deps, unpinned_deps)
+ for dep in solution.dependencies:
+ _FlattenDep(dep, deps, hooks, unpinned_deps)
+ hooks.extend(solution.deps_hooks)
+
+
+def _FlattenDep(dep, deps, hooks, unpinned_deps):
+ _AddDep(dep, deps, unpinned_deps)
+ for recurse_dep_name in sorted(dep.recursedeps or []):
+ for sub_dep in dep.dependencies:
+ if recurse_dep_name == dep.name:
+ _FlattenDep(sub_dep, deps, hooks, unpinned_deps)
+ break
+ hooks.extend(dep.deps_hooks)
+
+
+def _AddDep(dep, deps, unpinned_deps):
+ assert dep.name not in deps
+ deps[dep.name] = dep.url
+ _, revision = gclient_utils.SplitUrlRevision(dep.url)
+ if not revision or not gclient_utils.IsGitSha(revision):
+ unpinned_deps[dep.name] = dep.url
+
+
+def _DepsToVarString(deps):
+ s = "deps = {\n"
+ for name in sorted(deps):
+ s += " '%s': '%s',\n" % (name, deps[name])
+ s += "}\n"
+ return s
+
+
+def _HooksToVarString(hooks):
+ s = "hooks = [\n"
+ for hook in hooks:
+ s += " {\n"
agable 2016/11/02 17:53:26 Make this a triple-quoted multi-line template stri
Dirk Pranke 2016/11/02 19:01:22 I originally didn't do this because I thought hand
+ if 'name' in hook:
+ s += " 'name': '%s',\n" % hook['name']
+ if 'pattern' in hook:
+ s += " 'pattern': '%s',\n" % hook['pattern']
+ s += " 'action': [\n"
+ s += " "
+ s += ",\n ".join("'%s'" % arg for arg in hook['action'])
+ s += ",\n"
+ s += " ],\n"
+ s += " },\n"
+ s += "}"
+ return s
+
+
@subcommand.usage('[args ...]')
def CMDfetch(parser, args):
"""Fetches upstream commits for all modules.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698