libv8 6.3.292.48.1 → 6.7.288.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +10 -34
- data/CHANGELOG.md +16 -0
- data/README.md +9 -63
- data/Rakefile +2 -2
- data/ext/libv8/builder.rb +22 -87
- data/ext/libv8/extconf.rb +1 -1
- data/ext/libv8/paths.rb +5 -18
- data/lib/libv8/version.rb +1 -1
- data/spec/location_spec.rb +1 -2
- data/spec/spec_helper.rb +0 -1
- data/vendor/depot_tools/.gitattributes +1 -2
- data/vendor/depot_tools/OWNERS +0 -1
- data/vendor/depot_tools/PRESUBMIT.py +11 -6
- data/vendor/depot_tools/README.md +0 -1
- data/vendor/depot_tools/WATCHLISTS +0 -6
- data/vendor/depot_tools/auth.py +129 -87
- data/vendor/depot_tools/autoninja +11 -1
- data/vendor/depot_tools/autoninja.bat +7 -1
- data/vendor/depot_tools/autoninja.py +14 -6
- data/vendor/depot_tools/bootstrap/win/manifest.txt +1 -1
- data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +1 -1
- data/vendor/depot_tools/cipd +23 -2
- data/vendor/depot_tools/cipd.bat +2 -2
- data/vendor/depot_tools/cipd_client_version +1 -1
- data/vendor/depot_tools/cipd_manifest.txt +17 -7
- data/vendor/depot_tools/cit.py +7 -6
- data/vendor/depot_tools/cpplint.py +195 -35
- data/vendor/depot_tools/detect_host_arch.py +51 -0
- data/vendor/depot_tools/download_from_google_storage.py +85 -26
- data/vendor/depot_tools/fetch.py +11 -6
- data/vendor/depot_tools/fetch_configs/chromium.py +0 -1
- data/vendor/depot_tools/fetch_configs/goma_client.py +41 -0
- data/vendor/depot_tools/fetch_configs/infra.py +0 -1
- data/vendor/depot_tools/fetch_configs/infra_internal.py +0 -1
- data/vendor/depot_tools/gclient-new-workdir.py +4 -0
- data/vendor/depot_tools/gclient.py +732 -476
- data/vendor/depot_tools/gclient_eval.py +569 -58
- data/vendor/depot_tools/gclient_scm.py +258 -46
- data/vendor/depot_tools/gclient_utils.py +17 -1
- data/vendor/depot_tools/gerrit_util.py +46 -13
- data/vendor/depot_tools/git_cache.py +0 -2
- data/vendor/depot_tools/git_cl.py +176 -335
- data/vendor/depot_tools/git_common.py +19 -16
- data/vendor/depot_tools/git_footers.py +19 -5
- data/vendor/depot_tools/git_hyper_blame.py +9 -3
- data/vendor/depot_tools/git_new_branch.py +15 -3
- data/vendor/depot_tools/git_upstream_diff.py +7 -2
- data/vendor/depot_tools/gsutil.py +1 -1
- data/vendor/depot_tools/infra/config/cq.cfg +1 -2
- data/vendor/depot_tools/infra/config/recipes.cfg +1 -1
- data/vendor/depot_tools/luci-auth +13 -0
- data/vendor/depot_tools/luci-auth.bat +8 -0
- data/vendor/depot_tools/man/html/depot_tools.html +0 -8
- data/vendor/depot_tools/man/html/git-upstream-diff.html +20 -3
- data/vendor/depot_tools/man/man1/git-upstream-diff.1 +27 -6
- data/vendor/depot_tools/man/man7/depot_tools.7 +0 -5
- data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +2 -2
- data/vendor/depot_tools/man/src/git-upstream-diff.txt +21 -3
- data/vendor/depot_tools/man/src/make_docs.sh +6 -0
- data/vendor/depot_tools/my_activity.py +283 -93
- data/vendor/depot_tools/owners.py +9 -4
- data/vendor/depot_tools/owners_finder.py +7 -3
- data/vendor/depot_tools/post_build_ninja_summary.py +322 -0
- data/vendor/depot_tools/presubmit_canned_checks.py +91 -106
- data/vendor/depot_tools/presubmit_support.py +219 -157
- data/vendor/depot_tools/prpc +13 -0
- data/vendor/depot_tools/prpc.bat +8 -0
- data/vendor/depot_tools/recipes/OWNERS +3 -1
- data/vendor/depot_tools/recipes/README.recipes.md +70 -111
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +12 -5
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +36 -68
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_json.json → no_apply_patch_on_gclient.json} +64 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{no_shallow.json → shallow.json} +1 -1
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_empty_revision.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +0 -6
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +0 -7
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +0 -6
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle_deprecated.json +44 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_buildbot.json → tryjob_gerrit_branch_heads.json} +51 -5
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +48 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +19 -26
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +193 -155
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +9 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +2 -7
- data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +31 -5
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +37 -19
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +37 -19
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +37 -19
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +37 -23
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +4 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +40 -8
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +3 -3
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.py +6 -3
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/OWNERS +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/__init__.py +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +7 -56
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +15 -16
- data/vendor/depot_tools/recipes/recipes.py +4 -2
- data/vendor/depot_tools/recipes/trigger_recipe_roller.txt +12 -0
- data/vendor/depot_tools/roll_dep.py +35 -37
- data/vendor/depot_tools/support/chromite_wrapper +1 -1
- data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +3 -3
- data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +2 -2
- data/vendor/depot_tools/third_party/logilab/astroid/astpeephole.py +86 -0
- data/vendor/depot_tools/third_party/logilab/astroid/bases.py +53 -66
- data/vendor/depot_tools/third_party/logilab/astroid/brain/py2pytest.py +31 -31
- data/vendor/depot_tools/third_party/logilab/astroid/brain/pynose.py +39 -16
- data/vendor/depot_tools/third_party/logilab/astroid/brain/pysix_moves.py +225 -189
- data/vendor/depot_tools/third_party/logilab/astroid/inference.py +45 -41
- data/vendor/depot_tools/third_party/logilab/astroid/manager.py +1 -0
- data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +2 -2
- data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +3 -2
- data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +1 -0
- data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +57 -3
- data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +1 -1
- data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +21 -1
- data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +58 -33
- data/vendor/depot_tools/third_party/pylint/README.chromium +2 -2
- data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +3 -3
- data/vendor/depot_tools/third_party/pylint/checkers/base.py +6 -18
- data/vendor/depot_tools/third_party/pylint/checkers/classes.py +64 -63
- data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +25 -57
- data/vendor/depot_tools/third_party/pylint/checkers/format.py +14 -10
- data/vendor/depot_tools/third_party/pylint/checkers/python3.py +142 -37
- data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +10 -1
- data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +50 -7
- data/vendor/depot_tools/third_party/pylint/checkers/strings.py +1 -1
- data/vendor/depot_tools/third_party/pylint/epylint.py +2 -1
- data/vendor/depot_tools/third_party/pylint/gui.py +1 -1
- data/vendor/depot_tools/third_party/pylint/lint.py +88 -23
- data/vendor/depot_tools/third_party/pylint/reporters/html.py +37 -5
- data/vendor/depot_tools/third_party/pylint/testutils.py +1 -1
- data/vendor/depot_tools/third_party/pylint/utils.py +5 -0
- data/vendor/depot_tools/vpython +31 -1
- data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +35 -2
- data/vendor/depot_tools/win_toolchain/package_from_installed.py +0 -15
- data/vendor/depot_tools/yapf +17 -0
- data/vendor/depot_tools/{apply_issue.bat → yapf.bat} +2 -2
- metadata +16 -58
- data/ext/libv8/compiler.rb +0 -39
- data/ext/libv8/compiler/apple_llvm.rb +0 -22
- data/ext/libv8/compiler/clang.rb +0 -22
- data/ext/libv8/compiler/gcc.rb +0 -22
- data/ext/libv8/compiler/generic_compiler.rb +0 -66
- data/ext/libv8/make.rb +0 -13
- data/ext/libv8/patcher.rb +0 -21
- data/patches/0001-Build-a-standalone-static-library.patch +0 -26
- data/patches/0002-Don-t-compile-unnecessary-stuff.patch +0 -85
- data/patches/0003-Use-the-fPIC-flag-for-the-static-library.patch +0 -25
- data/patches/0004-Do-not-embed-debug-symbols-in-macOS-libraries.patch +0 -25
- data/patches/0005-Remove-TryInstallOptimizedCode.patch +0 -321
- data/patches/mingw-generate-makefiles.sh +0 -97
- data/spec/compiler/apple_llvm_spec.rb +0 -37
- data/spec/compiler/clang_spec.rb +0 -37
- data/spec/compiler/gcc_spec.rb +0 -37
- data/spec/compiler/generic_compiler_spec.rb +0 -50
- data/spec/compiler_spec.rb +0 -45
- data/spec/support/compiler_helpers.rb +0 -47
- data/vendor/depot_tools/apply_issue +0 -8
- data/vendor/depot_tools/apply_issue.py +0 -315
- data/vendor/depot_tools/man/html/git-cherry-pick-upload.html +0 -815
- data/vendor/depot_tools/man/man1/git-cherry-pick-upload.1 +0 -80
- data/vendor/depot_tools/man/src/_git-cherry-pick-upload_desc.helper.txt +0 -1
- data/vendor/depot_tools/man/src/git-cherry-pick-upload.demo.1.sh +0 -17
- data/vendor/depot_tools/man/src/git-cherry-pick-upload.txt +0 -35
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2_json_win.json +0 -196
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/__init__.py +0 -6
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/api.py +0 -97
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/basic.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/buildbot.json +0 -30
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/no_auth.json +0 -27
- data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.py +0 -38
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch.json +0 -69
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch_new.json +0 -69
- data/vendor/depot_tools/third_party/cq_client/OWNERS +0 -2
- data/vendor/depot_tools/third_party/cq_client/README.depot_tools.md +0 -2
- data/vendor/depot_tools/third_party/cq_client/README.md +0 -59
- data/vendor/depot_tools/third_party/cq_client/__init__.py +0 -3
- data/vendor/depot_tools/third_party/cq_client/v1/__init__.py +0 -3
- data/vendor/depot_tools/third_party/cq_client/v1/cq.pb.go +0 -810
- data/vendor/depot_tools/third_party/cq_client/v1/cq.proto +0 -281
- data/vendor/depot_tools/third_party/cq_client/v1/cq_pb2.py +0 -794
- data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_both.cfg +0 -71
- data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_gerrit.cfg +0 -58
- data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_rietveld.cfg +0 -60
- data/vendor/depot_tools/third_party/cq_client/v2/__init__.py +0 -3
- data/vendor/depot_tools/third_party/cq_client/v2/cq.pb.go +0 -792
- data/vendor/depot_tools/third_party/cq_client/v2/cq.proto +0 -270
- data/vendor/depot_tools/third_party/cq_client/v2/cq_pb2.py +0 -841
@@ -3,29 +3,104 @@
|
|
3
3
|
# found in the LICENSE file.
|
4
4
|
|
5
5
|
import ast
|
6
|
+
import cStringIO
|
6
7
|
import collections
|
8
|
+
import logging
|
9
|
+
import tokenize
|
10
|
+
|
11
|
+
import gclient_utils
|
7
12
|
|
8
13
|
from third_party import schema
|
9
14
|
|
10
15
|
|
16
|
+
class _NodeDict(collections.MutableMapping):
|
17
|
+
"""Dict-like type that also stores information on AST nodes and tokens."""
|
18
|
+
def __init__(self, data, tokens=None):
|
19
|
+
self.data = collections.OrderedDict(data)
|
20
|
+
self.tokens = tokens
|
21
|
+
|
22
|
+
def __str__(self):
|
23
|
+
return str({k: v[0] for k, v in self.data.iteritems()})
|
24
|
+
|
25
|
+
def __getitem__(self, key):
|
26
|
+
return self.data[key][0]
|
27
|
+
|
28
|
+
def __setitem__(self, key, value):
|
29
|
+
self.data[key] = (value, None)
|
30
|
+
|
31
|
+
def __delitem__(self, key):
|
32
|
+
del self.data[key]
|
33
|
+
|
34
|
+
def __iter__(self):
|
35
|
+
return iter(self.data)
|
36
|
+
|
37
|
+
def __len__(self):
|
38
|
+
return len(self.data)
|
39
|
+
|
40
|
+
def MoveTokens(self, origin, delta):
|
41
|
+
if self.tokens:
|
42
|
+
new_tokens = {}
|
43
|
+
for pos, token in self.tokens.iteritems():
|
44
|
+
if pos[0] >= origin:
|
45
|
+
pos = (pos[0] + delta, pos[1])
|
46
|
+
token = token[:2] + (pos,) + token[3:]
|
47
|
+
new_tokens[pos] = token
|
48
|
+
|
49
|
+
for value, node in self.data.values():
|
50
|
+
if node.lineno >= origin:
|
51
|
+
node.lineno += delta
|
52
|
+
if isinstance(value, _NodeDict):
|
53
|
+
value.MoveTokens(origin, delta)
|
54
|
+
|
55
|
+
def GetNode(self, key):
|
56
|
+
return self.data[key][1]
|
57
|
+
|
58
|
+
def SetNode(self, key, value, node):
|
59
|
+
self.data[key] = (value, node)
|
60
|
+
|
61
|
+
|
62
|
+
def _NodeDictSchema(dict_schema):
|
63
|
+
"""Validate dict_schema after converting _NodeDict to a regular dict."""
|
64
|
+
def validate(d):
|
65
|
+
schema.Schema(dict_schema).validate(dict(d))
|
66
|
+
return True
|
67
|
+
return validate
|
68
|
+
|
69
|
+
|
11
70
|
# See https://github.com/keleshev/schema for docs how to configure schema.
|
12
|
-
_GCLIENT_DEPS_SCHEMA = {
|
71
|
+
_GCLIENT_DEPS_SCHEMA = _NodeDictSchema({
|
13
72
|
schema.Optional(basestring): schema.Or(
|
14
73
|
None,
|
15
74
|
basestring,
|
16
|
-
{
|
75
|
+
_NodeDictSchema({
|
17
76
|
# Repo and revision to check out under the path
|
18
77
|
# (same as if no dict was used).
|
19
|
-
'url': basestring,
|
78
|
+
'url': schema.Or(None, basestring),
|
20
79
|
|
21
80
|
# Optional condition string. The dep will only be processed
|
22
81
|
# if the condition evaluates to True.
|
23
82
|
schema.Optional('condition'): basestring,
|
24
|
-
|
83
|
+
|
84
|
+
schema.Optional('dep_type', default='git'): basestring,
|
85
|
+
}),
|
86
|
+
# CIPD package.
|
87
|
+
_NodeDictSchema({
|
88
|
+
'packages': [
|
89
|
+
_NodeDictSchema({
|
90
|
+
'package': basestring,
|
91
|
+
|
92
|
+
'version': basestring,
|
93
|
+
})
|
94
|
+
],
|
95
|
+
|
96
|
+
schema.Optional('condition'): basestring,
|
97
|
+
|
98
|
+
schema.Optional('dep_type', default='cipd'): basestring,
|
99
|
+
}),
|
25
100
|
),
|
26
|
-
}
|
101
|
+
})
|
27
102
|
|
28
|
-
_GCLIENT_HOOKS_SCHEMA = [{
|
103
|
+
_GCLIENT_HOOKS_SCHEMA = [_NodeDictSchema({
|
29
104
|
# Hook action: list of command-line arguments to invoke.
|
30
105
|
'action': [basestring],
|
31
106
|
|
@@ -43,9 +118,9 @@ _GCLIENT_HOOKS_SCHEMA = [{
|
|
43
118
|
# Optional condition string. The hook will only be run
|
44
119
|
# if the condition evaluates to True.
|
45
120
|
schema.Optional('condition'): basestring,
|
46
|
-
}]
|
121
|
+
})]
|
47
122
|
|
48
|
-
_GCLIENT_SCHEMA = schema.Schema({
|
123
|
+
_GCLIENT_SCHEMA = schema.Schema(_NodeDictSchema({
|
49
124
|
# List of host names from which dependencies are allowed (whitelist).
|
50
125
|
# NOTE: when not present, all hosts are allowed.
|
51
126
|
# NOTE: scoped to current DEPS file, not recursive.
|
@@ -63,9 +138,14 @@ _GCLIENT_SCHEMA = schema.Schema({
|
|
63
138
|
|
64
139
|
# Similar to 'deps' (see above) - also keyed by OS (e.g. 'linux').
|
65
140
|
# Also see 'target_os'.
|
66
|
-
schema.Optional('deps_os'): {
|
141
|
+
schema.Optional('deps_os'): _NodeDictSchema({
|
67
142
|
schema.Optional(basestring): _GCLIENT_DEPS_SCHEMA,
|
68
|
-
},
|
143
|
+
}),
|
144
|
+
|
145
|
+
# Dependency to get gclient_gn_args* settings from. This allows these values
|
146
|
+
# to be set in a recursedeps file, rather than requiring that they exist in
|
147
|
+
# the top-level solution.
|
148
|
+
schema.Optional('gclient_gn_args_from'): basestring,
|
69
149
|
|
70
150
|
# Path to GN args file to write selected variables.
|
71
151
|
schema.Optional('gclient_gn_args_file'): basestring,
|
@@ -79,9 +159,9 @@ _GCLIENT_SCHEMA = schema.Schema({
|
|
79
159
|
schema.Optional('hooks'): _GCLIENT_HOOKS_SCHEMA,
|
80
160
|
|
81
161
|
# Similar to 'hooks', also keyed by OS.
|
82
|
-
schema.Optional('hooks_os'): {
|
162
|
+
schema.Optional('hooks_os'): _NodeDictSchema({
|
83
163
|
schema.Optional(basestring): _GCLIENT_HOOKS_SCHEMA
|
84
|
-
},
|
164
|
+
}),
|
85
165
|
|
86
166
|
# Rules which #includes are allowed in the directory.
|
87
167
|
# Also see 'skip_child_includes' and 'specific_include_rules'.
|
@@ -107,9 +187,9 @@ _GCLIENT_SCHEMA = schema.Schema({
|
|
107
187
|
|
108
188
|
# Mapping from paths to include rules specific for that path.
|
109
189
|
# See 'include_rules' for more details.
|
110
|
-
schema.Optional('specific_include_rules'): {
|
190
|
+
schema.Optional('specific_include_rules'): _NodeDictSchema({
|
111
191
|
schema.Optional(basestring): [basestring]
|
112
|
-
},
|
192
|
+
}),
|
113
193
|
|
114
194
|
# List of additional OS names to consider when selecting dependencies
|
115
195
|
# from deps_os.
|
@@ -120,13 +200,13 @@ _GCLIENT_SCHEMA = schema.Schema({
|
|
120
200
|
schema.Optional('use_relative_paths'): bool,
|
121
201
|
|
122
202
|
# Variables that can be referenced using Var() - see 'deps'.
|
123
|
-
schema.Optional('vars'): {
|
203
|
+
schema.Optional('vars'): _NodeDictSchema({
|
124
204
|
schema.Optional(basestring): schema.Or(basestring, bool),
|
125
|
-
},
|
126
|
-
})
|
205
|
+
}),
|
206
|
+
}))
|
127
207
|
|
128
208
|
|
129
|
-
def _gclient_eval(node_or_string,
|
209
|
+
def _gclient_eval(node_or_string, filename='<unknown>', vars_dict=None):
|
130
210
|
"""Safely evaluates a single expression. Returns the result."""
|
131
211
|
_allowed_names = {'None': None, 'True': True, 'False': False}
|
132
212
|
if isinstance(node_or_string, basestring):
|
@@ -135,7 +215,15 @@ def _gclient_eval(node_or_string, global_scope, filename='<unknown>'):
|
|
135
215
|
node_or_string = node_or_string.body
|
136
216
|
def _convert(node):
|
137
217
|
if isinstance(node, ast.Str):
|
138
|
-
|
218
|
+
if vars_dict is None:
|
219
|
+
return node.s
|
220
|
+
try:
|
221
|
+
return node.s.format(**vars_dict)
|
222
|
+
except KeyError as e:
|
223
|
+
raise KeyError(
|
224
|
+
'%s was used as a variable, but was not declared in the vars dict '
|
225
|
+
'(file %r, line %s)' % (
|
226
|
+
e.message, filename, getattr(node, 'lineno', '<unknown>')))
|
139
227
|
elif isinstance(node, ast.Num):
|
140
228
|
return node.n
|
141
229
|
elif isinstance(node, ast.Tuple):
|
@@ -143,8 +231,7 @@ def _gclient_eval(node_or_string, global_scope, filename='<unknown>'):
|
|
143
231
|
elif isinstance(node, ast.List):
|
144
232
|
return list(map(_convert, node.elts))
|
145
233
|
elif isinstance(node, ast.Dict):
|
146
|
-
return
|
147
|
-
(_convert(k), _convert(v))
|
234
|
+
return _NodeDict((_convert(k), (_convert(v), v))
|
148
235
|
for k, v in zip(node.keys, node.values))
|
149
236
|
elif isinstance(node, ast.Name):
|
150
237
|
if node.id not in _allowed_names:
|
@@ -153,16 +240,27 @@ def _gclient_eval(node_or_string, global_scope, filename='<unknown>'):
|
|
153
240
|
node.id, filename, getattr(node, 'lineno', '<unknown>')))
|
154
241
|
return _allowed_names[node.id]
|
155
242
|
elif isinstance(node, ast.Call):
|
156
|
-
if not isinstance(node.func, ast.Name):
|
243
|
+
if not isinstance(node.func, ast.Name) or node.func.id != 'Var':
|
157
244
|
raise ValueError(
|
158
|
-
'
|
245
|
+
'Var is the only allowed function (file %r, line %s)' % (
|
159
246
|
filename, getattr(node, 'lineno', '<unknown>')))
|
160
|
-
if node.keywords or node.starargs or node.kwargs:
|
247
|
+
if node.keywords or node.starargs or node.kwargs or len(node.args) != 1:
|
161
248
|
raise ValueError(
|
162
|
-
'
|
249
|
+
'Var takes exactly one argument (file %r, line %s)' % (
|
163
250
|
filename, getattr(node, 'lineno', '<unknown>')))
|
164
|
-
|
165
|
-
|
251
|
+
arg = _convert(node.args[0])
|
252
|
+
if not isinstance(arg, basestring):
|
253
|
+
raise ValueError(
|
254
|
+
'Var\'s argument must be a variable name (file %r, line %s)' % (
|
255
|
+
filename, getattr(node, 'lineno', '<unknown>')))
|
256
|
+
if vars_dict is None:
|
257
|
+
return '{' + arg + '}'
|
258
|
+
if arg not in vars_dict:
|
259
|
+
raise KeyError(
|
260
|
+
'%s was used as a variable, but was not declared in the vars dict '
|
261
|
+
'(file %r, line %s)' % (
|
262
|
+
arg, filename, getattr(node, 'lineno', '<unknown>')))
|
263
|
+
return vars_dict[arg]
|
166
264
|
elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add):
|
167
265
|
return _convert(node.left) + _convert(node.right)
|
168
266
|
elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.Mod):
|
@@ -175,41 +273,35 @@ def _gclient_eval(node_or_string, global_scope, filename='<unknown>'):
|
|
175
273
|
return _convert(node_or_string)
|
176
274
|
|
177
275
|
|
178
|
-
def Exec(content,
|
179
|
-
"""Safely execs a set of assignments.
|
180
|
-
|
181
|
-
|
182
|
-
node_or_string = node_or_string.body
|
183
|
-
|
184
|
-
def _visit_in_module(node):
|
185
|
-
if isinstance(node, ast.Assign):
|
186
|
-
if len(node.targets) != 1:
|
187
|
-
raise ValueError(
|
188
|
-
'invalid assignment: use exactly one target (file %r, line %s)' % (
|
189
|
-
filename, getattr(node, 'lineno', '<unknown>')))
|
190
|
-
target = node.targets[0]
|
191
|
-
if not isinstance(target, ast.Name):
|
192
|
-
raise ValueError(
|
193
|
-
'invalid assignment: target should be a name (file %r, line %s)' % (
|
194
|
-
filename, getattr(node, 'lineno', '<unknown>')))
|
195
|
-
value = _gclient_eval(node.value, global_scope, filename=filename)
|
196
|
-
|
197
|
-
if target.id in local_scope:
|
198
|
-
raise ValueError(
|
199
|
-
'invalid assignment: overrides var %r (file %r, line %s)' % (
|
200
|
-
target.id, filename, getattr(node, 'lineno', '<unknown>')))
|
201
|
-
|
202
|
-
local_scope[target.id] = value
|
203
|
-
else:
|
276
|
+
def Exec(content, filename='<unknown>', vars_override=None):
|
277
|
+
"""Safely execs a set of assignments."""
|
278
|
+
def _validate_statement(node, local_scope):
|
279
|
+
if not isinstance(node, ast.Assign):
|
204
280
|
raise ValueError(
|
205
281
|
'unexpected AST node: %s %s (file %r, line %s)' % (
|
206
282
|
node, ast.dump(node), filename,
|
207
283
|
getattr(node, 'lineno', '<unknown>')))
|
208
284
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
285
|
+
if len(node.targets) != 1:
|
286
|
+
raise ValueError(
|
287
|
+
'invalid assignment: use exactly one target (file %r, line %s)' % (
|
288
|
+
filename, getattr(node, 'lineno', '<unknown>')))
|
289
|
+
|
290
|
+
target = node.targets[0]
|
291
|
+
if not isinstance(target, ast.Name):
|
292
|
+
raise ValueError(
|
293
|
+
'invalid assignment: target should be a name (file %r, line %s)' % (
|
294
|
+
filename, getattr(node, 'lineno', '<unknown>')))
|
295
|
+
if target.id in local_scope:
|
296
|
+
raise ValueError(
|
297
|
+
'invalid assignment: overrides var %r (file %r, line %s)' % (
|
298
|
+
target.id, filename, getattr(node, 'lineno', '<unknown>')))
|
299
|
+
|
300
|
+
node_or_string = ast.parse(content, filename=filename, mode='exec')
|
301
|
+
if isinstance(node_or_string, ast.Expression):
|
302
|
+
node_or_string = node_or_string.body
|
303
|
+
|
304
|
+
if not isinstance(node_or_string, ast.Module):
|
213
305
|
raise ValueError(
|
214
306
|
'unexpected AST node: %s %s (file %r, line %s)' % (
|
215
307
|
node_or_string,
|
@@ -217,7 +309,191 @@ def Exec(content, global_scope, local_scope, filename='<unknown>'):
|
|
217
309
|
filename,
|
218
310
|
getattr(node_or_string, 'lineno', '<unknown>')))
|
219
311
|
|
220
|
-
|
312
|
+
statements = {}
|
313
|
+
for statement in node_or_string.body:
|
314
|
+
_validate_statement(statement, statements)
|
315
|
+
statements[statement.targets[0].id] = statement.value
|
316
|
+
|
317
|
+
tokens = {
|
318
|
+
token[2]: list(token)
|
319
|
+
for token in tokenize.generate_tokens(
|
320
|
+
cStringIO.StringIO(content).readline)
|
321
|
+
}
|
322
|
+
local_scope = _NodeDict({}, tokens)
|
323
|
+
|
324
|
+
# Process vars first, so we can expand variables in the rest of the DEPS file.
|
325
|
+
vars_dict = {}
|
326
|
+
if 'vars' in statements:
|
327
|
+
vars_statement = statements['vars']
|
328
|
+
value = _gclient_eval(vars_statement, filename)
|
329
|
+
local_scope.SetNode('vars', value, vars_statement)
|
330
|
+
# Update the parsed vars with the overrides, but only if they are already
|
331
|
+
# present (overrides do not introduce new variables).
|
332
|
+
vars_dict.update(value)
|
333
|
+
if vars_override:
|
334
|
+
vars_dict.update({
|
335
|
+
k: v
|
336
|
+
for k, v in vars_override.iteritems()
|
337
|
+
if k in vars_dict})
|
338
|
+
|
339
|
+
for name, node in statements.iteritems():
|
340
|
+
value = _gclient_eval(node, filename, vars_dict)
|
341
|
+
local_scope.SetNode(name, value, node)
|
342
|
+
|
343
|
+
return _GCLIENT_SCHEMA.validate(local_scope)
|
344
|
+
|
345
|
+
|
346
|
+
def ExecLegacy(content, filename='<unknown>', vars_override=None):
|
347
|
+
"""Executes a DEPS file |content| using exec."""
|
348
|
+
local_scope = {}
|
349
|
+
global_scope = {'Var': lambda var_name: '{%s}' % var_name}
|
350
|
+
|
351
|
+
# If we use 'exec' directly, it complains that 'Parse' contains a nested
|
352
|
+
# function with free variables.
|
353
|
+
# This is because on versions of Python < 2.7.9, "exec(a, b, c)" not the same
|
354
|
+
# as "exec a in b, c" (See https://bugs.python.org/issue21591).
|
355
|
+
eval(compile(content, filename, 'exec'), global_scope, local_scope)
|
356
|
+
|
357
|
+
if 'vars' not in local_scope:
|
358
|
+
return local_scope
|
359
|
+
|
360
|
+
vars_dict = {}
|
361
|
+
vars_dict.update(local_scope['vars'])
|
362
|
+
if vars_override:
|
363
|
+
vars_dict.update({
|
364
|
+
k: v
|
365
|
+
for k, v in vars_override.iteritems()
|
366
|
+
if k in vars_dict
|
367
|
+
})
|
368
|
+
|
369
|
+
def _DeepFormat(node):
|
370
|
+
if isinstance(node, basestring):
|
371
|
+
return node.format(**vars_dict)
|
372
|
+
elif isinstance(node, dict):
|
373
|
+
return {
|
374
|
+
k.format(**vars_dict): _DeepFormat(v)
|
375
|
+
for k, v in node.iteritems()
|
376
|
+
}
|
377
|
+
elif isinstance(node, list):
|
378
|
+
return [_DeepFormat(elem) for elem in node]
|
379
|
+
elif isinstance(node, tuple):
|
380
|
+
return tuple(_DeepFormat(elem) for elem in node)
|
381
|
+
else:
|
382
|
+
return node
|
383
|
+
|
384
|
+
return _DeepFormat(local_scope)
|
385
|
+
|
386
|
+
|
387
|
+
def _StandardizeDeps(deps_dict, vars_dict):
|
388
|
+
""""Standardizes the deps_dict.
|
389
|
+
|
390
|
+
For each dependency:
|
391
|
+
- Expands the variable in the dependency name.
|
392
|
+
- Ensures the dependency is a dictionary.
|
393
|
+
- Set's the 'dep_type' to be 'git' by default.
|
394
|
+
"""
|
395
|
+
new_deps_dict = {}
|
396
|
+
for dep_name, dep_info in deps_dict.items():
|
397
|
+
dep_name = dep_name.format(**vars_dict)
|
398
|
+
if not isinstance(dep_info, collections.Mapping):
|
399
|
+
dep_info = {'url': dep_info}
|
400
|
+
dep_info.setdefault('dep_type', 'git')
|
401
|
+
new_deps_dict[dep_name] = dep_info
|
402
|
+
return new_deps_dict
|
403
|
+
|
404
|
+
|
405
|
+
def _MergeDepsOs(deps_dict, os_deps_dict, os_name):
|
406
|
+
"""Merges the deps in os_deps_dict into conditional dependencies in deps_dict.
|
407
|
+
|
408
|
+
The dependencies in os_deps_dict are transformed into conditional dependencies
|
409
|
+
using |'checkout_' + os_name|.
|
410
|
+
If the dependency is already present, the URL and revision must coincide.
|
411
|
+
"""
|
412
|
+
for dep_name, dep_info in os_deps_dict.items():
|
413
|
+
# Make this condition very visible, so it's not a silent failure.
|
414
|
+
# It's unclear how to support None override in deps_os.
|
415
|
+
if dep_info['url'] is None:
|
416
|
+
logging.error('Ignoring %r:%r in %r deps_os', dep_name, dep_info, os_name)
|
417
|
+
continue
|
418
|
+
|
419
|
+
os_condition = 'checkout_' + (os_name if os_name != 'unix' else 'linux')
|
420
|
+
UpdateCondition(dep_info, 'and', os_condition)
|
421
|
+
|
422
|
+
if dep_name in deps_dict:
|
423
|
+
if deps_dict[dep_name]['url'] != dep_info['url']:
|
424
|
+
raise gclient_utils.Error(
|
425
|
+
'Value from deps_os (%r; %r: %r) conflicts with existing deps '
|
426
|
+
'entry (%r).' % (
|
427
|
+
os_name, dep_name, dep_info, deps_dict[dep_name]))
|
428
|
+
|
429
|
+
UpdateCondition(dep_info, 'or', deps_dict[dep_name].get('condition'))
|
430
|
+
|
431
|
+
deps_dict[dep_name] = dep_info
|
432
|
+
|
433
|
+
|
434
|
+
def UpdateCondition(info_dict, op, new_condition):
|
435
|
+
"""Updates info_dict's condition with |new_condition|.
|
436
|
+
|
437
|
+
An absent value is treated as implicitly True.
|
438
|
+
"""
|
439
|
+
curr_condition = info_dict.get('condition')
|
440
|
+
# Easy case: Both are present.
|
441
|
+
if curr_condition and new_condition:
|
442
|
+
info_dict['condition'] = '(%s) %s (%s)' % (
|
443
|
+
curr_condition, op, new_condition)
|
444
|
+
# If |op| == 'and', and at least one condition is present, then use it.
|
445
|
+
elif op == 'and' and (curr_condition or new_condition):
|
446
|
+
info_dict['condition'] = curr_condition or new_condition
|
447
|
+
# Otherwise, no condition should be set
|
448
|
+
elif curr_condition:
|
449
|
+
del info_dict['condition']
|
450
|
+
|
451
|
+
|
452
|
+
def Parse(content, validate_syntax, filename, vars_override=None):
|
453
|
+
"""Parses DEPS strings.
|
454
|
+
|
455
|
+
Executes the Python-like string stored in content, resulting in a Python
|
456
|
+
dictionary specifyied by the schema above. Supports syntax validation and
|
457
|
+
variable expansion.
|
458
|
+
|
459
|
+
Args:
|
460
|
+
content: str. DEPS file stored as a string.
|
461
|
+
validate_syntax: bool. Whether syntax should be validated using the schema
|
462
|
+
defined above.
|
463
|
+
filename: str. The name of the DEPS file, or a string describing the source
|
464
|
+
of the content, e.g. '<string>', '<unknown>'.
|
465
|
+
vars_override: dict, optional. A dictionary with overrides for the variables
|
466
|
+
defined by the DEPS file.
|
467
|
+
|
468
|
+
Returns:
|
469
|
+
A Python dict with the parsed contents of the DEPS file, as specified by the
|
470
|
+
schema above.
|
471
|
+
"""
|
472
|
+
if validate_syntax:
|
473
|
+
result = Exec(content, filename, vars_override)
|
474
|
+
else:
|
475
|
+
result = ExecLegacy(content, filename, vars_override)
|
476
|
+
|
477
|
+
vars_dict = result.get('vars', {})
|
478
|
+
if 'deps' in result:
|
479
|
+
result['deps'] = _StandardizeDeps(result['deps'], vars_dict)
|
480
|
+
|
481
|
+
if 'deps_os' in result:
|
482
|
+
deps = result.setdefault('deps', {})
|
483
|
+
for os_name, os_deps in result['deps_os'].iteritems():
|
484
|
+
os_deps = _StandardizeDeps(os_deps, vars_dict)
|
485
|
+
_MergeDepsOs(deps, os_deps, os_name)
|
486
|
+
del result['deps_os']
|
487
|
+
|
488
|
+
if 'hooks_os' in result:
|
489
|
+
hooks = result.setdefault('hooks', [])
|
490
|
+
for os_name, os_hooks in result['hooks_os'].iteritems():
|
491
|
+
for hook in os_hooks:
|
492
|
+
UpdateCondition(hook, 'and', 'checkout_' + os_name)
|
493
|
+
hooks.extend(os_hooks)
|
494
|
+
del result['hooks_os']
|
495
|
+
|
496
|
+
return result
|
221
497
|
|
222
498
|
|
223
499
|
def EvaluateCondition(condition, variables, referenced_variables=None):
|
@@ -317,3 +593,238 @@ def EvaluateCondition(condition, variables, referenced_variables=None):
|
|
317
593
|
'unexpected AST node: %s %s (inside %r)' % (
|
318
594
|
node, ast.dump(node), condition))
|
319
595
|
return _convert(main_node)
|
596
|
+
|
597
|
+
|
598
|
+
def RenderDEPSFile(gclient_dict):
|
599
|
+
contents = sorted(gclient_dict.tokens.values(), key=lambda token: token[2])
|
600
|
+
return tokenize.untokenize(contents)
|
601
|
+
|
602
|
+
|
603
|
+
def _UpdateAstString(tokens, node, value):
|
604
|
+
position = node.lineno, node.col_offset
|
605
|
+
quote_char = tokens[position][1][0]
|
606
|
+
tokens[position][1] = quote_char + value + quote_char
|
607
|
+
node.s = value
|
608
|
+
|
609
|
+
|
610
|
+
def _ShiftLinesInTokens(tokens, delta, start):
|
611
|
+
new_tokens = {}
|
612
|
+
for token in tokens.values():
|
613
|
+
if token[2][0] >= start:
|
614
|
+
token[2] = token[2][0] + delta, token[2][1]
|
615
|
+
token[3] = token[3][0] + delta, token[3][1]
|
616
|
+
new_tokens[token[2]] = token
|
617
|
+
return new_tokens
|
618
|
+
|
619
|
+
|
620
|
+
def AddVar(gclient_dict, var_name, value):
|
621
|
+
if not isinstance(gclient_dict, _NodeDict) or gclient_dict.tokens is None:
|
622
|
+
raise ValueError(
|
623
|
+
"Can't use SetVar for the given gclient dict. It contains no "
|
624
|
+
"formatting information.")
|
625
|
+
|
626
|
+
if 'vars' not in gclient_dict:
|
627
|
+
raise KeyError("vars dict is not defined.")
|
628
|
+
|
629
|
+
if var_name in gclient_dict['vars']:
|
630
|
+
raise ValueError(
|
631
|
+
"%s has already been declared in the vars dict. Consider using SetVar "
|
632
|
+
"instead." % var_name)
|
633
|
+
|
634
|
+
if not gclient_dict['vars']:
|
635
|
+
raise ValueError('vars dict is empty. This is not yet supported.')
|
636
|
+
|
637
|
+
# We will attempt to add the var right after 'vars = {'.
|
638
|
+
node = gclient_dict.GetNode('vars')
|
639
|
+
if node is None:
|
640
|
+
raise ValueError(
|
641
|
+
"The vars dict has no formatting information." % var_name)
|
642
|
+
line = node.lineno + 1
|
643
|
+
|
644
|
+
# We will try to match the new var's indentation to the next variable.
|
645
|
+
col = node.keys[0].col_offset
|
646
|
+
|
647
|
+
# We use a minimal Python dictionary, so that ast can parse it.
|
648
|
+
var_content = '{\n%s"%s": "%s",\n}' % (' ' * col, var_name, value)
|
649
|
+
var_ast = ast.parse(var_content).body[0].value
|
650
|
+
|
651
|
+
# Set the ast nodes for the key and value.
|
652
|
+
vars_node = gclient_dict.GetNode('vars')
|
653
|
+
|
654
|
+
var_name_node = var_ast.keys[0]
|
655
|
+
var_name_node.lineno += line - 2
|
656
|
+
vars_node.keys.insert(0, var_name_node)
|
657
|
+
|
658
|
+
value_node = var_ast.values[0]
|
659
|
+
value_node.lineno += line - 2
|
660
|
+
vars_node.values.insert(0, value_node)
|
661
|
+
|
662
|
+
# Update the tokens.
|
663
|
+
var_tokens = list(tokenize.generate_tokens(
|
664
|
+
cStringIO.StringIO(var_content).readline))
|
665
|
+
var_tokens = {
|
666
|
+
token[2]: list(token)
|
667
|
+
# Ignore the tokens corresponding to braces and new lines.
|
668
|
+
for token in var_tokens[2:-2]
|
669
|
+
}
|
670
|
+
|
671
|
+
gclient_dict.tokens = _ShiftLinesInTokens(gclient_dict.tokens, 1, line)
|
672
|
+
gclient_dict.tokens.update(_ShiftLinesInTokens(var_tokens, line - 2, 0))
|
673
|
+
|
674
|
+
|
675
|
+
def SetVar(gclient_dict, var_name, value):
|
676
|
+
if not isinstance(gclient_dict, _NodeDict) or gclient_dict.tokens is None:
|
677
|
+
raise ValueError(
|
678
|
+
"Can't use SetVar for the given gclient dict. It contains no "
|
679
|
+
"formatting information.")
|
680
|
+
tokens = gclient_dict.tokens
|
681
|
+
|
682
|
+
if 'vars' not in gclient_dict:
|
683
|
+
raise KeyError("vars dict is not defined.")
|
684
|
+
|
685
|
+
if var_name not in gclient_dict['vars']:
|
686
|
+
raise ValueError(
|
687
|
+
"%s has not been declared in the vars dict. Consider using AddVar "
|
688
|
+
"instead." % var_name)
|
689
|
+
|
690
|
+
node = gclient_dict['vars'].GetNode(var_name)
|
691
|
+
if node is None:
|
692
|
+
raise ValueError(
|
693
|
+
"The vars entry for %s has no formatting information." % var_name)
|
694
|
+
|
695
|
+
_UpdateAstString(tokens, node, value)
|
696
|
+
gclient_dict['vars'].SetNode(var_name, value, node)
|
697
|
+
|
698
|
+
|
699
|
+
def SetCIPD(gclient_dict, dep_name, package_name, new_version):
|
700
|
+
if not isinstance(gclient_dict, _NodeDict) or gclient_dict.tokens is None:
|
701
|
+
raise ValueError(
|
702
|
+
"Can't use SetCIPD for the given gclient dict. It contains no "
|
703
|
+
"formatting information.")
|
704
|
+
tokens = gclient_dict.tokens
|
705
|
+
|
706
|
+
if 'deps' not in gclient_dict or dep_name not in gclient_dict['deps']:
|
707
|
+
raise KeyError(
|
708
|
+
"Could not find any dependency called %s." % dep_name)
|
709
|
+
|
710
|
+
# Find the package with the given name
|
711
|
+
packages = [
|
712
|
+
package
|
713
|
+
for package in gclient_dict['deps'][dep_name]['packages']
|
714
|
+
if package['package'] == package_name
|
715
|
+
]
|
716
|
+
if len(packages) != 1:
|
717
|
+
raise ValueError(
|
718
|
+
"There must be exactly one package with the given name (%s), "
|
719
|
+
"%s were found." % (package_name, len(packages)))
|
720
|
+
|
721
|
+
# TODO(ehmaldonado): Support Var in package's version.
|
722
|
+
node = packages[0].GetNode('version')
|
723
|
+
if node is None:
|
724
|
+
raise ValueError(
|
725
|
+
"The deps entry for %s:%s has no formatting information." %
|
726
|
+
(dep_name, package_name))
|
727
|
+
|
728
|
+
new_version = 'version:' + new_version
|
729
|
+
_UpdateAstString(tokens, node, new_version)
|
730
|
+
packages[0].SetNode('version', new_version, node)
|
731
|
+
|
732
|
+
|
733
|
+
def SetRevision(gclient_dict, dep_name, new_revision):
|
734
|
+
def _GetVarName(node):
|
735
|
+
if isinstance(node, ast.Call):
|
736
|
+
return node.args[0].s
|
737
|
+
elif node.s.endswith('}'):
|
738
|
+
last_brace = node.s.rfind('{')
|
739
|
+
return node.s[last_brace+1:-1]
|
740
|
+
return None
|
741
|
+
|
742
|
+
def _UpdateRevision(dep_dict, dep_key, new_revision):
|
743
|
+
dep_node = dep_dict.GetNode(dep_key)
|
744
|
+
if dep_node is None:
|
745
|
+
raise ValueError(
|
746
|
+
"The deps entry for %s has no formatting information." % dep_name)
|
747
|
+
|
748
|
+
node = dep_node
|
749
|
+
if isinstance(node, ast.BinOp):
|
750
|
+
node = node.right
|
751
|
+
|
752
|
+
if not isinstance(node, ast.Call) and not isinstance(node, ast.Str):
|
753
|
+
raise ValueError(
|
754
|
+
"Unsupported dependency revision format. Please file a bug.")
|
755
|
+
|
756
|
+
var_name = _GetVarName(node)
|
757
|
+
if var_name is not None:
|
758
|
+
SetVar(gclient_dict, var_name, new_revision)
|
759
|
+
else:
|
760
|
+
if '@' in node.s:
|
761
|
+
# '@' is part of the last string, which we want to modify. Discard
|
762
|
+
# whatever was after the '@' and put the new revision in its place.
|
763
|
+
new_revision = node.s.split('@')[0] + '@' + new_revision
|
764
|
+
elif '@' not in dep_dict[dep_key]:
|
765
|
+
# '@' is not part of the URL at all. This mean the dependency is
|
766
|
+
# unpinned and we should pin it.
|
767
|
+
new_revision = node.s + '@' + new_revision
|
768
|
+
_UpdateAstString(tokens, node, new_revision)
|
769
|
+
dep_dict.SetNode(dep_key, new_revision, node)
|
770
|
+
|
771
|
+
if not isinstance(gclient_dict, _NodeDict) or gclient_dict.tokens is None:
|
772
|
+
raise ValueError(
|
773
|
+
"Can't use SetRevision for the given gclient dict. It contains no "
|
774
|
+
"formatting information.")
|
775
|
+
tokens = gclient_dict.tokens
|
776
|
+
|
777
|
+
if 'deps' not in gclient_dict or dep_name not in gclient_dict['deps']:
|
778
|
+
raise KeyError(
|
779
|
+
"Could not find any dependency called %s." % dep_name)
|
780
|
+
|
781
|
+
if isinstance(gclient_dict['deps'][dep_name], _NodeDict):
|
782
|
+
_UpdateRevision(gclient_dict['deps'][dep_name], 'url', new_revision)
|
783
|
+
else:
|
784
|
+
_UpdateRevision(gclient_dict['deps'], dep_name, new_revision)
|
785
|
+
|
786
|
+
|
787
|
+
def GetVar(gclient_dict, var_name):
|
788
|
+
if 'vars' not in gclient_dict or var_name not in gclient_dict['vars']:
|
789
|
+
raise KeyError(
|
790
|
+
"Could not find any variable called %s." % var_name)
|
791
|
+
|
792
|
+
return gclient_dict['vars'][var_name]
|
793
|
+
|
794
|
+
|
795
|
+
def GetCIPD(gclient_dict, dep_name, package_name):
|
796
|
+
if 'deps' not in gclient_dict or dep_name not in gclient_dict['deps']:
|
797
|
+
raise KeyError(
|
798
|
+
"Could not find any dependency called %s." % dep_name)
|
799
|
+
|
800
|
+
# Find the package with the given name
|
801
|
+
packages = [
|
802
|
+
package
|
803
|
+
for package in gclient_dict['deps'][dep_name]['packages']
|
804
|
+
if package['package'] == package_name
|
805
|
+
]
|
806
|
+
if len(packages) != 1:
|
807
|
+
raise ValueError(
|
808
|
+
"There must be exactly one package with the given name (%s), "
|
809
|
+
"%s were found." % (package_name, len(packages)))
|
810
|
+
|
811
|
+
return packages[0]['version'][len('version:'):]
|
812
|
+
|
813
|
+
|
814
|
+
def GetRevision(gclient_dict, dep_name):
|
815
|
+
if 'deps' not in gclient_dict or dep_name not in gclient_dict['deps']:
|
816
|
+
raise KeyError(
|
817
|
+
"Could not find any dependency called %s." % dep_name)
|
818
|
+
|
819
|
+
dep = gclient_dict['deps'][dep_name]
|
820
|
+
if dep is None:
|
821
|
+
return None
|
822
|
+
elif isinstance(dep, basestring):
|
823
|
+
_, _, revision = dep.partition('@')
|
824
|
+
return revision or None
|
825
|
+
elif isinstance(dep, collections.Mapping) and 'url' in dep:
|
826
|
+
_, _, revision = dep['url'].partition('@')
|
827
|
+
return revision or None
|
828
|
+
else:
|
829
|
+
raise ValueError(
|
830
|
+
'%s is not a valid git dependency.' % dep_name)
|