Commit 032d5459 authored by Paweł Hajdan, Jr's avatar Paweł Hajdan, Jr Committed by Commit Bot

gclient: implement conditions for hooks

Bug: 570091
Change-Id: I5a489f9f9cbc5384b720685264aa918573234cf5
Reviewed-on: https://chromium-review.googlesource.com/544965Reviewed-by: 's avatarDirk Pranke <dpranke@chromium.org>
Commit-Queue: Paweł Hajdan Jr. <phajdan.jr@chromium.org>
parent b983ac1a
...@@ -139,7 +139,8 @@ def ToGNString(value, allow_dicts = True): ...@@ -139,7 +139,8 @@ def ToGNString(value, allow_dicts = True):
class Hook(object): class Hook(object):
"""Descriptor of command ran before/after sync or on demand.""" """Descriptor of command ran before/after sync or on demand."""
def __init__(self, action, pattern=None, name=None, cwd=None): def __init__(self, action, pattern=None, name=None, cwd=None, condition=None,
variables=None):
"""Constructor. """Constructor.
Arguments: Arguments:
...@@ -147,16 +148,26 @@ class Hook(object): ...@@ -147,16 +148,26 @@ class Hook(object):
pattern (basestring regex): noop with git; deprecated pattern (basestring regex): noop with git; deprecated
name (basestring): optional name; no effect on operation name (basestring): optional name; no effect on operation
cwd (basestring): working directory to use cwd (basestring): working directory to use
condition (basestring): condition when to run the hook
variables (dict): variables for evaluating the condition
""" """
self._action = gclient_utils.freeze(action) self._action = gclient_utils.freeze(action)
self._pattern = pattern self._pattern = pattern
self._name = name self._name = name
self._cwd = cwd self._cwd = cwd
self._condition = condition
self._variables = variables
@staticmethod @staticmethod
def from_dict(d): def from_dict(d, variables=None):
"""Creates a Hook instance from a dict like in the DEPS file.""" """Creates a Hook instance from a dict like in the DEPS file."""
return Hook(d['action'], d.get('pattern'), d.get('name'), d.get('cwd')) return Hook(
d['action'],
d.get('pattern'),
d.get('name'),
d.get('cwd'),
d.get('condition'),
variables=variables)
@property @property
def action(self): def action(self):
...@@ -178,7 +189,11 @@ class Hook(object): ...@@ -178,7 +189,11 @@ class Hook(object):
return bool([f for f in file_list if pattern.search(f)]) return bool([f for f in file_list if pattern.search(f)])
def run(self, root): def run(self, root):
"""Executes the hook's command.""" """Executes the hook's command (provided the condition is met)."""
if (self._condition and
not gclient_eval.EvaluateCondition(self._condition, self._variables)):
return
cmd = list(self._action) cmd = list(self._action)
if cmd[0] == 'python': if cmd[0] == 'python':
# If the hook specified "python" as the first item, the action is a # If the hook specified "python" as the first item, the action is a
...@@ -782,7 +797,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): ...@@ -782,7 +797,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
hooks_to_run.append(hook) hooks_to_run.append(hook)
if self.recursion_limit: if self.recursion_limit:
self._pre_deps_hooks = [Hook.from_dict(hook) for hook in self._pre_deps_hooks = [
Hook.from_dict(hook, variables=self._vars) for hook in
local_scope.get('pre_deps_hooks', [])] local_scope.get('pre_deps_hooks', [])]
self.add_dependencies_and_close( self.add_dependencies_and_close(
...@@ -803,7 +819,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): ...@@ -803,7 +819,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
self.add_dependency(dep) self.add_dependency(dep)
for dep in (orig_deps_to_add or deps_to_add): for dep in (orig_deps_to_add or deps_to_add):
self.add_orig_dependency(dep) self.add_orig_dependency(dep)
self._mark_as_parsed([Hook.from_dict(h) for h in hooks]) self._mark_as_parsed(
[Hook.from_dict(h, variables=self._vars) for h in hooks])
def findDepsFromNotAllowedHosts(self): def findDepsFromNotAllowedHosts(self):
"""Returns a list of depenecies from not allowed hosts. """Returns a list of depenecies from not allowed hosts.
...@@ -994,7 +1011,6 @@ class Dependency(gclient_utils.WorkItem, DependencySettings): ...@@ -994,7 +1011,6 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
for hook in self.pre_deps_hooks: for hook in self.pre_deps_hooks:
hook.run(self.root.root_dir) hook.run(self.root.root_dir)
def subtree(self, include_all): def subtree(self, include_all):
"""Breadth first recursion excluding root node.""" """Breadth first recursion excluding root node."""
dependencies = self.dependencies dependencies = self.dependencies
......
...@@ -23,6 +23,10 @@ _GCLIENT_HOOKS_SCHEMA = [{ ...@@ -23,6 +23,10 @@ _GCLIENT_HOOKS_SCHEMA = [{
# Working directory where to execute the hook. # Working directory where to execute the hook.
schema.Optional('cwd'): basestring, schema.Optional('cwd'): basestring,
# Optional condition string. The hook will only be run
# if the condition evaluates to True.
schema.Optional('condition'): basestring,
}] }]
_GCLIENT_SCHEMA = schema.Schema({ _GCLIENT_SCHEMA = schema.Schema({
......
...@@ -298,7 +298,7 @@ class FakeReposBase(object): ...@@ -298,7 +298,7 @@ class FakeReposBase(object):
class FakeRepos(FakeReposBase): class FakeRepos(FakeReposBase):
"""Implements populateGit().""" """Implements populateGit()."""
NB_GIT_REPOS = 6 NB_GIT_REPOS = 7
def populateGit(self): def populateGit(self):
# Testing: # Testing:
...@@ -507,6 +507,27 @@ recursedeps = [ ...@@ -507,6 +507,27 @@ recursedeps = [
'origin': 'git/repo_6@1\n', 'origin': 'git/repo_6@1\n',
}) })
self._commit_git('repo_7', {
'DEPS': """
vars = {
'true_var': 'True',
'false_var': 'true_var and False',
}
hooks = [
{
'action': ['python', '-c',
'open(\\'src/should_run\\', \\'w\\').write(\\'should_run\\')'],
'condition': 'true_var or True',
},
{
'action': ['python', '-c',
'open(\\'src/should_not_run\\', \\'w\\').write(\\'should_not_run\\')'],
'condition': 'false_var',
},
]""",
'origin': 'git/repo_7@1\n',
})
class FakeRepoSkiaDEPS(FakeReposBase): class FakeRepoSkiaDEPS(FakeReposBase):
"""Simulates the Skia DEPS transition in Chrome.""" """Simulates the Skia DEPS transition in Chrome."""
......
...@@ -461,6 +461,15 @@ class GClientSmokeGIT(GClientSmokeBase): ...@@ -461,6 +461,15 @@ class GClientSmokeGIT(GClientSmokeBase):
tree['src/git_hooked2'] = 'git_hooked2' tree['src/git_hooked2'] = 'git_hooked2'
self.assertTree(tree) self.assertTree(tree)
def testRunHooksCondition(self):
if not self.enabled:
return
self.gclient(['config', self.git_base + 'repo_7', '--name', 'src'])
self.gclient(['sync', '--deps', 'mac'])
tree = self.mangle_git_tree(('repo_7@1', 'src'))
tree['src/should_run'] = 'should_run'
self.assertTree(tree)
def testPreDepsHooks(self): def testPreDepsHooks(self):
if not self.enabled: if not self.enabled:
return return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment