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
@@ -6,13 +6,17 @@
|
|
6
6
|
|
7
7
|
from __future__ import print_function
|
8
8
|
|
9
|
+
import collections
|
10
|
+
import contextlib
|
9
11
|
import errno
|
12
|
+
import json
|
10
13
|
import logging
|
11
14
|
import os
|
12
15
|
import posixpath
|
13
16
|
import re
|
14
17
|
import sys
|
15
18
|
import tempfile
|
19
|
+
import threading
|
16
20
|
import traceback
|
17
21
|
import urlparse
|
18
22
|
|
@@ -81,37 +85,6 @@ class GitDiffFilterer(DiffFiltererWrapper):
|
|
81
85
|
return re.sub("[a|b]/" + self._current_file, self._replacement_file, line)
|
82
86
|
|
83
87
|
|
84
|
-
### SCM abstraction layer
|
85
|
-
|
86
|
-
# Factory Method for SCM wrapper creation
|
87
|
-
|
88
|
-
def GetScmName(url):
|
89
|
-
if not url:
|
90
|
-
return None
|
91
|
-
url, _ = gclient_utils.SplitUrlRevision(url)
|
92
|
-
if url.endswith('.git'):
|
93
|
-
return 'git'
|
94
|
-
protocol = url.split('://')[0]
|
95
|
-
if protocol in (
|
96
|
-
'file', 'git', 'git+http', 'git+https', 'http', 'https', 'ssh', 'sso'):
|
97
|
-
return 'git'
|
98
|
-
return None
|
99
|
-
|
100
|
-
|
101
|
-
def CreateSCM(url, root_dir=None, relpath=None, out_fh=None, out_cb=None):
|
102
|
-
SCM_MAP = {
|
103
|
-
'git' : GitWrapper,
|
104
|
-
}
|
105
|
-
|
106
|
-
scm_name = GetScmName(url)
|
107
|
-
if not scm_name in SCM_MAP:
|
108
|
-
raise gclient_utils.Error('No SCM found for url %s' % url)
|
109
|
-
scm_class = SCM_MAP[scm_name]
|
110
|
-
if not scm_class.BinaryExists():
|
111
|
-
raise gclient_utils.Error('%s command not found' % scm_name)
|
112
|
-
return scm_class(url, root_dir, relpath, out_fh, out_cb)
|
113
|
-
|
114
|
-
|
115
88
|
# SCMWrapper base class
|
116
89
|
|
117
90
|
class SCMWrapper(object):
|
@@ -121,7 +94,7 @@ class SCMWrapper(object):
|
|
121
94
|
"""
|
122
95
|
|
123
96
|
def __init__(self, url=None, root_dir=None, relpath=None, out_fh=None,
|
124
|
-
out_cb=None):
|
97
|
+
out_cb=None, print_outbuf=False):
|
125
98
|
self.url = url
|
126
99
|
self._root_dir = root_dir
|
127
100
|
if self._root_dir:
|
@@ -135,6 +108,7 @@ class SCMWrapper(object):
|
|
135
108
|
out_fh = sys.stdout
|
136
109
|
self.out_fh = out_fh
|
137
110
|
self.out_cb = out_cb
|
111
|
+
self.print_outbuf = print_outbuf
|
138
112
|
|
139
113
|
def Print(self, *args, **kwargs):
|
140
114
|
kwargs.setdefault('file', self.out_fh)
|
@@ -238,11 +212,11 @@ class GitWrapper(SCMWrapper):
|
|
238
212
|
|
239
213
|
cache_dir = None
|
240
214
|
|
241
|
-
def __init__(self, url=None, *args):
|
215
|
+
def __init__(self, url=None, *args, **kwargs):
|
242
216
|
"""Removes 'git+' fake prefix from git URL."""
|
243
217
|
if url.startswith('git+http://') or url.startswith('git+https://'):
|
244
218
|
url = url[4:]
|
245
|
-
SCMWrapper.__init__(self, url, *args)
|
219
|
+
SCMWrapper.__init__(self, url, *args, **kwargs)
|
246
220
|
filter_kwargs = { 'time_throttle': 1, 'out_fh': self.out_fh }
|
247
221
|
if self.out_cb:
|
248
222
|
filter_kwargs['predicate'] = self.out_cb
|
@@ -278,11 +252,10 @@ class GitWrapper(SCMWrapper):
|
|
278
252
|
).split()
|
279
253
|
|
280
254
|
def diff(self, options, _args, _file_list):
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
self._Run(['-c', 'core.quotePath=false', 'diff'] + merge_base, options)
|
255
|
+
_, revision = gclient_utils.SplitUrlRevision(self.url)
|
256
|
+
if not revision:
|
257
|
+
revision = 'refs/remotes/%s/master' % self.remote
|
258
|
+
self._Run(['-c', 'core.quotePath=false', 'diff', revision], options)
|
286
259
|
|
287
260
|
def pack(self, _options, _args, _file_list):
|
288
261
|
"""Generates a patch file which can be applied to the root of the
|
@@ -367,6 +340,32 @@ class GitWrapper(SCMWrapper):
|
|
367
340
|
self.Print('FAILED to break lock: %s: %s' % (to_break, ex))
|
368
341
|
raise
|
369
342
|
|
343
|
+
def apply_patch_ref(self, patch_repo, patch_ref, options, file_list):
|
344
|
+
base_rev = self._Capture(['rev-parse', 'HEAD'])
|
345
|
+
self.Print('===Applying patch ref===')
|
346
|
+
self.Print('Repo is %r @ %r, ref is %r, root is %r' % (
|
347
|
+
patch_repo, patch_ref, base_rev, self.checkout_path))
|
348
|
+
self._Capture(['reset', '--hard'])
|
349
|
+
self._Capture(['fetch', patch_repo, patch_ref])
|
350
|
+
if file_list is not None:
|
351
|
+
file_list.extend(self._GetDiffFilenames('FETCH_HEAD'))
|
352
|
+
self._Capture(['checkout', 'FETCH_HEAD'])
|
353
|
+
|
354
|
+
if options.rebase_patch_ref:
|
355
|
+
try:
|
356
|
+
# TODO(ehmaldonado): Look into cherry-picking to avoid an expensive
|
357
|
+
# checkout + rebase.
|
358
|
+
self._Capture(['rebase', base_rev])
|
359
|
+
except subprocess2.CalledProcessError as e:
|
360
|
+
self.Print('Failed to apply %r @ %r to %r at %r' % (
|
361
|
+
patch_repo, patch_ref, base_rev, self.checkout_path))
|
362
|
+
self.Print('git returned non-zero exit status %s:\n%s' % (
|
363
|
+
e.returncode, e.stderr))
|
364
|
+
self._Capture(['rebase', '--abort'])
|
365
|
+
raise
|
366
|
+
if options.reset_patch_ref:
|
367
|
+
self._Capture(['reset', '--soft', base_rev])
|
368
|
+
|
370
369
|
def update(self, options, args, file_list):
|
371
370
|
"""Runs git to update or transparently checkout the working copy.
|
372
371
|
|
@@ -825,12 +824,6 @@ class GitWrapper(SCMWrapper):
|
|
825
824
|
|
826
825
|
return sha1
|
827
826
|
|
828
|
-
def FullUrlForRelativeUrl(self, url):
|
829
|
-
# Strip from last '/'
|
830
|
-
# Equivalent to unix basename
|
831
|
-
base_url = self.url
|
832
|
-
return base_url[:base_url.rfind('/')] + url
|
833
|
-
|
834
827
|
def GetGitBackupDirPath(self):
|
835
828
|
"""Returns the path where the .git folder for the current project can be
|
836
829
|
staged/restored. Use case: subproject moved from DEPS <-> outer project."""
|
@@ -923,7 +916,14 @@ class GitWrapper(SCMWrapper):
|
|
923
916
|
dir=parent_dir)
|
924
917
|
try:
|
925
918
|
clone_cmd.append(tmp_dir)
|
926
|
-
|
919
|
+
if self.print_outbuf:
|
920
|
+
print_stdout = True
|
921
|
+
stdout = gclient_utils.WriteToStdout(self.out_fh)
|
922
|
+
else:
|
923
|
+
print_stdout = False
|
924
|
+
stdout = self.out_fh
|
925
|
+
self._Run(clone_cmd, options, cwd=self._root_dir, retry=True,
|
926
|
+
print_stdout=print_stdout, stdout=stdout)
|
927
927
|
gclient_utils.safe_makedirs(self.checkout_path)
|
928
928
|
gclient_utils.safe_rename(os.path.join(tmp_dir, '.git'),
|
929
929
|
os.path.join(self.checkout_path, '.git'))
|
@@ -1230,3 +1230,215 @@ class GitWrapper(SCMWrapper):
|
|
1230
1230
|
gclient_utils.CheckCallAndFilterAndHeader(cmd, env=env, **kwargs)
|
1231
1231
|
else:
|
1232
1232
|
gclient_utils.CheckCallAndFilter(cmd, env=env, **kwargs)
|
1233
|
+
|
1234
|
+
|
1235
|
+
class CipdPackage(object):
|
1236
|
+
"""A representation of a single CIPD package."""
|
1237
|
+
|
1238
|
+
def __init__(self, name, version, authority_for_subdir):
|
1239
|
+
self._authority_for_subdir = authority_for_subdir
|
1240
|
+
self._name = name
|
1241
|
+
self._version = version
|
1242
|
+
|
1243
|
+
@property
|
1244
|
+
def authority_for_subdir(self):
|
1245
|
+
"""Whether this package has authority to act on behalf of its subdir.
|
1246
|
+
|
1247
|
+
Some operations should only be performed once per subdirectory. A package
|
1248
|
+
that has authority for its subdirectory is the only package that should
|
1249
|
+
perform such operations.
|
1250
|
+
|
1251
|
+
Returns:
|
1252
|
+
bool; whether this package has subdir authority.
|
1253
|
+
"""
|
1254
|
+
return self._authority_for_subdir
|
1255
|
+
|
1256
|
+
@property
|
1257
|
+
def name(self):
|
1258
|
+
return self._name
|
1259
|
+
|
1260
|
+
@property
|
1261
|
+
def version(self):
|
1262
|
+
return self._version
|
1263
|
+
|
1264
|
+
|
1265
|
+
class CipdRoot(object):
|
1266
|
+
"""A representation of a single CIPD root."""
|
1267
|
+
def __init__(self, root_dir, service_url):
|
1268
|
+
self._all_packages = set()
|
1269
|
+
self._mutator_lock = threading.Lock()
|
1270
|
+
self._packages_by_subdir = collections.defaultdict(list)
|
1271
|
+
self._root_dir = root_dir
|
1272
|
+
self._service_url = service_url
|
1273
|
+
|
1274
|
+
def add_package(self, subdir, package, version):
|
1275
|
+
"""Adds a package to this CIPD root.
|
1276
|
+
|
1277
|
+
As far as clients are concerned, this grants both root and subdir authority
|
1278
|
+
to packages arbitrarily. (The implementation grants root authority to the
|
1279
|
+
first package added and subdir authority to the first package added for that
|
1280
|
+
subdir, but clients should not depend on or expect that behavior.)
|
1281
|
+
|
1282
|
+
Args:
|
1283
|
+
subdir: str; relative path to where the package should be installed from
|
1284
|
+
the cipd root directory.
|
1285
|
+
package: str; the cipd package name.
|
1286
|
+
version: str; the cipd package version.
|
1287
|
+
Returns:
|
1288
|
+
CipdPackage; the package that was created and added to this root.
|
1289
|
+
"""
|
1290
|
+
with self._mutator_lock:
|
1291
|
+
cipd_package = CipdPackage(
|
1292
|
+
package, version,
|
1293
|
+
not self._packages_by_subdir[subdir])
|
1294
|
+
self._all_packages.add(cipd_package)
|
1295
|
+
self._packages_by_subdir[subdir].append(cipd_package)
|
1296
|
+
return cipd_package
|
1297
|
+
|
1298
|
+
def packages(self, subdir):
|
1299
|
+
"""Get the list of configured packages for the given subdir."""
|
1300
|
+
return list(self._packages_by_subdir[subdir])
|
1301
|
+
|
1302
|
+
def clobber(self):
|
1303
|
+
"""Remove the .cipd directory.
|
1304
|
+
|
1305
|
+
This is useful for forcing ensure to redownload and reinitialize all
|
1306
|
+
packages.
|
1307
|
+
"""
|
1308
|
+
with self._mutator_lock:
|
1309
|
+
cipd_cache_dir = os.path.join(self.root_dir, '.cipd')
|
1310
|
+
try:
|
1311
|
+
gclient_utils.rmtree(os.path.join(cipd_cache_dir))
|
1312
|
+
except OSError:
|
1313
|
+
if os.path.exists(cipd_cache_dir):
|
1314
|
+
raise
|
1315
|
+
|
1316
|
+
@contextlib.contextmanager
|
1317
|
+
def _create_ensure_file(self):
|
1318
|
+
try:
|
1319
|
+
ensure_file = None
|
1320
|
+
with tempfile.NamedTemporaryFile(
|
1321
|
+
suffix='.ensure', delete=False) as ensure_file:
|
1322
|
+
for subdir, packages in sorted(self._packages_by_subdir.iteritems()):
|
1323
|
+
ensure_file.write('@Subdir %s\n' % subdir)
|
1324
|
+
for package in sorted(packages, key=lambda p: p.name):
|
1325
|
+
ensure_file.write('%s %s\n' % (package.name, package.version))
|
1326
|
+
ensure_file.write('\n')
|
1327
|
+
yield ensure_file.name
|
1328
|
+
finally:
|
1329
|
+
if ensure_file is not None and os.path.exists(ensure_file.name):
|
1330
|
+
os.remove(ensure_file.name)
|
1331
|
+
|
1332
|
+
def ensure(self):
|
1333
|
+
"""Run `cipd ensure`."""
|
1334
|
+
with self._mutator_lock:
|
1335
|
+
with self._create_ensure_file() as ensure_file:
|
1336
|
+
cmd = [
|
1337
|
+
'cipd', 'ensure',
|
1338
|
+
'-log-level', 'error',
|
1339
|
+
'-root', self.root_dir,
|
1340
|
+
'-ensure-file', ensure_file,
|
1341
|
+
]
|
1342
|
+
gclient_utils.CheckCallAndFilterAndHeader(cmd)
|
1343
|
+
|
1344
|
+
def run(self, command):
|
1345
|
+
if command == 'update':
|
1346
|
+
self.ensure()
|
1347
|
+
elif command == 'revert':
|
1348
|
+
self.clobber()
|
1349
|
+
self.ensure()
|
1350
|
+
|
1351
|
+
def created_package(self, package):
|
1352
|
+
"""Checks whether this root created the given package.
|
1353
|
+
|
1354
|
+
Args:
|
1355
|
+
package: CipdPackage; the package to check.
|
1356
|
+
Returns:
|
1357
|
+
bool; whether this root created the given package.
|
1358
|
+
"""
|
1359
|
+
return package in self._all_packages
|
1360
|
+
|
1361
|
+
@property
|
1362
|
+
def root_dir(self):
|
1363
|
+
return self._root_dir
|
1364
|
+
|
1365
|
+
@property
|
1366
|
+
def service_url(self):
|
1367
|
+
return self._service_url
|
1368
|
+
|
1369
|
+
|
1370
|
+
class CipdWrapper(SCMWrapper):
|
1371
|
+
"""Wrapper for CIPD.
|
1372
|
+
|
1373
|
+
Currently only supports chrome-infra-packages.appspot.com.
|
1374
|
+
"""
|
1375
|
+
name = 'cipd'
|
1376
|
+
|
1377
|
+
def __init__(self, url=None, root_dir=None, relpath=None, out_fh=None,
|
1378
|
+
out_cb=None, root=None, package=None):
|
1379
|
+
super(CipdWrapper, self).__init__(
|
1380
|
+
url=url, root_dir=root_dir, relpath=relpath, out_fh=out_fh,
|
1381
|
+
out_cb=out_cb)
|
1382
|
+
assert root.created_package(package)
|
1383
|
+
self._package = package
|
1384
|
+
self._root = root
|
1385
|
+
|
1386
|
+
#override
|
1387
|
+
def GetCacheMirror(self):
|
1388
|
+
return None
|
1389
|
+
|
1390
|
+
#override
|
1391
|
+
def GetActualRemoteURL(self, options):
|
1392
|
+
return self._root.service_url
|
1393
|
+
|
1394
|
+
#override
|
1395
|
+
def DoesRemoteURLMatch(self, options):
|
1396
|
+
del options
|
1397
|
+
return True
|
1398
|
+
|
1399
|
+
def revert(self, options, args, file_list):
|
1400
|
+
"""Does nothing.
|
1401
|
+
|
1402
|
+
CIPD packages should be reverted at the root by running
|
1403
|
+
`CipdRoot.run('revert')`.
|
1404
|
+
"""
|
1405
|
+
pass
|
1406
|
+
|
1407
|
+
def diff(self, options, args, file_list):
|
1408
|
+
"""CIPD has no notion of diffing."""
|
1409
|
+
pass
|
1410
|
+
|
1411
|
+
def pack(self, options, args, file_list):
|
1412
|
+
"""CIPD has no notion of diffing."""
|
1413
|
+
pass
|
1414
|
+
|
1415
|
+
def revinfo(self, options, args, file_list):
|
1416
|
+
"""Grab the instance ID."""
|
1417
|
+
try:
|
1418
|
+
tmpdir = tempfile.mkdtemp()
|
1419
|
+
describe_json_path = os.path.join(tmpdir, 'describe.json')
|
1420
|
+
cmd = [
|
1421
|
+
'cipd', 'describe',
|
1422
|
+
self._package.name,
|
1423
|
+
'-log-level', 'error',
|
1424
|
+
'-version', self._package.version,
|
1425
|
+
'-json-output', describe_json_path
|
1426
|
+
]
|
1427
|
+
gclient_utils.CheckCallAndFilter(
|
1428
|
+
cmd, filter_fn=lambda _line: None, print_stdout=False)
|
1429
|
+
with open(describe_json_path) as f:
|
1430
|
+
describe_json = json.load(f)
|
1431
|
+
return describe_json.get('result', {}).get('pin', {}).get('instance_id')
|
1432
|
+
finally:
|
1433
|
+
gclient_utils.rmtree(tmpdir)
|
1434
|
+
|
1435
|
+
def status(self, options, args, file_list):
|
1436
|
+
pass
|
1437
|
+
|
1438
|
+
def update(self, options, args, file_list):
|
1439
|
+
"""Does nothing.
|
1440
|
+
|
1441
|
+
CIPD packages should be updated at the root by running
|
1442
|
+
`CipdRoot.run('update')`.
|
1443
|
+
"""
|
1444
|
+
pass
|
@@ -325,6 +325,22 @@ class Wrapper(object):
|
|
325
325
|
return getattr(self._wrapped, name)
|
326
326
|
|
327
327
|
|
328
|
+
class WriteToStdout(Wrapper):
|
329
|
+
"""Creates a file object clone to also print to sys.stdout."""
|
330
|
+
def __init__(self, wrapped):
|
331
|
+
super(WriteToStdout, self).__init__(wrapped)
|
332
|
+
if not hasattr(self, 'lock'):
|
333
|
+
self.lock = threading.Lock()
|
334
|
+
|
335
|
+
def write(self, out, *args, **kwargs):
|
336
|
+
self._wrapped.write(out, *args, **kwargs)
|
337
|
+
self.lock.acquire()
|
338
|
+
try:
|
339
|
+
sys.stdout.write(out, *args, **kwargs)
|
340
|
+
finally:
|
341
|
+
self.lock.release()
|
342
|
+
|
343
|
+
|
328
344
|
class AutoFlush(Wrapper):
|
329
345
|
"""Creates a file object clone to automatically flush after N seconds."""
|
330
346
|
def __init__(self, wrapped, delay):
|
@@ -1262,7 +1278,7 @@ def freeze(obj):
|
|
1262
1278
|
|
1263
1279
|
Will raise TypeError if you pass an object which is not hashable.
|
1264
1280
|
"""
|
1265
|
-
if isinstance(obj,
|
1281
|
+
if isinstance(obj, collections.Mapping):
|
1266
1282
|
return FrozenDict((freeze(k), freeze(v)) for k, v in obj.iteritems())
|
1267
1283
|
elif isinstance(obj, (list, tuple)):
|
1268
1284
|
return tuple(freeze(i) for i in obj)
|
@@ -26,7 +26,9 @@ import urllib
|
|
26
26
|
import urlparse
|
27
27
|
from cStringIO import StringIO
|
28
28
|
|
29
|
+
import auth
|
29
30
|
import gclient_utils
|
31
|
+
import subprocess2
|
30
32
|
from third_party import httplib2
|
31
33
|
|
32
34
|
LOGGER = logging.getLogger()
|
@@ -85,6 +87,10 @@ class Authenticator(object):
|
|
85
87
|
Probes the local system and its environment and identifies the
|
86
88
|
Authenticator instance to use.
|
87
89
|
"""
|
90
|
+
# LUCI Context takes priority since it's normally present only on bots,
|
91
|
+
# which then must use it.
|
92
|
+
if LuciContextAuthenticator.is_luci():
|
93
|
+
return LuciContextAuthenticator()
|
88
94
|
if GceAuthenticator.is_gce():
|
89
95
|
return GceAuthenticator()
|
90
96
|
return CookiesAuthenticator()
|
@@ -166,7 +172,11 @@ class CookiesAuthenticator(Authenticator):
|
|
166
172
|
def get_gitcookies_path(cls):
|
167
173
|
if os.getenv('GIT_COOKIES_PATH'):
|
168
174
|
return os.getenv('GIT_COOKIES_PATH')
|
169
|
-
|
175
|
+
try:
|
176
|
+
return subprocess2.check_output(
|
177
|
+
['git', 'config', '--path', 'http.cookiefile']).strip()
|
178
|
+
except subprocess2.CalledProcessError:
|
179
|
+
return os.path.join(os.environ['HOME'], '.gitcookies')
|
170
180
|
|
171
181
|
@classmethod
|
172
182
|
def _get_gitcookies(cls):
|
@@ -202,17 +212,17 @@ class CookiesAuthenticator(Authenticator):
|
|
202
212
|
return self.netrc.authenticators(host)
|
203
213
|
|
204
214
|
def get_auth_header(self, host):
|
205
|
-
|
206
|
-
if
|
207
|
-
return 'Basic %s' % (base64.b64encode('%s:%s' % (
|
215
|
+
a = self._get_auth_for_host(host)
|
216
|
+
if a:
|
217
|
+
return 'Basic %s' % (base64.b64encode('%s:%s' % (a[0], a[2])))
|
208
218
|
return None
|
209
219
|
|
210
220
|
def get_auth_email(self, host):
|
211
221
|
"""Best effort parsing of email to be used for auth for the given host."""
|
212
|
-
|
213
|
-
if not
|
222
|
+
a = self._get_auth_for_host(host)
|
223
|
+
if not a:
|
214
224
|
return None
|
215
|
-
login =
|
225
|
+
login = a[0]
|
216
226
|
# login typically looks like 'git-xxx.example.com'
|
217
227
|
if not login.startswith('git-') or '.' not in login:
|
218
228
|
return None
|
@@ -251,7 +261,8 @@ class GceAuthenticator(Authenticator):
|
|
251
261
|
# Based on https://cloud.google.com/compute/docs/metadata#runninggce
|
252
262
|
try:
|
253
263
|
resp, _ = cls._get(cls._INFO_URL)
|
254
|
-
except (socket.error, httplib2.ServerNotFoundError
|
264
|
+
except (socket.error, httplib2.ServerNotFoundError,
|
265
|
+
httplib2.socks.HTTPError):
|
255
266
|
# Could not resolve URL.
|
256
267
|
return False
|
257
268
|
return resp.get('metadata-flavor') == 'Google'
|
@@ -297,14 +308,36 @@ class GceAuthenticator(Authenticator):
|
|
297
308
|
return '%(token_type)s %(access_token)s' % token_dict
|
298
309
|
|
299
310
|
|
311
|
+
class LuciContextAuthenticator(Authenticator):
|
312
|
+
"""Authenticator implementation that uses LUCI_CONTEXT ambient local auth.
|
313
|
+
"""
|
314
|
+
|
315
|
+
@staticmethod
|
316
|
+
def is_luci():
|
317
|
+
return auth.has_luci_context_local_auth()
|
318
|
+
|
319
|
+
def __init__(self):
|
320
|
+
self._access_token = None
|
321
|
+
self._ensure_fresh()
|
322
|
+
|
323
|
+
def _ensure_fresh(self):
|
324
|
+
if not self._access_token or self._access_token.needs_refresh():
|
325
|
+
self._access_token = auth.get_luci_context_access_token(
|
326
|
+
scopes=' '.join([auth.OAUTH_SCOPE_EMAIL, auth.OAUTH_SCOPE_GERRIT]))
|
327
|
+
|
328
|
+
def get_auth_header(self, _host):
|
329
|
+
self._ensure_fresh()
|
330
|
+
return 'Bearer %s' % self._access_token.token
|
331
|
+
|
332
|
+
|
300
333
|
def CreateHttpConn(host, path, reqtype='GET', headers=None, body=None):
|
301
334
|
"""Opens an https connection to a gerrit service, and sends a request."""
|
302
335
|
headers = headers or {}
|
303
336
|
bare_host = host.partition(':')[0]
|
304
337
|
|
305
|
-
|
306
|
-
if
|
307
|
-
headers.setdefault('Authorization',
|
338
|
+
a = Authenticator.get().get_auth_header(bare_host)
|
339
|
+
if a:
|
340
|
+
headers.setdefault('Authorization', a)
|
308
341
|
else:
|
309
342
|
LOGGER.debug('No authorization found for %s.' % bare_host)
|
310
343
|
|
@@ -360,9 +393,9 @@ def ReadHttpResponse(conn, accept_statuses=frozenset([200])):
|
|
360
393
|
raise GerritAuthenticationError(response.status, reason)
|
361
394
|
|
362
395
|
# If response.status < 500 then the result is final; break retry loop.
|
363
|
-
# If the response is 404, it might be because of replication lag, so
|
396
|
+
# If the response is 404/409, it might be because of replication lag, so
|
364
397
|
# keep trying anyway.
|
365
|
-
if ((response.status < 500 and response.status
|
398
|
+
if ((response.status < 500 and response.status not in [404, 409])
|
366
399
|
or response.status in accept_statuses):
|
367
400
|
LOGGER.debug('got response %d for %s %s', response.status,
|
368
401
|
conn.req_params['method'], conn.req_params['uri'])
|