diff --git a/gclient.py b/gclient.py index ed61ff8bf..9fe9ffa72 100755 --- a/gclient.py +++ b/gclient.py @@ -159,14 +159,19 @@ class Hook(object): self._verbose = verbose @staticmethod - def from_dict(d, variables=None, verbose=False): + def from_dict(d, variables=None, verbose=False, conditions=None): """Creates a Hook instance from a dict like in the DEPS file.""" + # Merge any local and inherited conditions. + if conditions and d.get('condition'): + condition = '(%s) and (%s)' % (conditions, d['condition']) + else: + condition = conditions or d.get('condition') return Hook( d['action'], d.get('pattern'), d.get('name'), d.get('cwd'), - d.get('condition'), + condition, variables=variables, # Always print the header if not printing to a TTY. verbose=verbose or not setup_color.IS_TTY) @@ -628,6 +633,24 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): for d in self.custom_deps: if d not in deps: deps[d] = self.custom_deps[d] + # Make child deps conditional on any parent conditions. This ensures that, + # when flattened, recursed entries have the correct restrictions, even if + # not explicitly set in the recursed DEPS file. For instance, if + # "src/ios_foo" is conditional on "checkout_ios=True", then anything + # recursively included by "src/ios_foo/DEPS" should also require + # "checkout_ios=True". + if self.condition: + for dname, dval in deps.iteritems(): + if isinstance(dval, basestring): + dval = {'url': dval} + deps[dname] = dval + else: + assert isinstance(dval, collections.Mapping) + if dval.get('condition'): + dval['condition'] = '(%s) and (%s)' % ( + dval['condition'], self.condition) + else: + dval['condition'] = self.condition if rel_prefix: logging.warning('use_relative_paths enabled.') @@ -848,7 +871,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): # Keep original contents of hooks_os for flatten. for hook_os, os_hooks in hooks_os.iteritems(): self._os_deps_hooks[hook_os] = [ - Hook.from_dict(hook, variables=self.get_vars(), verbose=True) + Hook.from_dict(hook, variables=self.get_vars(), verbose=True, + conditions=self.condition) for hook in os_hooks] # Specifically append these to ensure that hooks_os run after hooks. @@ -864,7 +888,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): if self.recursion_limit: self._pre_deps_hooks = [ - Hook.from_dict(hook, variables=self.get_vars(), verbose=True) + Hook.from_dict(hook, variables=self.get_vars(), verbose=True, + conditions=self.condition) for hook in local_scope.get('pre_deps_hooks', []) ] @@ -884,7 +909,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): self.add_dependency(dep) self._mark_as_parsed([ Hook.from_dict( - h, variables=self.get_vars(), verbose=self.root._options.verbose) + h, variables=self.get_vars(), verbose=self.root._options.verbose, + conditions=self.condition) for h in hooks ]) diff --git a/testing_support/fake_repos.py b/testing_support/fake_repos.py index 0826f0ab2..3bc48d58f 100755 --- a/testing_support/fake_repos.py +++ b/testing_support/fake_repos.py @@ -507,7 +507,7 @@ allowed_hosts = [ deps = { 'src/repo2': { 'url': Var('git_base') + 'repo_2@%(hash)s', - 'condition': 'True', + 'condition': 'true_str_var', }, 'src/repo4': { 'url': '/repo_4', diff --git a/tests/gclient_smoketest.py b/tests/gclient_smoketest.py index 65dbfa86a..1e5ab8b03 100755 --- a/tests/gclient_smoketest.py +++ b/tests/gclient_smoketest.py @@ -678,6 +678,7 @@ class GClientSmokeGIT(GClientSmokeBase): ' # src -> src/repo2 -> foo/bar', ' "foo/bar": {', ' "url": "/repo_3",', + ' "condition": \'true_str_var\',', ' },', '', ' # src', @@ -689,7 +690,7 @@ class GClientSmokeGIT(GClientSmokeBase): ' "src/repo2": {', ' "url": "{git_base}repo_2@%s",' % ( self.githash('repo_2', 1)[:7]), - ' "condition": \'True\',', + ' "condition": \'true_str_var\',', ' },', '', ' # src -> src/repo4', @@ -840,6 +841,7 @@ class GClientSmokeGIT(GClientSmokeBase): with open(output_deps) as f: deps_contents = f.read() + self.maxDiff = None self.assertEqual([ 'gclient_gn_args_file = "src/repo2/gclient.args"', 'gclient_gn_args = [\'false_var\', \'false_str_var\', \'true_var\', ' @@ -852,6 +854,7 @@ class GClientSmokeGIT(GClientSmokeBase): ' # src -> src/repo2 -> foo/bar', ' "foo/bar": {', ' "url": "/repo_3@%s",' % (self.githash('repo_3', 2)), + ' "condition": \'true_str_var\',', ' },', '', ' # src', @@ -864,7 +867,7 @@ class GClientSmokeGIT(GClientSmokeBase): ' "src/repo2": {', ' "url": "{git_base}repo_2@%s",' % ( self.githash('repo_2', 1)), - ' "condition": \'True\',', + ' "condition": \'true_str_var\',', ' },', '', ' # src -> src/repo4',