Commit 16f4bad9 authored by Edward Lemur's avatar Edward Lemur Committed by Commit Bot

gclient: Merge hook_os with hooks and deps_os with os.

This is done in gclient_eval, so we can remove all code
that deals with deps_os and hooks_os from gclient.

Bug: 839925
Change-Id: I491819207a712d62008ff010e313add87d22c937
Reviewed-on: https://chromium-review.googlesource.com/1058375
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
Reviewed-by: 's avatarAaron Gable <agable@chromium.org>
parent 3f0591d4
This diff is collapsed.
......@@ -5,8 +5,11 @@
import ast
import cStringIO
import collections
import logging
import tokenize
import gclient_utils
from third_party import schema
......@@ -345,31 +348,9 @@ def Exec(content, expand_vars=True, filename='<unknown>', vars_override=None):
return _GCLIENT_SCHEMA.validate(local_scope)
def Parse(content, expand_vars, validate_syntax, filename, vars_override=None):
"""Parses DEPS strings.
Executes the Python-like string stored in content, resulting in a Python
dictionary specifyied by the schema above. Supports syntax validation and
variable expansion.
Args:
content: str. DEPS file stored as a string.
expand_vars: bool. Whether variables should be expanded to their values.
validate_syntax: bool. Whether syntax should be validated using the schema
defined above.
filename: str. The name of the DEPS file, or a string describing the source
of the content, e.g. '<string>', '<unknown>'.
vars_override: dict, optional. A dictionary with overrides for the variables
defined by the DEPS file.
Returns:
A Python dict with the parsed contents of the DEPS file, as specified by the
schema above.
"""
# TODO(ehmaldonado): Make validate_syntax = True the only case
if validate_syntax:
return Exec(content, expand_vars, filename, vars_override)
def ExecLegacy(content, expand_vars=True, filename='<unknown>',
vars_override=None):
"""Executes a DEPS file |content| using exec."""
local_scope = {}
global_scope = {'Var': lambda var_name: '{%s}' % var_name}
......@@ -409,6 +390,119 @@ def Parse(content, expand_vars, validate_syntax, filename, vars_override=None):
return _DeepFormat(local_scope)
def _StandardizeDeps(deps_dict, vars_dict):
""""Standardizes the deps_dict.
For each dependency:
- Expands the variable in the dependency name.
- Ensures the dependency is a dictionary.
- Set's the 'dep_type' to be 'git' by default.
"""
new_deps_dict = {}
for dep_name, dep_info in deps_dict.items():
dep_name = dep_name.format(**vars_dict)
if not isinstance(dep_info, collections.Mapping):
dep_info = {'url': dep_info}
dep_info.setdefault('dep_type', 'git')
new_deps_dict[dep_name] = dep_info
return new_deps_dict
def _MergeDepsOs(deps_dict, os_deps_dict, os_name):
"""Merges the deps in os_deps_dict into conditional dependencies in deps_dict.
The dependencies in os_deps_dict are transformed into conditional dependencies
using |'checkout_' + os_name|.
If the dependency is already present, the URL and revision must coincide.
"""
for dep_name, dep_info in os_deps_dict.items():
# Make this condition very visible, so it's not a silent failure.
# It's unclear how to support None override in deps_os.
if dep_info['url'] is None:
logging.error('Ignoring %r:%r in %r deps_os', dep_name, dep_info, os_name)
continue
os_condition = 'checkout_' + (os_name if os_name != 'unix' else 'linux')
UpdateCondition(dep_info, 'and', os_condition)
if dep_name in deps_dict:
if deps_dict[dep_name]['url'] != dep_info['url']:
raise gclient_utils.Error(
'Value from deps_os (%r; %r: %r) conflicts with existing deps '
'entry (%r).' % (
os_name, dep_name, dep_info, deps_dict[dep_name]))
UpdateCondition(dep_info, 'or', deps_dict[dep_name].get('condition'))
deps_dict[dep_name] = dep_info
def UpdateCondition(info_dict, op, new_condition):
"""Updates info_dict's condition with |new_condition|.
An absent value is treated as implicitly True.
"""
curr_condition = info_dict.get('condition')
# Easy case: Both are present.
if curr_condition and new_condition:
info_dict['condition'] = '(%s) %s (%s)' % (
curr_condition, op, new_condition)
# If |op| == 'and', and at least one condition is present, then use it.
elif op == 'and' and (curr_condition or new_condition):
info_dict['condition'] = curr_condition or new_condition
# Otherwise, no condition should be set
elif curr_condition:
del info_dict['condition']
def Parse(content, expand_vars, validate_syntax, filename, vars_override=None):
"""Parses DEPS strings.
Executes the Python-like string stored in content, resulting in a Python
dictionary specifyied by the schema above. Supports syntax validation and
variable expansion.
Args:
content: str. DEPS file stored as a string.
expand_vars: bool. Whether variables should be expanded to their values.
validate_syntax: bool. Whether syntax should be validated using the schema
defined above.
filename: str. The name of the DEPS file, or a string describing the source
of the content, e.g. '<string>', '<unknown>'.
vars_override: dict, optional. A dictionary with overrides for the variables
defined by the DEPS file.
Returns:
A Python dict with the parsed contents of the DEPS file, as specified by the
schema above.
"""
if validate_syntax:
result = Exec(content, expand_vars, filename, vars_override)
else:
result = ExecLegacy(content, expand_vars, filename, vars_override)
vars_dict = result.get('vars', {})
if 'deps' in result:
result['deps'] = _StandardizeDeps(result['deps'], vars_dict)
if 'deps_os' in result:
deps = result.setdefault('deps', {})
for os_name, os_deps in result['deps_os'].iteritems():
os_deps = _StandardizeDeps(os_deps, vars_dict)
_MergeDepsOs(deps, os_deps, os_name)
del result['deps_os']
if 'hooks_os' in result:
hooks = result.setdefault('hooks', [])
for os_name, os_hooks in result['hooks_os'].iteritems():
for hook in os_hooks:
UpdateCondition(hook, 'and', 'checkout_' + os_name)
hooks.extend(os_hooks)
del result['hooks_os']
return result
def EvaluateCondition(condition, variables, referenced_variables=None):
"""Safely evaluates a boolean condition. Returns the result."""
if not referenced_variables:
......
......@@ -186,6 +186,49 @@ class ExecTest(unittest.TestCase):
str(cm.exception))
class UpdateConditionTest(unittest.TestCase):
def test_both_present(self):
info = {'condition': 'foo'}
gclient_eval.UpdateCondition(info, 'and', 'bar')
self.assertEqual(info, {'condition': '(foo) and (bar)'})
info = {'condition': 'foo'}
gclient_eval.UpdateCondition(info, 'or', 'bar')
self.assertEqual(info, {'condition': '(foo) or (bar)'})
def test_one_present_and(self):
# If one of info's condition or new_condition is present, and |op| == 'and'
# then the the result must be the present condition.
info = {'condition': 'foo'}
gclient_eval.UpdateCondition(info, 'and', None)
self.assertEqual(info, {'condition': 'foo'})
info = {}
gclient_eval.UpdateCondition(info, 'and', 'bar')
self.assertEqual(info, {'condition': 'bar'})
def test_both_absent_and(self):
# Nothing happens
info = {}
gclient_eval.UpdateCondition(info, 'and', None)
self.assertEqual(info, {})
def test_or(self):
# If one of info's condition and new_condition is not present, then there
# shouldn't be a condition. An absent value is treated as implicitly True.
info = {'condition': 'foo'}
gclient_eval.UpdateCondition(info, 'or', None)
self.assertEqual(info, {})
info = {}
gclient_eval.UpdateCondition(info, 'or', 'bar')
self.assertEqual(info, {})
info = {}
gclient_eval.UpdateCondition(info, 'or', None)
self.assertEqual(info, {})
class EvaluateConditionTest(unittest.TestCase):
def test_true(self):
self.assertTrue(gclient_eval.EvaluateCondition('True', {}))
......@@ -573,8 +616,9 @@ class ParseTest(unittest.TestCase):
for validate_syntax in True, False:
local_scope = self.callParse(validate_syntax=validate_syntax)
self.assertEqual({
'vars': collections.OrderedDict([('foo', 'bar')]),
'deps': collections.OrderedDict([('a_dep', 'abarb')]),
'vars': {'foo': 'bar'},
'deps': {'a_dep': {'url': 'abarb',
'dep_type': 'git'}},
}, local_scope)
def test_no_expands_vars(self):
......@@ -582,8 +626,9 @@ class ParseTest(unittest.TestCase):
local_scope = self.callParse(False,
validate_syntax=validate_syntax)
self.assertEqual({
'vars': collections.OrderedDict([('foo', 'bar')]),
'deps': collections.OrderedDict([('a_dep', 'a{foo}b')]),
'vars': {'foo': 'bar'},
'deps': {'a_dep': {'url': 'a{foo}b',
'dep_type': 'git'}},
}, local_scope)
def test_overrides_vars(self):
......@@ -591,8 +636,9 @@ class ParseTest(unittest.TestCase):
local_scope = self.callParse(validate_syntax=validate_syntax,
vars_override={'foo': 'baz'})
self.assertEqual({
'vars': collections.OrderedDict([('foo', 'bar')]),
'deps': collections.OrderedDict([('a_dep', 'abazb')]),
'vars': {'foo': 'bar'},
'deps': {'a_dep': {'url': 'abazb',
'dep_type': 'git'}},
}, local_scope)
def test_no_extra_vars(self):
......@@ -618,6 +664,171 @@ class ParseTest(unittest.TestCase):
'<unknown>', {'baz': 'lalala'})
self.assertIn('baz', str(cm.exception))
def test_standardizes_deps_string_dep(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": "a_url@a_rev",',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
'deps': {'a_dep': {'url': 'a_url@a_rev',
'dep_type': 'git'}},
}, local_scope)
def test_standardizes_deps_dict_dep(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": {',
' "url": "a_url@a_rev",',
' "condition": "checkout_android",',
' },',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
'deps': {'a_dep': {'url': 'a_url@a_rev',
'dep_type': 'git',
'condition': 'checkout_android'}},
}, local_scope)
def test_ignores_none_in_deps_os(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": "a_url@a_rev",',
'}',
'deps_os = {',
' "mac": {',
' "a_dep": None,',
' },',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
'deps': {'a_dep': {'url': 'a_url@a_rev',
'dep_type': 'git'}},
}, local_scope)
def test_merges_deps_os_extra_dep(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": "a_url@a_rev",',
'}',
'deps_os = {',
' "mac": {',
' "b_dep": "b_url@b_rev"',
' },',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
'deps': {'a_dep': {'url': 'a_url@a_rev',
'dep_type': 'git'},
'b_dep': {'url': 'b_url@b_rev',
'dep_type': 'git',
'condition': 'checkout_mac'}},
}, local_scope)
def test_merges_deps_os_existing_dep_with_no_condition(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": "a_url@a_rev",',
'}',
'deps_os = {',
' "mac": {',
' "a_dep": "a_url@a_rev"',
' },',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
'deps': {'a_dep': {'url': 'a_url@a_rev',
'dep_type': 'git'}},
}, local_scope)
def test_merges_deps_os_existing_dep_with_condition(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": {',
' "url": "a_url@a_rev",',
' "condition": "some_condition",',
' },',
'}',
'deps_os = {',
' "mac": {',
' "a_dep": "a_url@a_rev"',
' },',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
'deps': {
'a_dep': {'url': 'a_url@a_rev',
'dep_type': 'git',
'condition': '(checkout_mac) or (some_condition)'},
},
}, local_scope)
def test_merges_deps_os_multiple_os(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'deps_os = {',
' "win": {'
' "a_dep": "a_url@a_rev"',
' },',
' "mac": {',
' "a_dep": "a_url@a_rev"',
' },',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
'deps': {
'a_dep': {'url': 'a_url@a_rev',
'dep_type': 'git',
'condition': '(checkout_mac) or (checkout_win)'},
},
}, local_scope)
def test_fails_to_merge_same_dep_with_different_revisions(self):
for validate_syntax in True, False:
with self.assertRaises(gclient_eval.gclient_utils.Error) as cm:
gclient_eval.Parse('\n'.join([
'deps = {',
' "a_dep": {',
' "url": "a_url@a_rev",',
' "condition": "some_condition",',
' },',
'}',
'deps_os = {',
' "mac": {',
' "a_dep": "a_url@b_rev"',
' },',
'}',
]), False, validate_syntax, '<unknown>')
self.assertIn('conflicts with existing deps', str(cm.exception))
def test_merges_hooks_os(self):
for validate_syntax in True, False:
local_scope = gclient_eval.Parse('\n'.join([
'hooks = [',
' {',
' "action": ["a", "action"],',
' },',
']',
'hooks_os = {',
' "mac": [',
' {',
' "action": ["b", "action"]',
' },',
' ]',
'}',
]), False, validate_syntax, '<unknown>')
self.assertEqual({
"hooks": [{"action": ["a", "action"]},
{"action": ["b", "action"], "condition": "checkout_mac"}],
}, local_scope)
if __name__ == '__main__':
level = logging.DEBUG if '-v' in sys.argv else logging.FATAL
......
......@@ -875,6 +875,18 @@ class GClientSmokeGIT(GClientSmokeBase):
' "url": "git://127.0.0.1:20000/git/repo_6",',
' },',
'',
' # src -> src/mac_repo',
' "src/mac_repo": {',
' "url": "{repo5_var}",',
' "condition": \'checkout_mac\',',
' },',
'',
' # src -> src/repo8 -> src/recursed_os_repo',
' "src/recursed_os_repo": {',
' "url": "/repo_5",',
' "condition": \'(checkout_linux) or (checkout_mac)\',',
' },',
'',
' # src -> src/repo2',
' "src/repo2": {',
' "url": "{git_base}repo_2@%s",' % (
......@@ -893,41 +905,16 @@ class GClientSmokeGIT(GClientSmokeBase):
' "url": "/repo_8",',
' },',
'',
'}',
'',
'deps_os = {',
' "mac": {',
' # src -> src/mac_repo',
' "src/mac_repo": {',
' "url": "{repo5_var}",',
' },',
'',
' # 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": "{repo5_var}",',
' },',
'',
' # src -> src/unix_repo',
' "src/unix_repo": {',
' "url": "{repo5_var}",',
' "condition": \'checkout_linux\',',
' },',
'',
' "win": {',
' # src -> src/win_repo',
' "src/win_repo": {',
' "url": "{repo5_var}",',
' },',
'',
' # src -> src/win_repo',
' "src/win_repo": {',
' "url": "{repo5_var}",',
' "condition": \'checkout_win\',',
' },',
'',
'}',
......@@ -957,25 +944,20 @@ class GClientSmokeGIT(GClientSmokeBase):
' ]',
' },',
'',
']',
'',
'hooks_os = {',
' "mac": [',
' # src',
' {',
' "pattern": ".",',
' "cwd": ".",',
' "action": [',
' "python",',
' "-c",',
' "open(\'src/git_hooked_mac\', \'w\').write('
'\'git_hooked_mac\')",',
' ]',
' },',
'',
' ],',
' # src',
' {',
' "pattern": ".",',
' "condition": \'checkout_mac\',',
' "cwd": ".",',
' "action": [',
' "python",',
' "-c",',
' "open(\'src/git_hooked_mac\', \'w\').write('
'\'git_hooked_mac\')",',
' ]',
' },',
'',
'}',
']',
'',
'vars = {',
' # src',
......@@ -1055,6 +1037,18 @@ class GClientSmokeGIT(GClientSmokeBase):
self.githash('repo_6', 1)),
' },',
'',
' # src -> src/mac_repo',
' "src/mac_repo": {',
' "url": "{repo5_var}@%s",' % (self.githash('repo_5', 3)),
' "condition": \'checkout_mac\',',
' },',
'',
' # src -> src/repo8 -> src/recursed_os_repo',
' "src/recursed_os_repo": {',
' "url": "/repo_5@%s",' % (self.githash('repo_5', 3)),
' "condition": \'(checkout_linux) or (checkout_mac)\',',
' },',
'',
' # src -> src/repo2',
' "src/repo2": {',
' "url": "{git_base}repo_2@%s",' % (
......@@ -1073,41 +1067,16 @@ class GClientSmokeGIT(GClientSmokeBase):
' "url": "/repo_8@%s",' % (self.githash('repo_8', 1)),
' },',
'',
'}',
'',
'deps_os = {',
' "mac": {',
' # src -> src/mac_repo',
' "src/mac_repo": {',
' "url": "{repo5_var}@%s",' % (self.githash('repo_5', 3)),
' },',
'',
' # src -> src/repo8 -> src/recursed_os_repo',
' "src/recursed_os_repo": {',
' "url": "/repo_5@%s",' % (self.githash('repo_5', 3)),
' },',
'',
' },',
'',
' "unix": {',
' # src -> src/repo8 -> src/recursed_os_repo',
' "src/recursed_os_repo": {',
' "url": "/repo_5@%s",' % (self.githash('repo_5', 3)),
' },',
'',
' # src -> src/unix_repo',
' "src/unix_repo": {',
' "url": "{repo5_var}@%s",' % (self.githash('repo_5', 3)),
' },',
'',
' # src -> src/unix_repo',
' "src/unix_repo": {',
' "url": "{repo5_var}@%s",' % (self.githash('repo_5', 3)),
' "condition": \'checkout_linux\',',
' },',
'',
' "win": {',
' # src -> src/win_repo',
' "src/win_repo": {',
' "url": "{repo5_var}@%s",' % (self.githash('repo_5', 3)),
' },',
'',
' # src -> src/win_repo',
' "src/win_repo": {',
' "url": "{repo5_var}@%s",' % (self.githash('repo_5', 3)),
' "condition": \'checkout_win\',',
' },',
'',
'}',
......@@ -1137,25 +1106,20 @@ class GClientSmokeGIT(GClientSmokeBase):
' ]',
' },',
'',
']',
'',
'hooks_os = {',
' "mac": [',
' # src',
' {',
' "pattern": ".",',
' "cwd": ".",',
' "action": [',
' "python",',
' "-c",',
' "open(\'src/git_hooked_mac\', \'w\').write('
'\'git_hooked_mac\')",',
' ]',
' },',
'',
' ],',
' # src',
' {',
' "pattern": ".",',
' "condition": \'checkout_mac\',',
' "cwd": ".",',
' "action": [',
' "python",',
' "-c",',
' "open(\'src/git_hooked_mac\', \'w\').write('
'\'git_hooked_mac\')",',
' ]',
' },',
'',
'}',
']',
'',
'vars = {',
' # src',
......@@ -1218,6 +1182,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 = ['str_var']",
......@@ -1227,6 +1192,30 @@ class GClientSmokeGIT(GClientSmokeBase):
' "url": "git://127.0.0.1:20000/git/repo_10",',
' },',
'',
' # src -> src/repo9 -> src/repo8 -> src/recursed_os_repo',
' "src/recursed_os_repo": {',
' "url": "/repo_5",',
' "condition": \'(checkout_linux) or (checkout_mac)\',',
' },',
'',
' # src -> src/repo11',
' "src/repo11": {',
' "url": "/repo_11",',
' "condition": \'(checkout_ios) or (checkout_mac)\',',
' },',
'',
' # src -> src/repo11 -> src/repo12',
' "src/repo12": {',
' "url": "/repo_12",',
' "condition": \'(checkout_ios) or (checkout_mac)\',',
' },',
'',
' # src -> src/repo9 -> src/repo4',
' "src/repo4": {',
' "url": "/repo_4",',
' "condition": \'checkout_android\',',
' },',
'',
' # src -> src/repo6',
' "src/repo6": {',
' "url": "/repo_6",',
......@@ -1249,56 +1238,6 @@ class GClientSmokeGIT(GClientSmokeBase):
'',
'}',
'',
'deps_os = {',
' "android": {',
' # src -> src/repo9 -> src/repo4',
' "src/repo4": {',
' "url": "/repo_4",',
' },',
'',
' },',
'',
' "ios": {',
' # src -> src/repo11',
' "src/repo11": {',
' "url": "/repo_11",',
' },',
'',
' # src -> src/repo11 -> src/repo12',
' "src/repo12": {',
' "url": "/repo_12",',
' },',
'',
' },',
'',
' "mac": {',
' # src -> src/repo9 -> src/repo8 -> src/recursed_os_repo',
' "src/recursed_os_repo": {',
' "url": "/repo_5",',
' },',
'',
' # src -> src/repo11',
' "src/repo11": {',
' "url": "/repo_11",',
' },',
'',
' # src -> src/repo11 -> src/repo12',
' "src/repo12": {',
' "url": "/repo_12",',
' },',
'',
' },',
'',
' "unix": {',
' # src -> src/repo9 -> src/repo8 -> src/recursed_os_repo',
' "src/recursed_os_repo": {',
' "url": "/repo_5",',
' },',
'',
' },',
'',
'}',
'',
'vars = {',
' # src -> src/repo9',
' "str_var": \'xyz\',',
......
......@@ -436,19 +436,10 @@ class GclientTest(trial_dir.TestCase):
' }]\n')
write(
os.path.join('foo', 'DEPS'),
'target_os = ["baz"]\n'
'deps_os = {\n'
' "unix": { "foo/unix": "/unix", },\n'
' "baz": { "foo/baz": "/baz", },\n'
' "jaz": { "foo/jaz": "/jaz", },\n'
'}')
'target_os = ["baz"]\n')
write(
os.path.join('bar', 'DEPS'),
'deps_os = {\n'
' "unix": { "bar/unix": "/unix", },\n'
' "baz": { "bar/baz": "/baz", },\n'
' "jaz": { "bar/jaz": "/jaz", },\n'
'}')
'')
parser = gclient.OptionParser()
options, _ = parser.parse_args(['--jobs', '1'])
......@@ -457,15 +448,11 @@ class GclientTest(trial_dir.TestCase):
obj = gclient.GClient.LoadCurrentConfig(options)
obj.RunOnDeps('None', [])
self.assertEqual(['unix'], sorted(obj.enforced_os))
self.assertEquals(
[
('bar', 'svn://example.com/bar'),
('bar/unix', 'svn://example.com/unix'),
('foo', 'svn://example.com/foo'),
('foo/baz', 'svn://example.com/baz'),
('foo/unix', 'svn://example.com/unix'),
],
sorted(self._get_processed()))
self.assertEqual([('unix', 'baz'), ('unix',)],
[dep.target_os for dep in obj.dependencies])
self.assertEqual([('foo', 'svn://example.com/foo'),
('bar', 'svn://example.com/bar')],
self._get_processed())
def testTargetOsForHooksInDepsFile(self):
"""Verifies that specifying a target_os value in a DEPS file runs the right
......@@ -506,119 +493,15 @@ class GclientTest(trial_dir.TestCase):
obj = gclient.GClient.LoadCurrentConfig(options)
obj.RunOnDeps('None', args)
self.assertEqual(['zippy'], sorted(obj.enforced_os))
all_hooks = [h.action for h in obj.GetHooks(options)]
self.assertEquals(
[('.', 'svn://example.com/'),],
sorted(self._get_processed()))
self.assertEquals(all_hooks,
[('python', 'do_a')])
# Test for OS that has extra hooks in hooks_os.
parser = gclient.OptionParser()
options, args = parser.parse_args(['--jobs', '1'])
options.deps_os = 'blorp'
obj = gclient.GClient.LoadCurrentConfig(options)
obj.RunOnDeps('None', args)
self.assertEqual(['blorp'], sorted(obj.enforced_os))
all_hooks = [h.action for h in obj.GetHooks(options)]
all_hooks = obj.GetHooks(options)
self.assertEquals(
[('.', 'svn://example.com/'),],
sorted(self._get_processed()))
self.assertEquals(all_hooks,
self.assertEquals([h.action for h in all_hooks],
[('python', 'do_a'),
('python', 'do_b')])
def testUpdateWithOsDeps(self):
"""Verifies that complicated deps_os constructs result in the
correct data also with multple operating systems. Also see
testDepsOsOverrideDepsInDepsFile."""
test_data = [
# Tuples of deps, deps_os, os_list and expected_deps.
(
# OS with no overrides at all.
{'foo': 'default_foo'},
{'os1': { 'foo': None } },
['os2'],
{'foo': 'default_foo'}
),
(
# One OS wants to add a module.
{'foo': 'default_foo'},
{'os1': { 'bar': 'os1_bar' }},
['os1'],
{'foo': 'default_foo',
'bar': {'should_process': True, 'url': 'os1_bar'}}
),
(
# One OS wants to add a module. One doesn't care.
{'foo': 'default_foo'},
{'os1': { 'bar': 'os1_bar' }},
['os1', 'os2'],
{'foo': 'default_foo',
'bar': {'should_process': True, 'url': 'os1_bar'}}
),
(
# Two OSes want to add a module with the same definition.
{'foo': 'default_foo'},
{'os1': { 'bar': 'os12_bar' },
'os2': { 'bar': 'os12_bar' }},
['os1', 'os2'],
{'foo': 'default_foo',
'bar': {'should_process': True, 'url': 'os12_bar'}}
),
(
# One OS doesn't need module, one OS wants the default.
{'foo': 'default_foo'},
{'os1': { 'foo': None },
'os2': {}},
['os1', 'os2'],
{'foo': 'default_foo'}
),
(
# OS doesn't need module.
{'foo': 'default_foo'},
{'os1': { 'foo': None } },
['os1'],
{'foo': 'default_foo'}
),
(
# No-op override. Regression test for http://crbug.com/735418 .
{'foo': 'default_foo'},
{'os1': { 'foo': 'default_foo' } },
[],
{'foo': {'should_process': True, 'url': 'default_foo'}}
),
]
for deps, deps_os, target_os_list, expected_deps in test_data:
orig_deps = copy.deepcopy(deps)
result = gclient.Dependency.MergeWithOsDeps(
deps, deps_os, target_os_list, False)
self.assertEqual(result, expected_deps)
self.assertEqual(deps, orig_deps)
def testUpdateWithOsDepsInvalid(self):
test_data = [
# Tuples of deps, deps_os, os_list.
(
# OS wants a different version of module.
{'foo': 'default_foo'},
{'os1': { 'foo': 'os1_foo'} },
['os1'],
),
(
# One OS doesn't need module, another OS wants a special version.
{'foo': 'default_foo'},
{'os1': { 'foo': None },
'os2': { 'foo': 'os2_foo'}},
['os1', 'os2'],
),
]
for deps, deps_os, target_os_list in test_data:
with self.assertRaises(gclient_utils.Error):
gclient.Dependency.MergeWithOsDeps(deps, deps_os, target_os_list, False)
self.assertEquals([h.condition for h in all_hooks],
[None, 'checkout_blorp'])
def testOverride(self):
"""Verifies expected behavior of OverrideURL."""
......
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