libv8 6.0.286.54.3 → 6.2.414.42.0beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -3
  3. data/CHANGELOG.md +4 -0
  4. data/Rakefile +3 -3
  5. data/lib/libv8/version.rb +1 -1
  6. data/patches/0001-Build-a-standalone-static-library.patch +4 -4
  7. data/patches/0002-Don-t-compile-unnecessary-stuff.patch +12 -14
  8. data/patches/0003-Use-the-fPIC-flag-for-the-static-library.patch +4 -4
  9. data/patches/0004-Do-not-embed-debug-symbols-in-macOS-libraries.patch +4 -4
  10. data/patches/0005-avoid-constructor-inheritance-due-to-compilation-iss.patch +81 -0
  11. data/patches/9001-Arm64-Fix-host-architecture-detection.patch +37 -0
  12. data/vendor/depot_tools/.gitignore +1 -0
  13. data/vendor/depot_tools/OWNERS +0 -1
  14. data/vendor/depot_tools/auth.py +154 -6
  15. data/vendor/depot_tools/bootstrap/win/manifest.txt +1 -1
  16. data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +1 -1
  17. data/vendor/depot_tools/cipd_bin_setup.sh +12 -2
  18. data/vendor/depot_tools/cipd_manifest.txt +4 -1
  19. data/vendor/depot_tools/fetch.py +2 -0
  20. data/vendor/depot_tools/gclient.py +4 -6
  21. data/vendor/depot_tools/gclient_scm.py +12 -5
  22. data/vendor/depot_tools/gerrit_util.py +23 -1
  23. data/vendor/depot_tools/git_cache.py +59 -23
  24. data/vendor/depot_tools/git_cl.py +114 -43
  25. data/vendor/depot_tools/git_common.py +7 -0
  26. data/vendor/depot_tools/git_rebase_update.py +1 -0
  27. data/vendor/depot_tools/git_upstream_diff.py +12 -5
  28. data/vendor/depot_tools/gsutil.py +10 -0
  29. data/vendor/depot_tools/infra/config/OWNERS +0 -1
  30. data/vendor/depot_tools/infra/config/cq.cfg +6 -5
  31. data/vendor/depot_tools/infra/config/recipes.cfg +1 -1
  32. data/vendor/depot_tools/mac_toolchain +12 -0
  33. data/vendor/depot_tools/man/html/git-upstream-diff.html +10 -6
  34. data/vendor/depot_tools/man/man1/git-upstream-diff.1 +18 -7
  35. data/vendor/depot_tools/man/src/git-upstream-diff.txt +8 -5
  36. data/vendor/depot_tools/owners.py +9 -2
  37. data/vendor/depot_tools/presubmit_canned_checks.py +122 -0
  38. data/vendor/depot_tools/presubmit_support.py +57 -4
  39. data/vendor/depot_tools/recipes/OWNERS +0 -1
  40. data/vendor/depot_tools/recipes/README.recipes.md +20 -17
  41. data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +1 -1
  42. data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +15 -4
  43. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic.json +23 -0
  44. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_with_branch_heads.json +46 -0
  45. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/buildbot.json +23 -0
  46. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/clobber.json +46 -0
  47. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +22 -0
  48. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_rebase_patch_ref.json +46 -0
  49. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_reset.json +46 -0
  50. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_shallow.json +46 -0
  51. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/reset_root_solution_revision.json +46 -0
  52. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange.json +46 -0
  53. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2_buildbot.json +46 -0
  54. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2_json.json +46 -0
  55. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/trychange_oauth2_json_win.json +46 -0
  56. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob.json +46 -0
  57. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_empty_revision.json +46 -0
  58. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +4 -45
  59. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +23 -0
  60. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +23 -0
  61. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle.json +46 -0
  62. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle_deprecated.json +46 -0
  63. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_feature_branch.json +46 -0
  64. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8.json +46 -0
  65. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8_feature_branch.json +46 -0
  66. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_webrtc.json +46 -0
  67. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +46 -0
  68. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +46 -0
  69. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_manifest_name.json +194 -0
  70. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_manifest_name_no_patch.json +105 -0
  71. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_tags.json +46 -0
  72. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +12 -2
  73. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +226 -149
  74. data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +16 -5
  75. data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +1 -2
  76. data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.expected/basic.json +11 -0
  77. data/vendor/depot_tools/rietveld.py +1 -1
  78. data/vendor/depot_tools/roll_dep.py +4 -1
  79. data/vendor/depot_tools/split_cl.py +3 -0
  80. data/vendor/depot_tools/third_party/cq_client/OWNERS +0 -1
  81. data/vendor/depot_tools/third_party/mock/LICENSE.txt +26 -0
  82. data/vendor/depot_tools/third_party/mock/README.chromium +24 -0
  83. data/vendor/depot_tools/third_party/mock/__init__.py +2366 -0
  84. data/vendor/depot_tools/watchlists.py +12 -5
  85. metadata +12 -5
  86. data/patches/0005-Fix-GCC-7-build-errors.patch +0 -147
@@ -954,6 +954,13 @@ def tree(treeref, recurse=False):
954
954
  return ret
955
955
 
956
956
 
957
+ def get_remote_url(remote='origin'):
958
+ try:
959
+ return run('config', 'remote.%s.url' % remote)
960
+ except subprocess2.CalledProcessError:
961
+ return None
962
+
963
+
957
964
  def upstream(branch):
958
965
  try:
959
966
  return run('rev-parse', '--abbrev-ref', '--symbolic-full-name',
@@ -161,6 +161,7 @@ def rebase_branch(branch, parent, start_hash):
161
161
  if not rebase_ret.success:
162
162
  # TODO(iannucci): Find collapsible branches in a smarter way?
163
163
  print "Failed! Attempting to squash", branch, "...",
164
+ sys.stdout.flush()
164
165
  squash_branch = branch+"_squash_attempt"
165
166
  git.run('checkout', '-b', squash_branch)
166
167
  git.squash_current_branch(merge_base=start_hash)
@@ -14,27 +14,34 @@ def main(args):
14
14
  default_args = git.get_config_list('depot-tools.upstream-diff.default-args')
15
15
  args = default_args + args
16
16
 
17
+ current_branch = git.current_branch()
18
+
17
19
  parser = argparse.ArgumentParser()
18
20
  parser.add_argument('--wordwise', action='store_true', default=False,
19
21
  help=(
20
22
  'Print a colorized wordwise diff '
21
23
  'instead of line-wise diff'))
24
+ parser.add_argument('branch', nargs='?', default=current_branch,
25
+ help='Show changes from a different branch')
22
26
  opts, extra_args = parser.parse_known_args(args)
23
27
 
24
- cur = git.current_branch()
25
- if not cur or cur == 'HEAD':
28
+ if not opts.branch or opts.branch == 'HEAD':
26
29
  print 'fatal: Cannot perform git-upstream-diff while not on a branch'
27
30
  return 1
28
31
 
29
- par = git.upstream(cur)
32
+ par = git.upstream(opts.branch)
30
33
  if not par:
31
- print 'fatal: No upstream configured for branch \'%s\'' % cur
34
+ print 'fatal: No upstream configured for branch \'%s\'' % opts.branch
32
35
  return 1
33
36
 
34
37
  cmd = [git.GIT_EXE, 'diff', '--patience', '-C', '-C']
35
38
  if opts.wordwise:
36
39
  cmd += ['--word-diff=color', r'--word-diff-regex=(\w+|[^[:space:]])']
37
- cmd += [git.get_or_create_merge_base(cur, par)]
40
+ cmd += [git.get_or_create_merge_base(opts.branch, par)]
41
+ # Only specify the end commit if it is not the current branch, this lets the
42
+ # diff include uncommitted changes when diffing the current branch.
43
+ if opts.branch != current_branch:
44
+ cmd += [opts.branch]
38
45
 
39
46
  cmd += extra_args
40
47
 
@@ -130,6 +130,16 @@ def run_gsutil(force_version, fallback, target, args, clean=False):
130
130
  gsutil_bin = fallback
131
131
  disable_update = ['-o', 'GSUtil:software_update_check_period=0']
132
132
 
133
+ if sys.platform == 'cygwin':
134
+ # This script requires Windows Python, so invoke with depot_tools'
135
+ # Python.
136
+ def winpath(path):
137
+ return subprocess.check_output(['cygpath', '-w', path]).strip()
138
+ cmd = ['python.bat', winpath(__file__)]
139
+ cmd.extend(args)
140
+ sys.exit(subprocess.call(cmd))
141
+ assert sys.platform != 'cygwin'
142
+
133
143
  # Run "gsutil" through "vpython". We need to do this because on GCE instances,
134
144
  # expectations are made about Python having access to "google-compute-engine"
135
145
  # and "boto" packages that are not met with non-system Python (e.g., bundles).
@@ -1,7 +1,6 @@
1
1
  set noparent
2
2
  iannucci@chromium.org
3
3
  nodir@chromium.org
4
- phajdan.jr@chromium.org
5
4
  sergiyb@chromium.org
6
5
  tandrii@chromium.org
7
6
 
@@ -16,13 +16,14 @@ verifiers {
16
16
 
17
17
  try_job {
18
18
  buckets {
19
- name: "luci.infra.depot_tools.try"
19
+ name: "luci.infra.try"
20
20
  builders { name: "Depot Tools Presubmit" }
21
- builders { name: "build Roll Tester" }
22
- builders { name: "infra Roll Tester" }
23
- builders { name: "skia Roll Tester" }
24
- builders { name: "skiabuildbot Roll Tester" }
21
+ builders { name: "Build downstream Recipe Roll tester from Depot Tools" }
22
+ builders { name: "Infra downstream Recipe Roll tester from Depot Tools" }
23
+ builders { name: "Skia downstream Recipe Roll tester from Depot Tools" }
24
+ builders { name: "Skia Buildbot downstream Recipe Roll tester from Depot Tools" }
25
25
  }
26
+
26
27
  buckets {
27
28
  name: "master.internal.infra.try"
28
29
  builders { name: "build_limited Roll Tester (depot_tools)" }
@@ -15,7 +15,7 @@
15
15
  "deps": {
16
16
  "recipe_engine": {
17
17
  "branch": "master",
18
- "revision": "c07de907b2223efcacbf45d7b793fc0d8a964f31",
18
+ "revision": "0f093b369402a86363de15a3fae0c98eab4c8e00",
19
19
  "url": "https://chromium.googlesource.com/infra/luci/recipes-py.git"
20
20
  }
21
21
  },
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+
3
+ # Copyright 2017 The Chromium Authors. All rights reserved.
4
+ # Use of this source code is governed by a BSD-style license that can be
5
+ # found in the LICENSE file.
6
+
7
+ MYPATH=$(dirname "${BASH_SOURCE[0]}")
8
+
9
+ source "$MYPATH/cipd_bin_setup.sh"
10
+ cipd_bin_setup &> /dev/null
11
+
12
+ exec "$MYPATH/.cipd_bin/mac_toolchain" "$@"
@@ -755,7 +755,7 @@ git-upstream-diff(1) Manual Page
755
755
  <h2 id="_synopsis">SYNOPSIS</h2>
756
756
  <div class="sectionbody">
757
757
  <div class="verseblock">
758
- <pre class="content"><em>git upstream-diff</em> [--wordwise] [&lt;extra args for git-diff&gt;*]</pre>
758
+ <pre class="content"><em>git upstream-diff</em> [--wordwise] [branch] [&lt;extra args for git-diff&gt;*]</pre>
759
759
  <div class="attribution">
760
760
  </div></div>
761
761
  </div>
@@ -763,11 +763,10 @@ git-upstream-diff(1) Manual Page
763
763
  <div class="sect1">
764
764
  <h2 id="_description">DESCRIPTION</h2>
765
765
  <div class="sectionbody">
766
- <div class="paragraph"><p>Shows a diff between your current branch and it&#8217;s upstream. This is <em>roughly</em> the
767
- same as:</p></div>
766
+ <div class="paragraph"><p>Shows a diff between a branch and its upstream. If the branch is omitted, the tool shows the diff for the current branch. This is <em>roughly</em> the same as:</p></div>
768
767
  <div class="listingblock">
769
768
  <div class="content">
770
- <pre><code>git diff --patience -C -C HEAD@{upstream} <b>&lt;1&gt;</b> <b>&lt;2&gt;</b></code></pre>
769
+ <pre><code>git diff --patience -C -C branch@{upstream} <b>&lt;1&gt;</b> <b>&lt;2&gt;</b></code></pre>
771
770
  </div></div>
772
771
  <div class="colist arabic"><ol>
773
772
  <li>
@@ -782,7 +781,7 @@ same as:</p></div>
782
781
  </p>
783
782
  </li>
784
783
  </ol></div>
785
- <div class="paragraph"><p>The difference is that <code>HEAD@{upstream}</code> is actually the tagged merge base of
784
+ <div class="paragraph"><p>The difference is that <code>branch@{upstream}</code> is actually the tagged merge base of
786
785
  your branch (See <a href="git-rebase-update.html">git-rebase-update(1)</a>). This means that if your upstream
787
786
  branch was rebased, but you haven&#8217;t yet rebased the current branch on top of it,
788
787
  you&#8217;ll still see an accurate diff compared to just diffing against
@@ -803,6 +802,11 @@ so it is disabled by default.</p></div>
803
802
  <p>
804
803
  Print a colorized word-wise diff instead of a line-wise diff.
805
804
  </p>
805
+ <div class="literalblock">
806
+ <div class="content">
807
+ <pre><code>Show a diff between the specified branch and its upstream, instead of using
808
+ the current branch.</code></pre>
809
+ </div></div>
806
810
  </dd>
807
811
  <dt class="hdlist1">
808
812
  &lt;extra args for git-diff&gt;
@@ -891,7 +895,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
891
895
  <div id="footnotes"><hr /></div>
892
896
  <div id="footer">
893
897
  <div id="footer-text">
894
- Last updated 2017-02-27 13:47:35 PST
898
+ Last updated 2017-11-03 14:35:37 PDT
895
899
  </div>
896
900
  </div>
897
901
  </body>
@@ -2,12 +2,12 @@
2
2
  .\" Title: git-upstream-diff
3
3
  .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
4
4
  .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
5
- .\" Date: 02/27/2017
5
+ .\" Date: 11/03/2017
6
6
  .\" Manual: Chromium depot_tools Manual
7
- .\" Source: depot_tools a6ba28f5
7
+ .\" Source: depot_tools 9c2758a5
8
8
  .\" Language: English
9
9
  .\"
10
- .TH "GIT\-UPSTREAM\-DIFF" "1" "02/27/2017" "depot_tools a6ba28f5" "Chromium depot_tools Manual"
10
+ .TH "GIT\-UPSTREAM\-DIFF" "1" "11/03/2017" "depot_tools 9c2758a5" "Chromium depot_tools Manual"
11
11
  .\" -----------------------------------------------------------------
12
12
  .\" * Define some portability stuff
13
13
  .\" -----------------------------------------------------------------
@@ -32,18 +32,18 @@ git-upstream-diff \- Print a diff of the current branch, compared to its upstrea
32
32
  .SH "SYNOPSIS"
33
33
  .sp
34
34
  .nf
35
- \fIgit upstream\-diff\fR [\-\-wordwise] [<extra args for git\-diff>*]
35
+ \fIgit upstream\-diff\fR [\-\-wordwise] [branch] [<extra args for git\-diff>*]
36
36
  .fi
37
37
  .sp
38
38
  .SH "DESCRIPTION"
39
39
  .sp
40
- Shows a diff between your current branch and it\(cqs upstream\&. This is \fIroughly\fR the same as:
40
+ Shows a diff between a branch and its upstream\&. If the branch is omitted, the tool shows the diff for the current branch\&. This is \fIroughly\fR the same as:
41
41
  .sp
42
42
  .if n \{\
43
43
  .RS 4
44
44
  .\}
45
45
  .nf
46
- git diff \-\-patience \-C \-C HEAD@{upstream} \fB(1)\fR \fB(2)\fR
46
+ git diff \-\-patience \-C \-C branch@{upstream} \fB(1)\fR \fB(2)\fR
47
47
  .fi
48
48
  .if n \{\
49
49
  .RE
@@ -57,7 +57,7 @@ detects file copies/renames
57
57
  uses the patience\-diff algorithm, which tends to produce nicer diffs in many cases\&.
58
58
  .br
59
59
  .sp
60
- The difference is that HEAD@{upstream} is actually the tagged merge base of your branch (See \fBgit-rebase-update\fR(1))\&. This means that if your upstream branch was rebased, but you haven\(cqt yet rebased the current branch on top of it, you\(cqll still see an accurate diff compared to just diffing against @{upstream}\&.
60
+ The difference is that branch@{upstream} is actually the tagged merge base of your branch (See \fBgit-rebase-update\fR(1))\&. This means that if your upstream branch was rebased, but you haven\(cqt yet rebased the current branch on top of it, you\(cqll still see an accurate diff compared to just diffing against @{upstream}\&.
61
61
  .sp
62
62
  The \-\-wordwise option also allows git\-diff to do word\-by\-word comparison in a semi\-intelligent way\&. However, sometimes it can produce surprising results, so it is disabled by default\&.
63
63
  .SH "OPTIONS"
@@ -65,6 +65,17 @@ The \-\-wordwise option also allows git\-diff to do word\-by\-word comparison in
65
65
  \-\-wordwise
66
66
  .RS 4
67
67
  Print a colorized word\-wise diff instead of a line\-wise diff\&.
68
+ .sp
69
+ .if n \{\
70
+ .RS 4
71
+ .\}
72
+ .nf
73
+ Show a diff between the specified branch and its upstream, instead of using
74
+ the current branch\&.
75
+ .fi
76
+ .if n \{\
77
+ .RE
78
+ .\}
68
79
  .RE
69
80
  .PP
70
81
  <extra args for git\-diff>
@@ -9,22 +9,21 @@ include::_git-upstream-diff_desc.helper.txt[]
9
9
  SYNOPSIS
10
10
  --------
11
11
  [verse]
12
- 'git upstream-diff' [--wordwise] [<extra args for git-diff>*]
12
+ 'git upstream-diff' [--wordwise] [branch] [<extra args for git-diff>*]
13
13
 
14
14
  DESCRIPTION
15
15
  -----------
16
16
 
17
- Shows a diff between your current branch and it's upstream. This is 'roughly' the
18
- same as:
17
+ Shows a diff between a branch and its upstream. If the branch is omitted, the tool shows the diff for the current branch. This is 'roughly' the same as:
19
18
 
20
19
  ----
21
- git diff --patience -C -C HEAD@{upstream} <1> <2>
20
+ git diff --patience -C -C branch@{upstream} <1> <2>
22
21
  ----
23
22
  <1> `-C -C` detects file copies/renames
24
23
  <2> `--patience` uses the patience-diff algorithm, which tends to produce nicer
25
24
  diffs in many cases.
26
25
 
27
- The difference is that `HEAD@{upstream}` is actually the tagged merge base of
26
+ The difference is that `branch@{upstream}` is actually the tagged merge base of
28
27
  your branch (See linkgit:git-rebase-update[1]). This means that if your upstream
29
28
  branch was rebased, but you haven't yet rebased the current branch on top of it,
30
29
  you'll still see an accurate diff compared to just diffing against
@@ -41,6 +40,10 @@ OPTIONS
41
40
  --wordwise::
42
41
  Print a colorized word-wise diff instead of a line-wise diff.
43
42
 
43
+ [branch]
44
+ Show a diff between the specified branch and its upstream, instead of using
45
+ the current branch.
46
+
44
47
  <extra args for git-diff>::
45
48
  Extra arguments are included in the invocation of linkgit:git-diff[1]. These
46
49
  can be anything that `git-diff` normally takes.
@@ -231,7 +231,7 @@ class Database(object):
231
231
 
232
232
  def _read_owners(self, path):
233
233
  owners_path = self.os_path.join(self.root, path)
234
- if not self.os_path.exists(owners_path):
234
+ if not (self.os_path.exists(owners_path) or (path in self.override_files)):
235
235
  return
236
236
 
237
237
  if owners_path in self.read_files:
@@ -379,6 +379,9 @@ class Database(object):
379
379
  start = self.os_path.dirname(self.os_path.relpath(start, self.root))
380
380
  include_path = self.os_path.join(start, path)
381
381
 
382
+ if include_path in self.override_files:
383
+ return include_path
384
+
382
385
  owners_path = self.os_path.join(self.root, include_path)
383
386
  if not self.os_path.exists(owners_path):
384
387
  return None
@@ -392,7 +395,11 @@ class Database(object):
392
395
  owners = set()
393
396
  self._included_files[include_file] = owners
394
397
  lineno = 0
395
- for line in self.fopen(self.os_path.join(self.root, include_file)):
398
+ if include_file in self.override_files:
399
+ file_iter = self.override_files[include_file]
400
+ else:
401
+ file_iter = self.fopen(self.os_path.join(self.root, include_file))
402
+ for line in file_iter:
396
403
  lineno += 1
397
404
  line = line.strip()
398
405
  if (line.startswith('#') or line == '' or
@@ -1193,3 +1193,125 @@ def CheckCIPDPackages(input_api, output_api, platforms, packages):
1193
1193
  for k, v in packages.iteritems():
1194
1194
  manifest.append('%s %s' % (k, v))
1195
1195
  return CheckCIPDManifest(input_api, output_api, content='\n'.join(manifest))
1196
+
1197
+
1198
+ def CheckVPythonSpec(input_api, output_api, file_filter=None):
1199
+ """Validates any changed .vpython files with vpython verification tool.
1200
+
1201
+ Args:
1202
+ input_api: Bag of input related interfaces.
1203
+ output_api: Bag of output related interfaces.
1204
+ file_filter: Custom function that takes a path (relative to client root) and
1205
+ returns boolean, which is used to filter files for which to apply the
1206
+ verification to. Defaults to any path ending with .vpython, which captures
1207
+ both global .vpython and <script>.vpython files.
1208
+
1209
+ Returns:
1210
+ A list of input_api.Command objects containing verification commands.
1211
+ """
1212
+ file_filter = file_filter or (lambda f: f.LocalPath().endswith('.vpython'))
1213
+ affected_files = input_api.AffectedFiles(file_filter=file_filter)
1214
+ affected_files = map(lambda f: f.AbsoluteLocalPath(), affected_files)
1215
+
1216
+ commands = []
1217
+ for f in affected_files:
1218
+ commands.append(input_api.Command(
1219
+ 'Verify %s' % f,
1220
+ ['vpython', '-vpython-spec', f, '-vpython-tool', 'verify'],
1221
+ {'stderr': input_api.subprocess.STDOUT},
1222
+ output_api.PresubmitError))
1223
+
1224
+ return commands
1225
+
1226
+
1227
+ def CheckChangedLUCIConfigs(input_api, output_api):
1228
+ import collections
1229
+ import base64
1230
+ import json
1231
+ import urllib2
1232
+
1233
+ import auth
1234
+ import git_cl
1235
+
1236
+ LUCI_CONFIG_HOST_NAME = 'luci-config.appspot.com'
1237
+
1238
+ cl = git_cl.Changelist()
1239
+ remote, remote_branch = cl.GetRemoteBranch()
1240
+ if remote_branch.startswith('refs/remotes/%s/' % remote):
1241
+ remote_branch = remote_branch.replace(
1242
+ 'refs/remotes/%s/' % remote, 'refs/heads/', 1)
1243
+ if remote_branch.startswith('refs/remotes/branch-heads/'):
1244
+ remote_branch = remote_branch.replace(
1245
+ 'refs/remotes/branch-heads/', 'refs/branch-heads/', 1)
1246
+
1247
+ remote_host_url = cl.GetRemoteUrl()
1248
+ if not remote_host_url:
1249
+ return [output_api.PresubmitError(
1250
+ 'Remote host url for git has not been defined')]
1251
+ remote_host_url = remote_host_url.rstrip('/')
1252
+ if remote_host_url.endswith('.git'):
1253
+ remote_host_url = remote_host_url[:-len('.git')]
1254
+
1255
+ # authentication
1256
+ try:
1257
+ authenticator = auth.get_authenticator_for_host(
1258
+ LUCI_CONFIG_HOST_NAME, auth.make_auth_config())
1259
+ acc_tkn = authenticator.get_access_token()
1260
+ except auth.AuthenticationError as e:
1261
+ return [output_api.PresubmitError(
1262
+ 'Error in authenticating user.', long_text=str(e))]
1263
+
1264
+ def request(endpoint, body=None):
1265
+ api_url = ('https://%s/_ah/api/config/v1/%s'
1266
+ % (LUCI_CONFIG_HOST_NAME, endpoint))
1267
+ req = urllib2.Request(api_url)
1268
+ req.add_header('Authorization', 'Bearer %s' % acc_tkn.token)
1269
+ if body is not None:
1270
+ req.add_header('Content-Type', 'application/json')
1271
+ req.add_data(json.dumps(body))
1272
+ return json.load(urllib2.urlopen(req))
1273
+
1274
+ try:
1275
+ config_sets = request('config-sets').get('config_sets')
1276
+ except urllib2.HTTPError as e:
1277
+ return [output_api.PresubmitError(
1278
+ 'Config set request to luci-config failed', long_text=str(e))]
1279
+ if not config_sets:
1280
+ return [output_api.PresubmitWarning('No config_sets were returned')]
1281
+ loc_pref = '%s/+/%s/' % (remote_host_url, remote_branch)
1282
+ dir_to_config_set = {
1283
+ '%s/' % cs['location'][len(loc_pref):].rstrip('/'): cs['config_set']
1284
+ for cs in config_sets
1285
+ if cs['location'].startswith(loc_pref) or
1286
+ ('%s/' % cs['location']) == loc_pref
1287
+ }
1288
+ cs_to_files = collections.defaultdict(list)
1289
+ for f in input_api.AffectedFiles():
1290
+ # windows
1291
+ file_path = f.LocalPath().replace(_os.sep, '/')
1292
+ for dr, cs in dir_to_config_set.iteritems():
1293
+ if dr == '/' or file_path.startswith(dr):
1294
+ cs_to_files[cs].append({
1295
+ 'path': file_path[len(dr):] if dr != '/' else file_path,
1296
+ 'content': base64.b64encode(
1297
+ '\n'.join(f.NewContents()).encode('utf-8'))
1298
+ })
1299
+ outputs = []
1300
+ for cs, f in cs_to_files.iteritems():
1301
+ try:
1302
+ # TODO(myjang): parallelize
1303
+ res = request(
1304
+ 'validate-config', body={'config_set': cs, 'files': f})
1305
+ except urllib2.HTTPError as e:
1306
+ return [output_api.PresubmitError(
1307
+ 'Validation request to luci-config failed', long_text=str(e))]
1308
+ for msg in res.get('messages', []):
1309
+ sev = msg['severity']
1310
+ if sev == 'WARNING':
1311
+ out_f = output_api.PresubmitPromptWarning
1312
+ elif sev == 'ERROR' or sev == 'CRITICAL':
1313
+ out_f = output_api.PresubmitError
1314
+ else:
1315
+ out_f = output_api.PresubmitNotifyResult
1316
+ outputs.append(out_f('Config validation: %s' % msg['text']))
1317
+ return outputs
@@ -94,6 +94,7 @@ class PresubmitOutput(object):
94
94
  self.input_stream = input_stream
95
95
  self.output_stream = output_stream
96
96
  self.reviewers = []
97
+ self.more_cc = []
97
98
  self.written_output = []
98
99
  self.error_count = 0
99
100
 
@@ -275,6 +276,11 @@ class OutputApi(object):
275
276
 
276
277
  def __init__(self, is_committing):
277
278
  self.is_committing = is_committing
279
+ self.more_cc = []
280
+
281
+ def AppendCC(self, cc):
282
+ """Appends a user to cc for this change."""
283
+ self.more_cc.append(cc)
278
284
 
279
285
  def PresubmitPromptOrNotify(self, *args, **kwargs):
280
286
  """Warn the user when uploading, but only notify if committing."""
@@ -447,6 +453,8 @@ class InputApi(object):
447
453
  # We carry the canned checks so presubmit scripts can easily use them.
448
454
  self.canned_checks = presubmit_canned_checks
449
455
 
456
+ # Temporary files we must manually remove at the end of a run.
457
+ self._named_temporary_files = []
450
458
 
451
459
  # TODO(dpranke): figure out a list of all approved owners for a repo
452
460
  # in order to be able to handle wildcard OWNERS files?
@@ -577,6 +585,40 @@ class InputApi(object):
577
585
  raise IOError('Access outside the repository root is denied.')
578
586
  return gclient_utils.FileRead(file_item, mode)
579
587
 
588
+ def CreateTemporaryFile(self, **kwargs):
589
+ """Returns a named temporary file that must be removed with a call to
590
+ RemoveTemporaryFiles().
591
+
592
+ All keyword arguments are forwarded to tempfile.NamedTemporaryFile(),
593
+ except for |delete|, which is always set to False.
594
+
595
+ Presubmit checks that need to create a temporary file and pass it for
596
+ reading should use this function instead of NamedTemporaryFile(), as
597
+ Windows fails to open a file that is already open for writing.
598
+
599
+ with input_api.CreateTemporaryFile() as f:
600
+ f.write('xyz')
601
+ f.close()
602
+ input_api.subprocess.check_output(['script-that', '--reads-from',
603
+ f.name])
604
+
605
+
606
+ Note that callers of CreateTemporaryFile() should not worry about removing
607
+ any temporary file; this is done transparently by the presubmit handling
608
+ code.
609
+ """
610
+ if 'delete' in kwargs:
611
+ # Prevent users from passing |delete|; we take care of file deletion
612
+ # ourselves and this prevents unintuitive error messages when we pass
613
+ # delete=False and 'delete' is also in kwargs.
614
+ raise TypeError('CreateTemporaryFile() does not take a "delete" '
615
+ 'argument, file deletion is handled automatically by '
616
+ 'the same presubmit_support code that creates InputApi '
617
+ 'objects.')
618
+ temp_file = self.tempfile.NamedTemporaryFile(delete=False, **kwargs)
619
+ self._named_temporary_files.append(temp_file.name)
620
+ return temp_file
621
+
580
622
  @property
581
623
  def tbr(self):
582
624
  """Returns if a change is TBR'ed."""
@@ -685,6 +727,10 @@ class AffectedFile(object):
685
727
 
686
728
  def LocalPath(self):
687
729
  """Returns the path of this file on the local disk relative to client root.
730
+
731
+ This should be used for error messages but not for accessing files,
732
+ because presubmit checks are run with CWD=PresubmitLocalPath() (which is
733
+ often != client root).
688
734
  """
689
735
  return normpath(self._path)
690
736
 
@@ -1231,6 +1277,7 @@ class PresubmitExecuter(object):
1231
1277
  self.gerrit = gerrit_obj
1232
1278
  self.verbose = verbose
1233
1279
  self.dry_run = dry_run
1280
+ self.more_cc = []
1234
1281
 
1235
1282
  def ExecPresubmitScript(self, script_text, presubmit_path):
1236
1283
  """Executes a single presubmit script.
@@ -1252,6 +1299,7 @@ class PresubmitExecuter(object):
1252
1299
  input_api = InputApi(self.change, presubmit_path, self.committing,
1253
1300
  self.rietveld, self.verbose,
1254
1301
  gerrit_obj=self.gerrit, dry_run=self.dry_run)
1302
+ output_api = OutputApi(self.committing)
1255
1303
  context = {}
1256
1304
  try:
1257
1305
  exec script_text in context
@@ -1265,10 +1313,14 @@ class PresubmitExecuter(object):
1265
1313
  else:
1266
1314
  function_name = 'CheckChangeOnUpload'
1267
1315
  if function_name in context:
1268
- context['__args'] = (input_api, OutputApi(self.committing))
1269
- logging.debug('Running %s in %s', function_name, presubmit_path)
1270
- result = eval(function_name + '(*__args)', context)
1271
- logging.debug('Running %s done.', function_name)
1316
+ try:
1317
+ context['__args'] = (input_api, output_api)
1318
+ logging.debug('Running %s in %s', function_name, presubmit_path)
1319
+ result = eval(function_name + '(*__args)', context)
1320
+ logging.debug('Running %s done.', function_name)
1321
+ self.more_cc.extend(output_api.more_cc)
1322
+ finally:
1323
+ map(os.remove, input_api._named_temporary_files)
1272
1324
  if not (isinstance(result, types.TupleType) or
1273
1325
  isinstance(result, types.ListType)):
1274
1326
  raise PresubmitFailure(
@@ -1359,6 +1411,7 @@ def DoPresubmitChecks(change,
1359
1411
  presubmit_script = gclient_utils.FileRead(filename, 'rU')
1360
1412
  results += executer.ExecPresubmitScript(presubmit_script, filename)
1361
1413
 
1414
+ output.more_cc.extend(executer.more_cc)
1362
1415
  errors = []
1363
1416
  notifications = []
1364
1417
  warnings = []