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):
class Hook(object):
"""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.
Arguments:
......@@ -147,16 +148,26 @@ class Hook(object):
pattern (basestring regex): noop with git; deprecated
name (basestring): optional name; no effect on operation
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._pattern = pattern
self._name = name
self._cwd = cwd
self._condition = condition
self._variables = variables
@staticmethod
def from_dict(d):
def from_dict(d, variables=None):
"""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
def action(self):
......@@ -178,7 +189,11 @@ class Hook(object):
return bool([f for f in file_list if pattern.search(f)])
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)
if cmd[0] == 'python':
# If the hook specified "python" as the first item, the action is a
......@@ -782,8 +797,9 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
hooks_to_run.append(hook)
if self.recursion_limit:
self._pre_deps_hooks = [Hook.from_dict(hook) for hook in
local_scope.get('pre_deps_hooks', [])]
self._pre_deps_hooks = [
Hook.from_dict(hook, variables=self._vars) for hook in
local_scope.get('pre_deps_hooks', [])]
self.add_dependencies_and_close(
deps_to_add, hooks_to_run, orig_deps_to_add=orig_deps_to_add)
......@@ -803,7 +819,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
self.add_dependency(dep)
for dep in (orig_deps_to_add or deps_to_add):
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):
"""Returns a list of depenecies from not allowed hosts.
......@@ -994,7 +1011,6 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
for hook in self.pre_deps_hooks:
hook.run(self.root.root_dir)
def subtree(self, include_all):
"""Breadth first recursion excluding root node."""
dependencies = self.dependencies
......
......@@ -23,6 +23,10 @@ _GCLIENT_HOOKS_SCHEMA = [{
# Working directory where to execute the hook.
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({
......
......@@ -298,7 +298,7 @@ class FakeReposBase(object):
class FakeRepos(FakeReposBase):
"""Implements populateGit()."""
NB_GIT_REPOS = 6
NB_GIT_REPOS = 7
def populateGit(self):
# Testing:
......@@ -507,6 +507,27 @@ recursedeps = [
'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):
"""Simulates the Skia DEPS transition in Chrome."""
......
......@@ -461,6 +461,15 @@ class GClientSmokeGIT(GClientSmokeBase):
tree['src/git_hooked2'] = 'git_hooked2'
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):
if not self.enabled:
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