Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Meta checkout dependency manager for Git.""" | 6 """Meta checkout dependency manager for Git.""" |
| 7 # Files | 7 # Files |
| 8 # .gclient : Current client configuration, written by 'config' command. | 8 # .gclient : Current client configuration, written by 'config' command. |
| 9 # Format is a Python script defining 'solutions', a list whose | 9 # Format is a Python script defining 'solutions', a list whose |
| 10 # entries each are maps binding the strings "name" and "url" | 10 # entries each are maps binding the strings "name" and "url" |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 754 # pylint: disable=W0221 | 754 # pylint: disable=W0221 |
| 755 def run(self, revision_overrides, command, args, work_queue, options): | 755 def run(self, revision_overrides, command, args, work_queue, options): |
| 756 """Runs |command| then parse the DEPS file.""" | 756 """Runs |command| then parse the DEPS file.""" |
| 757 logging.info('Dependency(%s).run()' % self.name) | 757 logging.info('Dependency(%s).run()' % self.name) |
| 758 assert self._file_list == [] | 758 assert self._file_list == [] |
| 759 if not self.should_process: | 759 if not self.should_process: |
| 760 return | 760 return |
| 761 # When running runhooks, there's no need to consult the SCM. | 761 # When running runhooks, there's no need to consult the SCM. |
| 762 # All known hooks are expected to run unconditionally regardless of working | 762 # All known hooks are expected to run unconditionally regardless of working |
| 763 # copy state, so skip the SCM status check. | 763 # copy state, so skip the SCM status check. |
| 764 run_scm = command not in ('runhooks', 'recurse', None) | 764 run_scm = command not in ('flatten', 'runhooks', 'recurse', None) |
| 765 parsed_url = self.LateOverride(self.url) | 765 parsed_url = self.LateOverride(self.url) |
| 766 file_list = [] if not options.nohooks else None | 766 file_list = [] if not options.nohooks else None |
| 767 revision_override = revision_overrides.pop(self.name, None) | 767 revision_override = revision_overrides.pop(self.name, None) |
| 768 if run_scm and parsed_url: | 768 if run_scm and parsed_url: |
| 769 # Create a shallow copy to mutate revision. | 769 # Create a shallow copy to mutate revision. |
| 770 options = copy.copy(options) | 770 options = copy.copy(options) |
| 771 options.revision = revision_override | 771 options.revision = revision_override |
| 772 self._used_revision = options.revision | 772 self._used_revision = options.revision |
| 773 self._used_scm = gclient_scm.CreateSCM( | 773 self._used_scm = gclient_scm.CreateSCM( |
| 774 parsed_url, self.root.root_dir, self.name, self.outbuf, | 774 parsed_url, self.root.root_dir, self.name, self.outbuf, |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1648 for scm in options.scm: | 1648 for scm in options.scm: |
| 1649 scm_set.update(scm.split(',')) | 1649 scm_set.update(scm.split(',')) |
| 1650 options.scm = scm_set | 1650 options.scm = scm_set |
| 1651 | 1651 |
| 1652 options.nohooks = True | 1652 options.nohooks = True |
| 1653 client = GClient.LoadCurrentConfig(options) | 1653 client = GClient.LoadCurrentConfig(options) |
| 1654 return client.RunOnDeps('recurse', args, ignore_requirements=True, | 1654 return client.RunOnDeps('recurse', args, ignore_requirements=True, |
| 1655 progress=not options.no_progress) | 1655 progress=not options.no_progress) |
| 1656 | 1656 |
| 1657 | 1657 |
| 1658 @subcommand.usage('[command] [--verify] [args ...]') | |
| 1659 def CMDflatten(parser, args): | |
| 1660 """Flattens the solutions into a single DEPS file.""" | |
| 1661 # Stop parsing at the first non-arg so that these go through to the command | |
| 1662 parser.add_option('--verify', action='store_true', | |
| 1663 help='Verifies that each dependencies is pinned at a ' | |
| 1664 '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,
| |
| 1665 options, args = parser.parse_args(args) | |
| 1666 root_and_entries = gclient_utils.GetGClientRootAndEntries() | |
| 1667 if not root_and_entries: | |
| 1668 print( | |
| 1669 'You need to run gclient sync at least once to use \'flatten\'.\n' | |
| 1670 'This is because .gclient_entries needs to exist and be up to date.', | |
| 1671 file=sys.stderr) | |
| 1672 return 1 | |
| 1673 | |
| 1674 options.nohooks = True | |
| 1675 client = GClient.LoadCurrentConfig(options) | |
| 1676 res = client.RunOnDeps('flatten', args, ignore_requirements=True, | |
| 1677 progress=False) | |
| 1678 if res: | |
| 1679 return res | |
| 1680 | |
| 1681 deps = {} | |
| 1682 hooks = [] | |
| 1683 unpinned_deps = {} | |
| 1684 | |
| 1685 for solution in client.dependencies: | |
| 1686 _FlattenSolution(solution, deps, hooks, unpinned_deps) | |
| 1687 | |
| 1688 if options.verify and unpinned_deps: | |
| 1689 for name in unpinned_deps: | |
| 1690 print("'%s' is not pinned to a Git revision" % name) | |
| 1691 return 1 | |
| 1692 | |
| 1693 flattened_deps = ('%s\n%s\n' % | |
| 1694 (_DepsToVarString(deps), _HooksToVarString(hooks))) | |
| 1695 print(flattened_deps) | |
| 1696 return 0 | |
| 1697 | |
| 1698 | |
| 1699 def _FlattenSolution(solution, deps, hooks, unpinned_deps): | |
| 1700 _AddDep(solution, deps, unpinned_deps) | |
| 1701 for dep in solution.dependencies: | |
| 1702 _FlattenDep(dep, deps, hooks, unpinned_deps) | |
| 1703 hooks.extend(solution.deps_hooks) | |
| 1704 | |
| 1705 | |
| 1706 def _FlattenDep(dep, deps, hooks, unpinned_deps): | |
| 1707 _AddDep(dep, deps, unpinned_deps) | |
| 1708 for recurse_dep_name in sorted(dep.recursedeps or []): | |
| 1709 for sub_dep in dep.dependencies: | |
| 1710 if recurse_dep_name == dep.name: | |
| 1711 _FlattenDep(sub_dep, deps, hooks, unpinned_deps) | |
| 1712 break | |
| 1713 hooks.extend(dep.deps_hooks) | |
| 1714 | |
| 1715 | |
| 1716 def _AddDep(dep, deps, unpinned_deps): | |
| 1717 assert dep.name not in deps | |
| 1718 deps[dep.name] = dep.url | |
| 1719 _, revision = gclient_utils.SplitUrlRevision(dep.url) | |
| 1720 if not revision or not gclient_utils.IsGitSha(revision): | |
| 1721 unpinned_deps[dep.name] = dep.url | |
| 1722 | |
| 1723 | |
| 1724 def _DepsToVarString(deps): | |
| 1725 s = "deps = {\n" | |
| 1726 for name in sorted(deps): | |
| 1727 s += " '%s': '%s',\n" % (name, deps[name]) | |
| 1728 s += "}\n" | |
| 1729 return s | |
| 1730 | |
| 1731 | |
| 1732 def _HooksToVarString(hooks): | |
| 1733 s = "hooks = [\n" | |
| 1734 for hook in hooks: | |
| 1735 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
| |
| 1736 if 'name' in hook: | |
| 1737 s += " 'name': '%s',\n" % hook['name'] | |
| 1738 if 'pattern' in hook: | |
| 1739 s += " 'pattern': '%s',\n" % hook['pattern'] | |
| 1740 s += " 'action': [\n" | |
| 1741 s += " " | |
| 1742 s += ",\n ".join("'%s'" % arg for arg in hook['action']) | |
| 1743 s += ",\n" | |
| 1744 s += " ],\n" | |
| 1745 s += " },\n" | |
| 1746 s += "}" | |
| 1747 return s | |
| 1748 | |
| 1749 | |
| 1658 @subcommand.usage('[args ...]') | 1750 @subcommand.usage('[args ...]') |
| 1659 def CMDfetch(parser, args): | 1751 def CMDfetch(parser, args): |
| 1660 """Fetches upstream commits for all modules. | 1752 """Fetches upstream commits for all modules. |
| 1661 | 1753 |
| 1662 Completely git-specific. Simply runs 'git fetch [args ...]' for each module. | 1754 Completely git-specific. Simply runs 'git fetch [args ...]' for each module. |
| 1663 """ | 1755 """ |
| 1664 (options, args) = parser.parse_args(args) | 1756 (options, args) = parser.parse_args(args) |
| 1665 return CMDrecurse(OptionParser(), [ | 1757 return CMDrecurse(OptionParser(), [ |
| 1666 '--jobs=%d' % options.jobs, '--scm=git', 'git', 'fetch'] + args) | 1758 '--jobs=%d' % options.jobs, '--scm=git', 'git', 'fetch'] + args) |
| 1667 | 1759 |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2180 | 2272 |
| 2181 | 2273 |
| 2182 if '__main__' == __name__: | 2274 if '__main__' == __name__: |
| 2183 try: | 2275 try: |
| 2184 sys.exit(main(sys.argv[1:])) | 2276 sys.exit(main(sys.argv[1:])) |
| 2185 except KeyboardInterrupt: | 2277 except KeyboardInterrupt: |
| 2186 sys.stderr.write('interrupted\n') | 2278 sys.stderr.write('interrupted\n') |
| 2187 sys.exit(1) | 2279 sys.exit(1) |
| 2188 | 2280 |
| 2189 # vim: ts=2:sw=2:tw=80:et: | 2281 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |