diff --git a/gclient.py b/gclient.py index 657c5aff3..2ded56ba3 100755 --- a/gclient.py +++ b/gclient.py @@ -1720,11 +1720,13 @@ def CMDfetch(parser, args): class Flattener(object): """Flattens a gclient solution.""" - def __init__(self, client): + def __init__(self, client, pin_all_deps=False): """Constructor. Arguments: client (GClient): client to flatten + pin_all_deps (bool): whether to pin all deps, even if they're not pinned + in DEPS """ self._client = client @@ -1738,18 +1740,35 @@ class Flattener(object): self._pre_deps_hooks = [] self._vars = {} - self._flatten() + self._flatten(pin_all_deps=pin_all_deps) @property def deps_string(self): assert self._deps_string is not None return self._deps_string - def _flatten(self): - """Runs the flattener. Saves resulting DEPS string.""" + def _flatten(self, pin_all_deps=False): + """Runs the flattener. Saves resulting DEPS string. + + Arguments: + pin_all_deps (bool): whether to pin all deps, even if they're not pinned + in DEPS + """ for solution in self._client.dependencies: self._flatten_solution(solution) + if pin_all_deps: + for dep in self._deps.itervalues(): + if dep.parsed_url is None: + continue + url, revision = gclient_utils.SplitUrlRevision(dep.parsed_url) + if revision and gclient_utils.IsGitSha(revision): + continue + scm = gclient_scm.CreateSCM( + dep.parsed_url, self._client.root_dir, dep.name, dep.outbuf) + dep._parsed_url = dep._url = '%s@%s' % ( + url, scm.revinfo(self._client._options, [], None)) + self._deps_string = '\n'.join( _GNSettingsToLines( self._client.dependencies[0]._gn_args_file, @@ -1825,6 +1844,10 @@ class Flattener(object): def CMDflatten(parser, args): """Flattens the solutions into a single DEPS file.""" parser.add_option('--output-deps', help='Path to the output DEPS file') + parser.add_option( + '--pin-all-deps', action='store_true', + help=('Pin all deps, even if not pinned in DEPS. CAVEAT: only does so ' + 'for checked out deps, NOT deps_os.')) options, args = parser.parse_args(args) options.nohooks = True @@ -1836,7 +1859,7 @@ def CMDflatten(parser, args): if code != 0: return code - flattener = Flattener(client) + flattener = Flattener(client, pin_all_deps=options.pin_all_deps) if options.output_deps: with open(options.output_deps, 'w') as f: diff --git a/tests/gclient_smoketest.py b/tests/gclient_smoketest.py index 89fd9bb8c..ab993a4e3 100755 --- a/tests/gclient_smoketest.py +++ b/tests/gclient_smoketest.py @@ -704,6 +704,142 @@ class GClientSmokeGIT(GClientSmokeBase): '', ], deps_contents.splitlines()) + def testFlattenPinAllDeps(self): + if not self.enabled: + return + + output_deps = os.path.join(self.root_dir, 'DEPS.flattened') + self.assertFalse(os.path.exists(output_deps)) + + self.gclient(['config', self.git_base + 'repo_6', '--name', 'src']) + self.gclient(['sync']) + self.gclient(['flatten', '-v', '-v', '-v', '--output-deps', output_deps, + '--pin-all-deps']) + + with open(output_deps) as f: + deps_contents = f.read() + + self.assertEqual([ + 'gclient_gn_args_file = "src/gclient.args"', + 'gclient_gn_args = [\'DummyVariable\']', + 'allowed_hosts = [', + ' "git://127.0.0.1:20000/git/",', + ']', + '', + 'deps = {', + ' # src -> src/repo2 -> foo/bar', + ' "foo/bar": {', + ' "url": "/repo_3",', + ' },', + '', + ' # src', + ' "src": {', + ' "url": "git://127.0.0.1:20000/git/repo_6@%s",' % ( + self.githash('repo_6', 1)), + ' },', + '', + ' # src -> src/repo2', + ' "src/repo2": {', + ' "url": "git://127.0.0.1:20000/git/repo_2@%s",' % ( + self.githash('repo_2', 1)[:7]), + ' "condition": "True",', + ' },', + '', + ' # src -> src/repo4', + ' "src/repo4": {', + ' "url": "/repo_4",', + ' "condition": "False",', + ' },', + '', + ' # src -> src/repo8', + ' "src/repo8": {', + ' "url": "/repo_8",', + ' },', + '', + '}', + '', + 'deps_os = {', + ' "mac": {', + ' # src -> src/mac_repo', + ' "src/mac_repo": {', + ' "url": "/repo_5",', + ' },', + '', + ' # src -> src/repo8 -> src/recursed_os_repo', + ' "src/recursed_os_repo": {', + ' "url": "/repo_5",', + ' },', + '', + ' },', + '', + ' "unix": {', + ' # src -> src/repo8 -> src/recursed_os_repo', + ' "src/recursed_os_repo": {', + ' "url": "/repo_5",', + ' },', + '', + ' # src -> src/unix_repo', + ' "src/unix_repo": {', + ' "url": "/repo_5",', + ' },', + '', + ' },', + '', + ' "win": {', + ' # src -> src/win_repo', + ' "src/win_repo": {', + ' "url": "/repo_5",', + ' },', + '', + ' },', + '', + '}', + '', + 'hooks = [', + ' # src', + ' {', + ' "pattern": ".",', + ' "cwd": ".",', + ' "action": [', + ' "python",', + ' "-c",', + ' "open(\'src/git_hooked1\', \'w\').write(\'git_hooked1\')",', + ' ]', + ' },', + '', + ' # src', + ' {', + ' "pattern": "nonexistent",', + ' "cwd": ".",', + ' "action": [', + ' "python",', + ' "-c",', + ' "open(\'src/git_hooked2\', \'w\').write(\'git_hooked2\')",', + ' ]', + ' },', + '', + ']', + '', + 'hooks_os = {', + ' "mac": [', + ' # src', + ' {', + ' "pattern": ".",', + ' "cwd": ".",', + ' "action": [', + ' "python",', + ' "-c",', + ' "open(\'src/git_hooked_mac\', \'w\').write(' + '\'git_hooked_mac\')",', + ' ]', + ' },', + '', + ' ],', + '', + '}', + '', + ], deps_contents.splitlines()) + class GClientSmokeGITMutates(GClientSmokeBase): """testRevertAndStatus mutates the git repo so move it to its own suite."""