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
data/spec/spec_helper.rb
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
/gsutil.vpython recipes
|
14
14
|
|
15
15
|
# Extensionless tools we want and support scripts.
|
16
|
-
/apply_issue recipes
|
17
16
|
/clang* recipes
|
18
17
|
/depot-tools-auth recipes
|
19
18
|
/download_from_google_storage recipes
|
@@ -25,6 +24,7 @@
|
|
25
24
|
/pylint* recipes
|
26
25
|
/repo recipes
|
27
26
|
/roll-dep* recipes
|
27
|
+
/yapf* recipes
|
28
28
|
|
29
29
|
# Symlinks
|
30
30
|
/cbuildbot recipes
|
@@ -37,7 +37,6 @@
|
|
37
37
|
# move to vpython/cipd.
|
38
38
|
/third_party/** recipes
|
39
39
|
/third_party/pymox/** -recipes
|
40
|
-
/third_party/cq_client/testdata/** -recipes
|
41
40
|
|
42
41
|
/win_toolchain/** recipes
|
43
42
|
|
data/vendor/depot_tools/OWNERS
CHANGED
@@ -12,11 +12,13 @@ import fnmatch
|
|
12
12
|
import os
|
13
13
|
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
$VerifiedPlatform mac-amd64
|
19
|
-
|
15
|
+
# CIPD ensure manifest for checking CIPD client itself.
|
16
|
+
CIPD_CLIENT_ENSURE_FILE_TEMPLATE = r'''
|
17
|
+
# Full supported.
|
18
|
+
$VerifiedPlatform linux-amd64 mac-amd64 windows-amd64 windows-386
|
19
|
+
# Best effort support.
|
20
|
+
$VerifiedPlatform linux-386 linux-ppc64 linux-ppc64le linux-s390x
|
21
|
+
$VerifiedPlatform linux-arm64 linux-armv6l linux-mips64
|
20
22
|
|
21
23
|
%s %s
|
22
24
|
'''
|
@@ -56,6 +58,8 @@ def DepotToolsPylint(input_api, output_api):
|
|
56
58
|
def CommonChecks(input_api, output_api, tests_to_black_list):
|
57
59
|
results = []
|
58
60
|
results.extend(input_api.canned_checks.CheckOwners(input_api, output_api))
|
61
|
+
results.extend(input_api.canned_checks.CheckOwnersFormat(
|
62
|
+
input_api, output_api))
|
59
63
|
# TODO(maruel): Make sure at least one file is modified first.
|
60
64
|
# TODO(maruel): If only tests are modified, only run them.
|
61
65
|
tests = DepotToolsPylint(input_api, output_api)
|
@@ -95,7 +99,8 @@ def CommonChecks(input_api, output_api, tests_to_black_list):
|
|
95
99
|
pkg = 'infra/tools/cipd/${platform}'
|
96
100
|
ver = input_api.ReadFile(path)
|
97
101
|
tests.append(input_api.canned_checks.CheckCIPDManifest(
|
98
|
-
input_api, output_api,
|
102
|
+
input_api, output_api,
|
103
|
+
content=CIPD_CLIENT_ENSURE_FILE_TEMPLATE % (pkg, ver)))
|
99
104
|
|
100
105
|
results.extend(input_api.RunTests(tests))
|
101
106
|
return results
|
@@ -8,9 +8,6 @@
|
|
8
8
|
{
|
9
9
|
|
10
10
|
'WATCHLIST_DEFINITIONS': {
|
11
|
-
'git_cl.py': {
|
12
|
-
'filepath': 'git_cl.py',
|
13
|
-
},
|
14
11
|
'this_file': {
|
15
12
|
'filepath': '^WATCHLISTS$',
|
16
13
|
},
|
@@ -21,9 +18,6 @@
|
|
21
18
|
|
22
19
|
'WATCHLISTS': {
|
23
20
|
'this_file': [],
|
24
|
-
'git_cl.py': [
|
25
|
-
'tandrii+omg_git_cl@chromium.org',
|
26
|
-
],
|
27
21
|
'depot_tools': [
|
28
22
|
'iannucci+depot_tools@chromium.org',
|
29
23
|
],
|
data/vendor/depot_tools/auth.py
CHANGED
@@ -45,14 +45,12 @@ OAUTH_CLIENT_ID = (
|
|
45
45
|
'446450136466-2hr92jrq8e6i4tnsa56b52vacp7t3936.apps.googleusercontent.com')
|
46
46
|
OAUTH_CLIENT_SECRET = 'uBfbay2KCy9t4QveJ-dOqHtp'
|
47
47
|
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
#
|
53
|
-
|
54
|
-
'code.google.com': 'https://www.googleapis.com/auth/projecthosting',
|
55
|
-
}
|
48
|
+
# This is what most GAE apps require for authentication.
|
49
|
+
OAUTH_SCOPE_EMAIL = 'https://www.googleapis.com/auth/userinfo.email'
|
50
|
+
# Gerrit and Git on *.googlesource.com require this scope.
|
51
|
+
OAUTH_SCOPE_GERRIT = 'https://www.googleapis.com/auth/gerritcodereview'
|
52
|
+
# Deprecated. Use OAUTH_SCOPE_EMAIL instead.
|
53
|
+
OAUTH_SCOPES = OAUTH_SCOPE_EMAIL
|
56
54
|
|
57
55
|
# Path to a file with cached OAuth2 credentials used by default relative to the
|
58
56
|
# home dir (see _get_token_cache_path). It should be a safe location accessible
|
@@ -74,10 +72,20 @@ AuthConfig = collections.namedtuple('AuthConfig', [
|
|
74
72
|
|
75
73
|
|
76
74
|
# OAuth access token with its expiration time (UTC datetime or None if unknown).
|
77
|
-
AccessToken
|
75
|
+
class AccessToken(collections.namedtuple('AccessToken', [
|
78
76
|
'token',
|
79
77
|
'expires_at',
|
80
|
-
])
|
78
|
+
])):
|
79
|
+
|
80
|
+
def needs_refresh(self, now=None):
|
81
|
+
"""True if this AccessToken should be refreshed."""
|
82
|
+
if self.expires_at is not None:
|
83
|
+
now = now or datetime.datetime.utcnow()
|
84
|
+
# Allow 3 min of clock skew between client and backend.
|
85
|
+
now += datetime.timedelta(seconds=180)
|
86
|
+
return now >= self.expires_at
|
87
|
+
# Token without expiration time never expires.
|
88
|
+
return False
|
81
89
|
|
82
90
|
|
83
91
|
# Refresh token passed via --auth-refresh-token-json.
|
@@ -106,8 +114,28 @@ class LoginRequiredError(AuthenticationError):
|
|
106
114
|
class LuciContextAuthError(Exception):
|
107
115
|
"""Raised on errors related to unsuccessful attempts to load LUCI_CONTEXT"""
|
108
116
|
|
117
|
+
def __init__(self, msg, exc=None):
|
118
|
+
if exc is None:
|
119
|
+
logging.error(msg)
|
120
|
+
else:
|
121
|
+
logging.exception(msg)
|
122
|
+
msg = '%s: %s' % (msg, exc)
|
123
|
+
super(LuciContextAuthError, self).__init__(msg)
|
124
|
+
|
125
|
+
|
126
|
+
def has_luci_context_local_auth():
|
127
|
+
"""Returns whether LUCI_CONTEXT should be used for ambient authentication.
|
128
|
+
"""
|
129
|
+
try:
|
130
|
+
params = _get_luci_context_local_auth_params()
|
131
|
+
except LuciContextAuthError:
|
132
|
+
return False
|
133
|
+
if params is None:
|
134
|
+
return False
|
135
|
+
return bool(params.default_account_id)
|
136
|
+
|
109
137
|
|
110
|
-
def get_luci_context_access_token():
|
138
|
+
def get_luci_context_access_token(scopes=OAUTH_SCOPE_EMAIL):
|
111
139
|
"""Returns a valid AccessToken from the local LUCI context auth server.
|
112
140
|
|
113
141
|
Adapted from
|
@@ -119,83 +147,116 @@ def get_luci_context_access_token():
|
|
119
147
|
None if LUCI_CONTEXT is absent.
|
120
148
|
|
121
149
|
Raises:
|
122
|
-
LuciContextAuthError if
|
123
|
-
|
150
|
+
LuciContextAuthError if LUCI_CONTEXT is present, but there was a failure
|
151
|
+
obtaining its access token.
|
124
152
|
"""
|
125
|
-
|
153
|
+
params = _get_luci_context_local_auth_params()
|
154
|
+
if params is None:
|
155
|
+
return None
|
156
|
+
return _get_luci_context_access_token(
|
157
|
+
params, datetime.datetime.utcnow(), scopes)
|
158
|
+
|
159
|
+
|
160
|
+
_LuciContextLocalAuthParams = collections.namedtuple(
|
161
|
+
'_LuciContextLocalAuthParams', [
|
162
|
+
'default_account_id',
|
163
|
+
'secret',
|
164
|
+
'rpc_port',
|
165
|
+
])
|
166
|
+
|
167
|
+
|
168
|
+
def _cache_thread_safe(f):
|
169
|
+
"""Decorator caching result of nullary function in thread-safe way."""
|
170
|
+
lock = threading.Lock()
|
171
|
+
cache = []
|
172
|
+
|
173
|
+
@functools.wraps(f)
|
174
|
+
def caching_wrapper():
|
175
|
+
if not cache:
|
176
|
+
with lock:
|
177
|
+
if not cache:
|
178
|
+
cache.append(f())
|
179
|
+
return cache[0]
|
180
|
+
|
181
|
+
# Allow easy way to clear cache, particularly useful in tests.
|
182
|
+
caching_wrapper.clear_cache = lambda: cache.pop() if cache else None
|
183
|
+
return caching_wrapper
|
184
|
+
|
126
185
|
|
186
|
+
@_cache_thread_safe
|
187
|
+
def _get_luci_context_local_auth_params():
|
188
|
+
"""Returns local auth parameters if local auth is configured else None.
|
127
189
|
|
128
|
-
|
129
|
-
|
190
|
+
Raises LuciContextAuthError on unexpected failures.
|
191
|
+
"""
|
192
|
+
ctx_path = os.environ.get('LUCI_CONTEXT')
|
130
193
|
if not ctx_path:
|
131
194
|
return None
|
132
195
|
ctx_path = ctx_path.decode(sys.getfilesystemencoding())
|
133
|
-
logging.debug('Loading LUCI_CONTEXT: %r', ctx_path)
|
134
|
-
|
135
|
-
def authErr(msg, *args):
|
136
|
-
error_msg = msg % args
|
137
|
-
ex = sys.exc_info()[1]
|
138
|
-
if not ex:
|
139
|
-
logging.error(error_msg)
|
140
|
-
raise LuciContextAuthError(error_msg)
|
141
|
-
logging.exception(error_msg)
|
142
|
-
raise LuciContextAuthError('%s: %s' % (error_msg, ex))
|
143
|
-
|
144
196
|
try:
|
145
197
|
loaded = _load_luci_context(ctx_path)
|
146
|
-
except (OSError, IOError, ValueError):
|
147
|
-
|
198
|
+
except (OSError, IOError, ValueError) as e:
|
199
|
+
raise LuciContextAuthError('Failed to open, read or decode LUCI_CONTEXT', e)
|
148
200
|
try:
|
149
201
|
local_auth = loaded.get('local_auth')
|
150
|
-
except AttributeError:
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
logging.debug('local_auth: no local auth found')
|
202
|
+
except AttributeError as e:
|
203
|
+
raise LuciContextAuthError('LUCI_CONTEXT not in proper format', e)
|
204
|
+
if local_auth is None:
|
205
|
+
logging.debug('LUCI_CONTEXT configured w/o local auth')
|
155
206
|
return None
|
156
207
|
try:
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
208
|
+
return _LuciContextLocalAuthParams(
|
209
|
+
default_account_id=local_auth.get('default_account_id'),
|
210
|
+
secret=local_auth.get('secret'),
|
211
|
+
rpc_port=int(local_auth.get('rpc_port')))
|
212
|
+
except (AttributeError, ValueError) as e:
|
213
|
+
raise LuciContextAuthError('local_auth config malformed', e)
|
214
|
+
|
215
|
+
|
216
|
+
def _load_luci_context(ctx_path):
|
217
|
+
# Kept separate for test mocking.
|
218
|
+
with open(ctx_path) as f:
|
219
|
+
return json.load(f)
|
220
|
+
|
221
|
+
|
222
|
+
def _get_luci_context_access_token(params, now, scopes=OAUTH_SCOPE_EMAIL):
|
223
|
+
# No account, local_auth shouldn't be used.
|
224
|
+
if not params.default_account_id:
|
167
225
|
return None
|
226
|
+
if not params.secret:
|
227
|
+
raise LuciContextAuthError('local_auth: no secret')
|
168
228
|
|
169
229
|
logging.debug('local_auth: requesting an access token for account "%s"',
|
170
|
-
|
230
|
+
params.default_account_id)
|
171
231
|
http = httplib2.Http()
|
172
|
-
host = '127.0.0.1:%d' % rpc_port
|
232
|
+
host = '127.0.0.1:%d' % params.rpc_port
|
173
233
|
resp, content = http.request(
|
174
234
|
uri='http://%s/rpc/LuciLocalAuthService.GetOAuthToken' % host,
|
175
235
|
method='POST',
|
176
236
|
body=json.dumps({
|
177
|
-
'account_id':
|
178
|
-
'scopes':
|
179
|
-
'secret': secret,
|
237
|
+
'account_id': params.default_account_id,
|
238
|
+
'scopes': scopes.split(' '),
|
239
|
+
'secret': params.secret,
|
180
240
|
}),
|
181
241
|
headers={'Content-Type': 'application/json'})
|
182
242
|
if resp.status != 200:
|
183
|
-
|
184
|
-
|
185
|
-
|
243
|
+
raise LuciContextAuthError(
|
244
|
+
'local_auth: Failed to grab access token from '
|
245
|
+
'LUCI context server with status %d: %r' % (resp.status, content))
|
186
246
|
try:
|
187
247
|
token = json.loads(content)
|
188
248
|
error_code = token.get('error_code')
|
189
249
|
error_message = token.get('error_message')
|
190
250
|
access_token = token.get('access_token')
|
191
251
|
expiry = token.get('expiry')
|
192
|
-
except (AttributeError, ValueError):
|
193
|
-
|
252
|
+
except (AttributeError, ValueError) as e:
|
253
|
+
raise LuciContextAuthError('Unexpected access token response format', e)
|
194
254
|
if error_code:
|
195
|
-
|
196
|
-
error_code, error_message)
|
255
|
+
raise LuciContextAuthError(
|
256
|
+
'Error %d in retrieving access token: %s', error_code, error_message)
|
197
257
|
if not access_token:
|
198
|
-
|
258
|
+
raise LuciContextAuthError(
|
259
|
+
'No access token returned from LUCI context server')
|
199
260
|
expiry_dt = None
|
200
261
|
if expiry:
|
201
262
|
try:
|
@@ -203,25 +264,19 @@ def _get_luci_context_access_token(env, now):
|
|
203
264
|
logging.debug(
|
204
265
|
'local_auth: got an access token for '
|
205
266
|
'account "%s" that expires in %d sec',
|
206
|
-
|
207
|
-
except (TypeError, ValueError):
|
208
|
-
|
267
|
+
params.default_account_id, (expiry_dt - now).total_seconds())
|
268
|
+
except (TypeError, ValueError) as e:
|
269
|
+
raise LuciContextAuthError('Invalid expiry in returned token', e)
|
209
270
|
else:
|
210
271
|
logging.debug(
|
211
|
-
'local auth: got an access token for '
|
212
|
-
|
213
|
-
account_id)
|
272
|
+
'local auth: got an access token for account "%s" that does not expire',
|
273
|
+
params.default_account_id)
|
214
274
|
access_token = AccessToken(access_token, expiry_dt)
|
215
|
-
if
|
216
|
-
|
275
|
+
if access_token.needs_refresh(now=now):
|
276
|
+
raise LuciContextAuthError('Received access token is already expired')
|
217
277
|
return access_token
|
218
278
|
|
219
279
|
|
220
|
-
def _load_luci_context(ctx_path):
|
221
|
-
with open(ctx_path) as f:
|
222
|
-
return json.load(f)
|
223
|
-
|
224
|
-
|
225
280
|
def make_auth_config(
|
226
281
|
use_oauth2=None,
|
227
282
|
save_cookies=None,
|
@@ -329,13 +384,14 @@ def auth_config_to_command_options(auth_config):
|
|
329
384
|
return opts
|
330
385
|
|
331
386
|
|
332
|
-
def get_authenticator_for_host(hostname, config):
|
387
|
+
def get_authenticator_for_host(hostname, config, scopes=OAUTH_SCOPE_EMAIL):
|
333
388
|
"""Returns Authenticator instance to access given host.
|
334
389
|
|
335
390
|
Args:
|
336
391
|
hostname: a naked hostname or http(s)://<hostname>[/] URL. Used to derive
|
337
392
|
a cache key for token cache.
|
338
393
|
config: AuthConfig instance.
|
394
|
+
scopes: space separated oauth scopes. Defaults to OAUTH_SCOPE_EMAIL.
|
339
395
|
|
340
396
|
Returns:
|
341
397
|
Authenticator object.
|
@@ -347,10 +403,7 @@ def get_authenticator_for_host(hostname, config):
|
|
347
403
|
# Append some scheme, otherwise urlparse puts hostname into parsed.path.
|
348
404
|
if '://' not in hostname:
|
349
405
|
hostname = 'https://' + hostname
|
350
|
-
scopes = OAUTH_SCOPES
|
351
406
|
parsed = urlparse.urlparse(hostname)
|
352
|
-
if parsed.netloc in ADDITIONAL_SCOPES:
|
353
|
-
scopes = "%s %s" % (scopes, ADDITIONAL_SCOPES[parsed.netloc])
|
354
407
|
|
355
408
|
if parsed.path or parsed.params or parsed.query or parsed.fragment:
|
356
409
|
raise AuthenticationError(
|
@@ -469,11 +522,11 @@ class Authenticator(object):
|
|
469
522
|
self._access_token = self._load_access_token()
|
470
523
|
|
471
524
|
# Refresh if expired or missing.
|
472
|
-
if not self._access_token or
|
525
|
+
if not self._access_token or self._access_token.needs_refresh():
|
473
526
|
# Maybe some other process already updated it, reload from the cache.
|
474
527
|
self._access_token = self._load_access_token()
|
475
528
|
# Nope, still expired, need to run the refresh flow.
|
476
|
-
if not self._access_token or
|
529
|
+
if not self._access_token or self._access_token.needs_refresh():
|
477
530
|
try:
|
478
531
|
self._access_token = self._create_access_token(
|
479
532
|
allow_user_interaction)
|
@@ -695,17 +748,6 @@ def _read_refresh_token_json(path):
|
|
695
748
|
'Failed to read refresh token from %s: missing key %s' % (path, e))
|
696
749
|
|
697
750
|
|
698
|
-
def _needs_refresh(access_token, now=None):
|
699
|
-
"""True if AccessToken should be refreshed."""
|
700
|
-
if access_token.expires_at is not None:
|
701
|
-
now = now or datetime.datetime.utcnow()
|
702
|
-
# Allow 5 min of clock skew between client and backend.
|
703
|
-
now += datetime.timedelta(seconds=300)
|
704
|
-
return now >= access_token.expires_at
|
705
|
-
# Token without expiration time never expires.
|
706
|
-
return False
|
707
|
-
|
708
|
-
|
709
751
|
def _log_credentials_info(title, credentials):
|
710
752
|
"""Dumps (non sensitive) part of client.Credentials object to debug log."""
|
711
753
|
if credentials:
|
@@ -9,4 +9,14 @@
|
|
9
9
|
# Also print it to reassure that the right settings are being used.
|
10
10
|
command=$(python $(dirname -- "$0")/autoninja.py "$@")
|
11
11
|
echo $command
|
12
|
-
|
12
|
+
$command
|
13
|
+
if [ $? -eq 0 ]; then
|
14
|
+
if [ "$NINJA_SUMMARIZE_BUILD" == "1" ]; then
|
15
|
+
python $(dirname -- "$0")/post_build_ninja_summary.py $@
|
16
|
+
fi
|
17
|
+
exit
|
18
|
+
fi
|
19
|
+
# Return an error code of 1 so that if a developer types:
|
20
|
+
# "autoninja chrome && chrome" then chrome won't run if the build fails.
|
21
|
+
exit 1
|
22
|
+
|
@@ -6,4 +6,10 @@
|
|
6
6
|
REM Execute whatever is printed by autoninja.py.
|
7
7
|
REM Also print it to reassure that the right settings are being used.
|
8
8
|
FOR /f "usebackq tokens=*" %%a in (`python %~dp0autoninja.py "%*"`) do echo %%a & %%a
|
9
|
-
|
9
|
+
@if errorlevel 1 goto buildfailure
|
10
|
+
@if "%NINJA_SUMMARIZE_BUILD%" == "1" python %~dp0post_build_ninja_summary.py %*
|
11
|
+
exit /b
|
12
|
+
:buildfailure
|
13
|
+
REM Return an error code of 1 so that if a developer types:
|
14
|
+
REM "autoninja chrome && chrome" then chrome won't run if the build fails.
|
15
|
+
cmd /c exit 1
|