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.
Files changed (195) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +10 -34
  3. data/CHANGELOG.md +16 -0
  4. data/README.md +9 -63
  5. data/Rakefile +2 -2
  6. data/ext/libv8/builder.rb +22 -87
  7. data/ext/libv8/extconf.rb +1 -1
  8. data/ext/libv8/paths.rb +5 -18
  9. data/lib/libv8/version.rb +1 -1
  10. data/spec/location_spec.rb +1 -2
  11. data/spec/spec_helper.rb +0 -1
  12. data/vendor/depot_tools/.gitattributes +1 -2
  13. data/vendor/depot_tools/OWNERS +0 -1
  14. data/vendor/depot_tools/PRESUBMIT.py +11 -6
  15. data/vendor/depot_tools/README.md +0 -1
  16. data/vendor/depot_tools/WATCHLISTS +0 -6
  17. data/vendor/depot_tools/auth.py +129 -87
  18. data/vendor/depot_tools/autoninja +11 -1
  19. data/vendor/depot_tools/autoninja.bat +7 -1
  20. data/vendor/depot_tools/autoninja.py +14 -6
  21. data/vendor/depot_tools/bootstrap/win/manifest.txt +1 -1
  22. data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +1 -1
  23. data/vendor/depot_tools/cipd +23 -2
  24. data/vendor/depot_tools/cipd.bat +2 -2
  25. data/vendor/depot_tools/cipd_client_version +1 -1
  26. data/vendor/depot_tools/cipd_manifest.txt +17 -7
  27. data/vendor/depot_tools/cit.py +7 -6
  28. data/vendor/depot_tools/cpplint.py +195 -35
  29. data/vendor/depot_tools/detect_host_arch.py +51 -0
  30. data/vendor/depot_tools/download_from_google_storage.py +85 -26
  31. data/vendor/depot_tools/fetch.py +11 -6
  32. data/vendor/depot_tools/fetch_configs/chromium.py +0 -1
  33. data/vendor/depot_tools/fetch_configs/goma_client.py +41 -0
  34. data/vendor/depot_tools/fetch_configs/infra.py +0 -1
  35. data/vendor/depot_tools/fetch_configs/infra_internal.py +0 -1
  36. data/vendor/depot_tools/gclient-new-workdir.py +4 -0
  37. data/vendor/depot_tools/gclient.py +732 -476
  38. data/vendor/depot_tools/gclient_eval.py +569 -58
  39. data/vendor/depot_tools/gclient_scm.py +258 -46
  40. data/vendor/depot_tools/gclient_utils.py +17 -1
  41. data/vendor/depot_tools/gerrit_util.py +46 -13
  42. data/vendor/depot_tools/git_cache.py +0 -2
  43. data/vendor/depot_tools/git_cl.py +176 -335
  44. data/vendor/depot_tools/git_common.py +19 -16
  45. data/vendor/depot_tools/git_footers.py +19 -5
  46. data/vendor/depot_tools/git_hyper_blame.py +9 -3
  47. data/vendor/depot_tools/git_new_branch.py +15 -3
  48. data/vendor/depot_tools/git_upstream_diff.py +7 -2
  49. data/vendor/depot_tools/gsutil.py +1 -1
  50. data/vendor/depot_tools/infra/config/cq.cfg +1 -2
  51. data/vendor/depot_tools/infra/config/recipes.cfg +1 -1
  52. data/vendor/depot_tools/luci-auth +13 -0
  53. data/vendor/depot_tools/luci-auth.bat +8 -0
  54. data/vendor/depot_tools/man/html/depot_tools.html +0 -8
  55. data/vendor/depot_tools/man/html/git-upstream-diff.html +20 -3
  56. data/vendor/depot_tools/man/man1/git-upstream-diff.1 +27 -6
  57. data/vendor/depot_tools/man/man7/depot_tools.7 +0 -5
  58. data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +2 -2
  59. data/vendor/depot_tools/man/src/git-upstream-diff.txt +21 -3
  60. data/vendor/depot_tools/man/src/make_docs.sh +6 -0
  61. data/vendor/depot_tools/my_activity.py +283 -93
  62. data/vendor/depot_tools/owners.py +9 -4
  63. data/vendor/depot_tools/owners_finder.py +7 -3
  64. data/vendor/depot_tools/post_build_ninja_summary.py +322 -0
  65. data/vendor/depot_tools/presubmit_canned_checks.py +91 -106
  66. data/vendor/depot_tools/presubmit_support.py +219 -157
  67. data/vendor/depot_tools/prpc +13 -0
  68. data/vendor/depot_tools/prpc.bat +8 -0
  69. data/vendor/depot_tools/recipes/OWNERS +3 -1
  70. data/vendor/depot_tools/recipes/README.recipes.md +70 -111
  71. data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +12 -5
  72. data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +36 -68
  73. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +0 -8
  74. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_json.json → no_apply_patch_on_gclient.json} +64 -10
  75. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{no_shallow.json → shallow.json} +1 -1
  76. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob.json +0 -8
  77. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_empty_revision.json +0 -8
  78. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +0 -6
  79. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +0 -7
  80. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +0 -6
  81. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle_deprecated.json +44 -0
  82. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange_oauth2_buildbot.json → tryjob_gerrit_branch_heads.json} +51 -5
  83. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +0 -8
  84. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +48 -8
  85. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +19 -26
  86. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +193 -155
  87. data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +9 -0
  88. data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +2 -7
  89. data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +31 -5
  90. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +37 -19
  91. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +37 -19
  92. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +37 -19
  93. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +37 -23
  94. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +4 -0
  95. data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +40 -8
  96. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +3 -3
  97. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.py +6 -3
  98. data/vendor/depot_tools/recipes/recipe_modules/gitiles/OWNERS +0 -1
  99. data/vendor/depot_tools/recipes/recipe_modules/tryserver/__init__.py +0 -1
  100. data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +7 -56
  101. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +0 -1
  102. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +15 -16
  103. data/vendor/depot_tools/recipes/recipes.py +4 -2
  104. data/vendor/depot_tools/recipes/trigger_recipe_roller.txt +12 -0
  105. data/vendor/depot_tools/roll_dep.py +35 -37
  106. data/vendor/depot_tools/support/chromite_wrapper +1 -1
  107. data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +3 -3
  108. data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +2 -2
  109. data/vendor/depot_tools/third_party/logilab/astroid/astpeephole.py +86 -0
  110. data/vendor/depot_tools/third_party/logilab/astroid/bases.py +53 -66
  111. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2pytest.py +31 -31
  112. data/vendor/depot_tools/third_party/logilab/astroid/brain/pynose.py +39 -16
  113. data/vendor/depot_tools/third_party/logilab/astroid/brain/pysix_moves.py +225 -189
  114. data/vendor/depot_tools/third_party/logilab/astroid/inference.py +45 -41
  115. data/vendor/depot_tools/third_party/logilab/astroid/manager.py +1 -0
  116. data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +2 -2
  117. data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +3 -2
  118. data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +1 -0
  119. data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +57 -3
  120. data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +1 -1
  121. data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +21 -1
  122. data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +58 -33
  123. data/vendor/depot_tools/third_party/pylint/README.chromium +2 -2
  124. data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +3 -3
  125. data/vendor/depot_tools/third_party/pylint/checkers/base.py +6 -18
  126. data/vendor/depot_tools/third_party/pylint/checkers/classes.py +64 -63
  127. data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +25 -57
  128. data/vendor/depot_tools/third_party/pylint/checkers/format.py +14 -10
  129. data/vendor/depot_tools/third_party/pylint/checkers/python3.py +142 -37
  130. data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +10 -1
  131. data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +50 -7
  132. data/vendor/depot_tools/third_party/pylint/checkers/strings.py +1 -1
  133. data/vendor/depot_tools/third_party/pylint/epylint.py +2 -1
  134. data/vendor/depot_tools/third_party/pylint/gui.py +1 -1
  135. data/vendor/depot_tools/third_party/pylint/lint.py +88 -23
  136. data/vendor/depot_tools/third_party/pylint/reporters/html.py +37 -5
  137. data/vendor/depot_tools/third_party/pylint/testutils.py +1 -1
  138. data/vendor/depot_tools/third_party/pylint/utils.py +5 -0
  139. data/vendor/depot_tools/vpython +31 -1
  140. data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +35 -2
  141. data/vendor/depot_tools/win_toolchain/package_from_installed.py +0 -15
  142. data/vendor/depot_tools/yapf +17 -0
  143. data/vendor/depot_tools/{apply_issue.bat → yapf.bat} +2 -2
  144. metadata +16 -58
  145. data/ext/libv8/compiler.rb +0 -39
  146. data/ext/libv8/compiler/apple_llvm.rb +0 -22
  147. data/ext/libv8/compiler/clang.rb +0 -22
  148. data/ext/libv8/compiler/gcc.rb +0 -22
  149. data/ext/libv8/compiler/generic_compiler.rb +0 -66
  150. data/ext/libv8/make.rb +0 -13
  151. data/ext/libv8/patcher.rb +0 -21
  152. data/patches/0001-Build-a-standalone-static-library.patch +0 -26
  153. data/patches/0002-Don-t-compile-unnecessary-stuff.patch +0 -85
  154. data/patches/0003-Use-the-fPIC-flag-for-the-static-library.patch +0 -25
  155. data/patches/0004-Do-not-embed-debug-symbols-in-macOS-libraries.patch +0 -25
  156. data/patches/0005-Remove-TryInstallOptimizedCode.patch +0 -321
  157. data/patches/mingw-generate-makefiles.sh +0 -97
  158. data/spec/compiler/apple_llvm_spec.rb +0 -37
  159. data/spec/compiler/clang_spec.rb +0 -37
  160. data/spec/compiler/gcc_spec.rb +0 -37
  161. data/spec/compiler/generic_compiler_spec.rb +0 -50
  162. data/spec/compiler_spec.rb +0 -45
  163. data/spec/support/compiler_helpers.rb +0 -47
  164. data/vendor/depot_tools/apply_issue +0 -8
  165. data/vendor/depot_tools/apply_issue.py +0 -315
  166. data/vendor/depot_tools/man/html/git-cherry-pick-upload.html +0 -815
  167. data/vendor/depot_tools/man/man1/git-cherry-pick-upload.1 +0 -80
  168. data/vendor/depot_tools/man/src/_git-cherry-pick-upload_desc.helper.txt +0 -1
  169. data/vendor/depot_tools/man/src/git-cherry-pick-upload.demo.1.sh +0 -17
  170. data/vendor/depot_tools/man/src/git-cherry-pick-upload.txt +0 -35
  171. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2.json +0 -8
  172. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2_json_win.json +0 -196
  173. data/vendor/depot_tools/recipes/recipe_modules/rietveld/__init__.py +0 -6
  174. data/vendor/depot_tools/recipes/recipe_modules/rietveld/api.py +0 -97
  175. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/basic.json +0 -8
  176. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/buildbot.json +0 -30
  177. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.expected/no_auth.json +0 -27
  178. data/vendor/depot_tools/recipes/recipe_modules/rietveld/examples/full.py +0 -38
  179. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch.json +0 -69
  180. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_rietveld_patch_new.json +0 -69
  181. data/vendor/depot_tools/third_party/cq_client/OWNERS +0 -2
  182. data/vendor/depot_tools/third_party/cq_client/README.depot_tools.md +0 -2
  183. data/vendor/depot_tools/third_party/cq_client/README.md +0 -59
  184. data/vendor/depot_tools/third_party/cq_client/__init__.py +0 -3
  185. data/vendor/depot_tools/third_party/cq_client/v1/__init__.py +0 -3
  186. data/vendor/depot_tools/third_party/cq_client/v1/cq.pb.go +0 -810
  187. data/vendor/depot_tools/third_party/cq_client/v1/cq.proto +0 -281
  188. data/vendor/depot_tools/third_party/cq_client/v1/cq_pb2.py +0 -794
  189. data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_both.cfg +0 -71
  190. data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_gerrit.cfg +0 -58
  191. data/vendor/depot_tools/third_party/cq_client/v1/testdata/cq_rietveld.cfg +0 -60
  192. data/vendor/depot_tools/third_party/cq_client/v2/__init__.py +0 -3
  193. data/vendor/depot_tools/third_party/cq_client/v2/cq.pb.go +0 -792
  194. data/vendor/depot_tools/third_party/cq_client/v2/cq.proto +0 -270
  195. data/vendor/depot_tools/third_party/cq_client/v2/cq_pb2.py +0 -841
@@ -2,4 +2,3 @@ $:.unshift File.expand_path '../../ext/libv8', __FILE__
2
2
  $:.unshift File.expand_path '../../lib', __FILE__
3
3
  require 'rspec'
4
4
  require 'libv8'
5
- require File.expand_path '../support/compiler_helpers', __FILE__
@@ -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
 
@@ -7,7 +7,6 @@ iannucci@chromium.org
7
7
  jochen@chromium.org
8
8
  maruel@chromium.org
9
9
  nodir@chromium.org
10
- petermayo@chromium.org
11
10
  tandrii@chromium.org
12
11
 
13
12
  per-file ninja*=thakis@chromium.org
@@ -12,11 +12,13 @@ import fnmatch
12
12
  import os
13
13
 
14
14
 
15
- ENSURE_FILE_TEMPLATE = r'''
16
- $VerifiedPlatform linux-386 linux-amd64 linux-arm64 linux-armv6l linux-mips64
17
- $VerifiedPlatform linux-ppc64 linux-ppc64le linux-s390x
18
- $VerifiedPlatform mac-amd64
19
- $VerifiedPlatform windows-386 windows-amd64
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, content=ENSURE_FILE_TEMPLATE % (pkg, ver)))
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
@@ -3,7 +3,6 @@
3
3
  Tools for working with Chromium development. It requires python 2.7.
4
4
 
5
5
 
6
-
7
6
  ## Tools
8
7
 
9
8
  The most important tools are:
@@ -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
  ],
@@ -45,14 +45,12 @@ OAUTH_CLIENT_ID = (
45
45
  '446450136466-2hr92jrq8e6i4tnsa56b52vacp7t3936.apps.googleusercontent.com')
46
46
  OAUTH_CLIENT_SECRET = 'uBfbay2KCy9t4QveJ-dOqHtp'
47
47
 
48
- # List of space separated OAuth scopes for generated tokens. GAE apps usually
49
- # use userinfo.email scope for authentication.
50
- OAUTH_SCOPES = 'https://www.googleapis.com/auth/userinfo.email'
51
-
52
- # Additional OAuth scopes.
53
- ADDITIONAL_SCOPES = {
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 = collections.namedtuple('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 the attempt to load LUCI_CONTEXT
123
- and request its access token is unsuccessful.
150
+ LuciContextAuthError if LUCI_CONTEXT is present, but there was a failure
151
+ obtaining its access token.
124
152
  """
125
- return _get_luci_context_access_token(os.environ, datetime.datetime.utcnow())
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
- def _get_luci_context_access_token(env, now):
129
- ctx_path = env.get('LUCI_CONTEXT')
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
- authErr('Failed to open, read or decode LUCI_CONTEXT')
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
- authErr('LUCI_CONTEXT not in proper format')
152
- # failed to grab local_auth from LUCI context
153
- if not local_auth:
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
- account_id = local_auth.get('default_account_id')
158
- secret = local_auth.get('secret')
159
- rpc_port = int(local_auth.get('rpc_port'))
160
- except (AttributeError, ValueError):
161
- authErr('local_auth: unexpected local auth format')
162
-
163
- if not secret:
164
- authErr('local_auth: no secret returned')
165
- # if account_id not specified, LUCI_CONTEXT should not be picked up
166
- if not account_id:
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
- account_id)
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': account_id,
178
- 'scopes': OAUTH_SCOPES.split(' '),
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
- err = ('local_auth: Failed to grab access token from '
184
- 'LUCI context server with status %d: %r')
185
- authErr(err, resp.status, content)
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
- authErr('local_auth: Unexpected access token response format')
252
+ except (AttributeError, ValueError) as e:
253
+ raise LuciContextAuthError('Unexpected access token response format', e)
194
254
  if error_code:
195
- authErr('local_auth: Error %d in retrieving access token: %s',
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
- authErr('local_auth: No access token returned from LUCI context server')
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
- account_id, (expiry_dt - now).total_seconds())
207
- except (TypeError, ValueError):
208
- authErr('Invalid expiry in returned token')
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
- 'account "%s" that does not expire',
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 _needs_refresh(access_token, now=now):
216
- authErr('local_auth: the returned access token needs to be refreshed')
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 _needs_refresh(self._access_token):
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 _needs_refresh(self._access_token):
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
- exec $command
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