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
@@ -41,12 +41,20 @@ for index, arg in enumerate(input_args[1:]):
41
41
 
42
42
  use_goma = False
43
43
  try:
44
- with open(os.path.join(output_dir, 'args.gn')) as file_handle:
45
- for line in file_handle:
46
- # This regex pattern copied from create_installer_archive.py
47
- m = re.match('^\s*use_goma\s*=\s*true(\s*$|\s*#.*$)', line)
48
- if m:
49
- use_goma = True
44
+ # If GOMA_DISABLED is set (to anything) then gomacc will use the local
45
+ # compiler instead of doing a goma compile. This is convenient if you want
46
+ # to briefly disable goma. It avoids having to rebuild the world when
47
+ # transitioning between goma/non-goma builds. However, it is not as fast as
48
+ # doing a "normal" non-goma build because an extra process is created for each
49
+ # compile step. Checking this environment variable ensures that autoninja uses
50
+ # an appropriate -j value in this situation.
51
+ if 'GOMA_DISABLED' not in os.environ:
52
+ with open(os.path.join(output_dir, 'args.gn')) as file_handle:
53
+ for line in file_handle:
54
+ # This regex pattern copied from create_installer_archive.py
55
+ m = re.match('^\s*use_goma\s*=\s*true(\s*$|\s*#.*$)', line)
56
+ if m:
57
+ use_goma = True
50
58
  except IOError:
51
59
  pass
52
60
 
@@ -17,4 +17,4 @@ $VerifiedPlatform windows-386 windows-amd64
17
17
  infra/python/cpython/windows-386 version:2.7.6
18
18
 
19
19
  @Subdir git
20
- infra/git/windows-${arch} version:2.15.1.2.chromium12
20
+ infra/git/windows-${arch} version:2.17.1.chromium15
@@ -17,4 +17,4 @@ $VerifiedPlatform windows-386 windows-amd64
17
17
  infra/python/cpython/${platform} version:2.7.13.chromium7
18
18
 
19
19
  @Subdir git
20
- infra/git/windows-${arch} version:2.15.1.2.chromium12
20
+ infra/git/windows-${arch} version:2.17.1.chromium15
@@ -6,6 +6,7 @@
6
6
 
7
7
  set -e -o pipefail
8
8
 
9
+ CYGWIN=false
9
10
  MYPATH=$(dirname "${BASH_SOURCE[0]}")
10
11
 
11
12
  : ${CIPD_CLIENT_VER:=`cat $MYPATH/cipd_client_version`}
@@ -16,14 +17,18 @@ case $UNAME in
16
17
  linux)
17
18
  PLAT=linux
18
19
  ;;
19
- cygwin*|msys*|mingw*)
20
+ cygwin*)
21
+ PLAT=windows
22
+ CYGWIN=true
23
+ ;;
24
+ msys*|mingw*)
20
25
  PLAT=windows
21
26
  ;;
22
27
  darwin)
23
28
  PLAT=mac
24
29
  ;;
25
30
  *)
26
- echo "UNKNOWN OS: $UNAME"
31
+ echo "cipd not supported on $UNAME"
27
32
  exit 1
28
33
  esac
29
34
 
@@ -106,4 +111,20 @@ if ! "$CLIENT" selfupdate -version "$CIPD_CLIENT_VER" ; then
106
111
  echo "" 1>&2
107
112
  fi
108
113
 
114
+ # CygWin requires changing absolute paths to Windows form. Relative paths
115
+ # are typically okay as Windows generally accepts both forward and back
116
+ # slashes. This could possibly be constrained to only /tmp/ and /cygdrive/.
117
+ if $CYGWIN; then
118
+ args=("$@")
119
+ for i in `seq 2 $#`; do
120
+ arg="${@:$i:1}"
121
+ if [ "${arg:0:1}" == "/" ]; then
122
+ last=$((i-1))
123
+ next=$((i+1))
124
+ set -- "${@:1:$last}" `cygpath -w "$arg"` "${@:$next}"
125
+ fi
126
+ done
127
+ echo "$CLIENT" "${@}"
128
+ fi
129
+
109
130
  exec "$CLIENT" "${@}"
@@ -25,6 +25,6 @@ if not errorlevel 0 goto :END
25
25
 
26
26
  :END
27
27
  endlocal & (
28
- set ERRORLEVEL=%ERRORLEVEL%
28
+ set EXPORT_ERRORLEVEL=%ERRORLEVEL%
29
29
  )
30
- exit /b %ERRORLEVEL%
30
+ exit /b %EXPORT_ERRORLEVEL%
@@ -1 +1 @@
1
- git_revision:d2677a4477e59cb7de00f1fb8a00e96b1aaeb927
1
+ git_revision:4d19637ec2c3d1efd8c6a1b05285118b786919e2
@@ -2,16 +2,26 @@
2
2
  # Use of this source code is governed by a BSD-style license that can be
3
3
  # found in the LICENSE file.
4
4
 
5
- $VerifiedPlatform linux-386 linux-amd64 linux-arm64 linux-armv6l linux-mips64
6
- $VerifiedPlatform linux-ppc64 linux-ppc64le linux-s390x
7
- $VerifiedPlatform mac-amd64
8
- $VerifiedPlatform windows-386 windows-amd64
5
+ # Fully supported plaforms.
6
+ $VerifiedPlatform linux-amd64 mac-amd64 windows-amd64 windows-386
7
+
8
+ # Platform with best-effort support: we have some binaries cross-compiled for
9
+ # them, but we do not test they work. They also may not have all necessary
10
+ # vpython packages.
11
+ $VerifiedPlatform linux-386 linux-ppc64 linux-ppc64le linux-s390x
12
+ $VerifiedPlatform linux-arm64 linux-armv6l linux-mips64
9
13
 
10
14
  # vpython.
11
- infra/tools/luci/vpython/${platform} git_revision:a3d636052088db3daa48413b3e209eed4f5cb4ad
15
+ infra/tools/luci/vpython/${platform} git_revision:4d19637ec2c3d1efd8c6a1b05285118b786919e2
12
16
 
13
17
  # LUCI editor
14
- infra/tools/luci/led/${platform} git_revision:54b6b3102fbb15ca3e3bd762ff3df7b08057d653
18
+ infra/tools/luci/led/${platform} git_revision:7ba61969ccbe1f9679661555f72ca947da508a70
15
19
 
16
20
  # Mac toolchain installer
17
- infra/tools/mac_toolchain/${os=mac}-${arch} git_revision:2b69be6203f56a970202d9b5984557c0453b4eb0
21
+ infra/tools/mac_toolchain/${os=mac}-${arch} git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a
22
+
23
+ # LUCI rpc command line tool
24
+ infra/tools/prpc/${platform} git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c
25
+
26
+ # LUCI authentication command line tool
27
+ infra/tools/luci-auth/${platform} git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c
@@ -12,14 +12,15 @@ This tool does a two things:
12
12
  * Acts as an alias to infra.git/cipd/<executable>
13
13
  """
14
14
 
15
- # TODO(hinoka): Use cipd/glyco instead of git/gclient.
15
+ # TODO(hinoka,iannucci): Pre-pack infra tools in cipd package with vpython spec.
16
16
 
17
17
  import argparse
18
18
  import sys
19
19
  import os
20
- import subprocess
21
20
  import re
22
21
 
22
+ import subprocess2 as subprocess
23
+
23
24
 
24
25
  SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
25
26
  GCLIENT = os.path.join(SCRIPT_DIR, 'gclient.py')
@@ -37,7 +38,7 @@ def need_to_update(branch):
37
38
  try:
38
39
  cmd = [sys.executable, GCLIENT, 'revinfo']
39
40
  subprocess.check_call(
40
- cmd, cwd=os.path.join(TARGET_DIR), stdout=subprocess.PIPE)
41
+ cmd, cwd=os.path.join(TARGET_DIR), stdout=subprocess.VOID)
41
42
  except subprocess.CalledProcessError:
42
43
  return True # Gclient failed, definitely need to update.
43
44
  except OSError:
@@ -50,7 +51,7 @@ def need_to_update(branch):
50
51
 
51
52
  subprocess.check_call(
52
53
  ['git', 'fetch', 'origin'], cwd=INFRA_DIR,
53
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
54
+ stdout=subprocess.VOID, stderr=subprocess.STDOUT)
54
55
  origin_rev = get_git_rev(INFRA_DIR, 'origin/%s' % (branch,))
55
56
  return origin_rev != local_rev
56
57
 
@@ -67,11 +68,11 @@ def ensure_infra(branch):
67
68
  subprocess.check_call(
68
69
  [sys.executable, os.path.join(SCRIPT_DIR, 'fetch.py'), 'infra'],
69
70
  cwd=TARGET_DIR,
70
- stdout=subprocess.PIPE)
71
+ stdout=subprocess.VOID)
71
72
  subprocess.check_call(
72
73
  [sys.executable, GCLIENT, 'sync', '--revision', 'origin/%s' % (branch,)],
73
74
  cwd=TARGET_DIR,
74
- stdout=subprocess.PIPE)
75
+ stdout=subprocess.VOID)
75
76
  sys.stderr.write(' done.\n')
76
77
  sys.stderr.flush()
77
78
 
@@ -53,12 +53,19 @@ import sre_compile
53
53
  import string
54
54
  import sys
55
55
  import unicodedata
56
+ import sysconfig
57
+
58
+ try:
59
+ xrange # Python 2
60
+ except NameError:
61
+ xrange = range # Python 3
56
62
 
57
63
 
58
64
  _USAGE = """
59
65
  Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
60
66
  [--counting=total|toplevel|detailed] [--root=subdir]
61
- [--linelength=digits]
67
+ [--linelength=digits] [--headers=x,y,...]
68
+ [--quiet]
62
69
  <file> [file] ...
63
70
 
64
71
  The style guidelines this tries to follow are those in
@@ -85,6 +92,9 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
85
92
  verbose=#
86
93
  Specify a number 0-5 to restrict errors to certain verbosity levels.
87
94
 
95
+ quiet
96
+ Don't print anything if no errors are found.
97
+
88
98
  filter=-x,+y,...
89
99
  Specify a comma-separated list of category-filters to apply: only
90
100
  error messages whose category names pass the filters will be printed.
@@ -116,12 +126,13 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
116
126
  ignored.
117
127
 
118
128
  Examples:
119
- Assuming that src/.git exists, the header guard CPP variables for
120
- src/chrome/browser/ui/browser.h are:
129
+ Assuming that top/src/.git exists (and cwd=top/src), the header guard
130
+ CPP variables for top/src/chrome/browser/ui/browser.h are:
121
131
 
122
132
  No flag => CHROME_BROWSER_UI_BROWSER_H_
123
133
  --root=chrome => BROWSER_UI_BROWSER_H_
124
134
  --root=chrome/browser => UI_BROWSER_H_
135
+ --root=.. => SRC_CHROME_BROWSER_UI_BROWSER_H_
125
136
 
126
137
  linelength=digits
127
138
  This is the allowed line length for the project. The default value is
@@ -136,6 +147,14 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
136
147
  Examples:
137
148
  --extensions=hpp,cpp
138
149
 
150
+ headers=x,y,...
151
+ The header extensions that cpplint will treat as .h in checks. Values are
152
+ automatically added to --extensions list.
153
+
154
+ Examples:
155
+ --headers=hpp,hxx
156
+ --headers=hpp
157
+
139
158
  cpplint.py supports per-directory configurations specified in CPPLINT.cfg
140
159
  files. CPPLINT.cfg file can contain a number of key=value pairs.
141
160
  Currently the following options are supported:
@@ -144,6 +163,8 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
144
163
  filter=+filter1,-filter2,...
145
164
  exclude_files=regex
146
165
  linelength=80
166
+ root=subdir
167
+ headers=x,y,...
147
168
 
148
169
  "set noparent" option prevents cpplint from traversing directory tree
149
170
  upwards looking for more .cfg files in parent directories. This option
@@ -159,6 +180,12 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
159
180
 
160
181
  "linelength" allows to specify the allowed line length for the project.
161
182
 
183
+ The "root" option is similar in function to the --root flag (see example
184
+ above). Paths are relative to the directory of the CPPLINT.cfg.
185
+
186
+ The "headers" option is similar in function to the --headers flag
187
+ (see example above).
188
+
162
189
  CPPLINT.cfg has an effect on files in the same directory and all
163
190
  sub-directories, unless overridden by a nested configuration file.
164
191
 
@@ -525,10 +552,7 @@ _error_suppressions = {}
525
552
  # The root directory used for deriving header guard CPP variable.
526
553
  # This is set by --root flag.
527
554
  _root = None
528
-
529
- # The project root directory. Used for deriving header guard CPP variable.
530
- # This is set by --project_root flag. Must be an absolute path.
531
- _project_root = None
555
+ _root_debug = False
532
556
 
533
557
  # The allowed line length of files.
534
558
  # This is set by --linelength flag.
@@ -538,10 +562,25 @@ _line_length = 80
538
562
  # This is set by --extensions flag.
539
563
  _valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh'])
540
564
 
565
+ # Treat all headers starting with 'h' equally: .h, .hpp, .hxx etc.
566
+ # This is set by --headers flag.
567
+ _hpp_headers = set(['h'])
568
+
541
569
  # {str, bool}: a map from error categories to booleans which indicate if the
542
570
  # category should be suppressed for every line.
543
571
  _global_error_suppressions = {}
544
572
 
573
+ def ProcessHppHeadersOption(val):
574
+ global _hpp_headers
575
+ try:
576
+ _hpp_headers = set(val.split(','))
577
+ # Automatically append to extensions list so it does not have to be set 2 times
578
+ _valid_extensions.update(_hpp_headers)
579
+ except ValueError:
580
+ PrintUsage('Header extensions must be comma separated list.')
581
+
582
+ def IsHeaderExtension(file_extension):
583
+ return file_extension in _hpp_headers
545
584
 
546
585
  def ParseNolintSuppressions(filename, raw_line, linenum, error):
547
586
  """Updates the global list of line error-suppressions.
@@ -834,6 +873,7 @@ class _CppLintState(object):
834
873
  self._filters_backup = self.filters[:]
835
874
  self.counting = 'total' # In what way are we counting errors?
836
875
  self.errors_by_category = {} # string to int dict storing error counts
876
+ self.quiet = False # Suppress non-error messagess?
837
877
 
838
878
  # output format:
839
879
  # "emacs" - format that emacs can parse (default)
@@ -844,6 +884,12 @@ class _CppLintState(object):
844
884
  """Sets the output format for errors."""
845
885
  self.output_format = output_format
846
886
 
887
+ def SetQuiet(self, quiet):
888
+ """Sets the module's quiet settings, and returns the previous setting."""
889
+ last_quiet = self.quiet
890
+ self.quiet = quiet
891
+ return last_quiet
892
+
847
893
  def SetVerboseLevel(self, level):
848
894
  """Sets the module's verbosity, and returns the previous setting."""
849
895
  last_verbose_level = self.verbose_level
@@ -911,7 +957,7 @@ class _CppLintState(object):
911
957
  for category, count in self.errors_by_category.iteritems():
912
958
  sys.stderr.write('Category \'%s\' errors found: %d\n' %
913
959
  (category, count))
914
- sys.stderr.write('Total errors found: %d\n' % self.error_count)
960
+ sys.stdout.write('Total errors found: %d\n' % self.error_count)
915
961
 
916
962
  _cpplint_state = _CppLintState()
917
963
 
@@ -925,6 +971,14 @@ def _SetOutputFormat(output_format):
925
971
  """Sets the module's output format."""
926
972
  _cpplint_state.SetOutputFormat(output_format)
927
973
 
974
+ def _Quiet():
975
+ """Return's the module's quiet setting."""
976
+ return _cpplint_state.quiet
977
+
978
+ def _SetQuiet(quiet):
979
+ """Set the module's quiet status, and return previous setting."""
980
+ return _cpplint_state.SetQuiet(quiet)
981
+
928
982
 
929
983
  def _VerboseLevel():
930
984
  """Returns the module's verbosity setting."""
@@ -1071,10 +1125,6 @@ class FileInfo(object):
1071
1125
  if os.path.exists(fullname):
1072
1126
  project_dir = os.path.dirname(fullname)
1073
1127
 
1074
- if _project_root:
1075
- prefix = os.path.commonprefix([_project_root, project_dir])
1076
- return fullname[len(prefix) + 1:]
1077
-
1078
1128
  if os.path.exists(os.path.join(project_dir, ".svn")):
1079
1129
  # If there's a .svn file in the current directory, we recursively look
1080
1130
  # up the directory tree for the top of the SVN checkout
@@ -1089,12 +1139,13 @@ class FileInfo(object):
1089
1139
 
1090
1140
  # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by
1091
1141
  # searching up from the current path.
1092
- root_dir = os.path.dirname(fullname)
1093
- while (root_dir != os.path.dirname(root_dir) and
1094
- not os.path.exists(os.path.join(root_dir, ".git")) and
1095
- not os.path.exists(os.path.join(root_dir, ".hg")) and
1096
- not os.path.exists(os.path.join(root_dir, ".svn"))):
1097
- root_dir = os.path.dirname(root_dir)
1142
+ root_dir = current_dir = os.path.dirname(fullname)
1143
+ while current_dir != os.path.dirname(current_dir):
1144
+ if (os.path.exists(os.path.join(current_dir, ".git")) or
1145
+ os.path.exists(os.path.join(current_dir, ".hg")) or
1146
+ os.path.exists(os.path.join(current_dir, ".svn"))):
1147
+ root_dir = current_dir
1148
+ current_dir = os.path.dirname(current_dir)
1098
1149
 
1099
1150
  if (os.path.exists(os.path.join(root_dir, ".git")) or
1100
1151
  os.path.exists(os.path.join(root_dir, ".hg")) or
@@ -1189,8 +1240,8 @@ def Error(filename, linenum, category, confidence, message):
1189
1240
  if _ShouldPrintError(category, confidence, linenum):
1190
1241
  _cpplint_state.IncrementErrorCount(category)
1191
1242
  if _cpplint_state.output_format == 'vs7':
1192
- sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
1193
- filename, linenum, message, category, confidence))
1243
+ sys.stderr.write('%s(%s): error cpplint: [%s] %s [%d]\n' % (
1244
+ filename, linenum, category, message, confidence))
1194
1245
  elif _cpplint_state.output_format == 'eclipse':
1195
1246
  sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
1196
1247
  filename, linenum, message, category, confidence))
@@ -1732,6 +1783,30 @@ def GetIndentLevel(line):
1732
1783
  else:
1733
1784
  return 0
1734
1785
 
1786
+ def PathSplitToList(path):
1787
+ """Returns the path split into a list by the separator.
1788
+
1789
+ Args:
1790
+ path: An absolute or relative path (e.g. '/a/b/c/' or '../a')
1791
+
1792
+ Returns:
1793
+ A list of path components (e.g. ['a', 'b', 'c]).
1794
+ """
1795
+ lst = []
1796
+ while True:
1797
+ (head, tail) = os.path.split(path)
1798
+ if head == path: # absolute paths end
1799
+ lst.append(head)
1800
+ break
1801
+ if tail == path: # relative paths end
1802
+ lst.append(tail)
1803
+ break
1804
+
1805
+ path = head
1806
+ lst.append(tail)
1807
+
1808
+ lst.reverse()
1809
+ return lst
1735
1810
 
1736
1811
  def GetHeaderGuardCPPVariable(filename):
1737
1812
  """Returns the CPP variable that should be used as a header guard.
@@ -1754,8 +1829,58 @@ def GetHeaderGuardCPPVariable(filename):
1754
1829
 
1755
1830
  fileinfo = FileInfo(filename)
1756
1831
  file_path_from_root = fileinfo.RepositoryName()
1757
- if _root:
1758
- file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root)
1832
+
1833
+ def FixupPathFromRoot():
1834
+ if _root_debug:
1835
+ sys.stderr.write("\n_root fixup, _root = '%s', repository name = '%s'\n"
1836
+ %(_root, fileinfo.RepositoryName()))
1837
+
1838
+ # Process the file path with the --root flag if it was set.
1839
+ if not _root:
1840
+ if _root_debug:
1841
+ sys.stderr.write("_root unspecified\n")
1842
+ return file_path_from_root
1843
+
1844
+ def StripListPrefix(lst, prefix):
1845
+ # f(['x', 'y'], ['w, z']) -> None (not a valid prefix)
1846
+ if lst[:len(prefix)] != prefix:
1847
+ return None
1848
+ # f(['a, 'b', 'c', 'd'], ['a', 'b']) -> ['c', 'd']
1849
+ return lst[(len(prefix)):]
1850
+
1851
+ # root behavior:
1852
+ # --root=subdir , lstrips subdir from the header guard
1853
+ maybe_path = StripListPrefix(PathSplitToList(file_path_from_root),
1854
+ PathSplitToList(_root))
1855
+
1856
+ if _root_debug:
1857
+ sys.stderr.write(("_root lstrip (maybe_path=%s, file_path_from_root=%s," +
1858
+ " _root=%s)\n") %(maybe_path, file_path_from_root, _root))
1859
+
1860
+ if maybe_path:
1861
+ return os.path.join(*maybe_path)
1862
+
1863
+ # --root=.. , will prepend the outer directory to the header guard
1864
+ full_path = fileinfo.FullName()
1865
+ root_abspath = os.path.abspath(_root)
1866
+
1867
+ maybe_path = StripListPrefix(PathSplitToList(full_path),
1868
+ PathSplitToList(root_abspath))
1869
+
1870
+ if _root_debug:
1871
+ sys.stderr.write(("_root prepend (maybe_path=%s, full_path=%s, " +
1872
+ "root_abspath=%s)\n") %(maybe_path, full_path, root_abspath))
1873
+
1874
+ if maybe_path:
1875
+ return os.path.join(*maybe_path)
1876
+
1877
+ if _root_debug:
1878
+ sys.stderr.write("_root ignore, returning %s\n" %(file_path_from_root))
1879
+
1880
+ # --root=FAKE_DIR is ignored
1881
+ return file_path_from_root
1882
+
1883
+ file_path_from_root = FixupPathFromRoot()
1759
1884
  return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_'
1760
1885
 
1761
1886
 
@@ -3864,6 +3989,14 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
3864
3989
  # outputting warnings for the matching closing brace, if there are
3865
3990
  # nested blocks with trailing semicolons, we will get the error
3866
3991
  # messages in reversed order.
3992
+
3993
+ # We need to check the line forward for NOLINT
3994
+ raw_lines = clean_lines.raw_lines
3995
+ ParseNolintSuppressions(filename, raw_lines[endlinenum-1], endlinenum-1,
3996
+ error)
3997
+ ParseNolintSuppressions(filename, raw_lines[endlinenum], endlinenum,
3998
+ error)
3999
+
3867
4000
  error(filename, endlinenum, 'readability/braces', 4,
3868
4001
  "You don't need a ; after a }")
3869
4002
 
@@ -4161,6 +4294,16 @@ def GetLineWidth(line):
4161
4294
  if unicodedata.east_asian_width(uc) in ('W', 'F'):
4162
4295
  width += 2
4163
4296
  elif not unicodedata.combining(uc):
4297
+ # Issue 337
4298
+ # https://mail.python.org/pipermail/python-list/2012-August/628809.html
4299
+ if (sys.version_info.major, sys.version_info.minor) <= (3, 2):
4300
+ # https://github.com/python/cpython/blob/2.7/Include/unicodeobject.h#L81
4301
+ is_wide_build = sysconfig.get_config_var("Py_UNICODE_SIZE") >= 4
4302
+ # https://github.com/python/cpython/blob/2.7/Objects/unicodeobject.c#L564
4303
+ is_low_surrogate = 0xDC00 <= ord(uc) <= 0xDFFF
4304
+ if not is_wide_build and is_low_surrogate:
4305
+ width -= 1
4306
+
4164
4307
  width += 1
4165
4308
  return width
4166
4309
  else:
@@ -4234,7 +4377,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
4234
4377
 
4235
4378
  # Check if the line is a header guard.
4236
4379
  is_header_guard = False
4237
- if file_extension == 'h':
4380
+ if IsHeaderExtension(file_extension):
4238
4381
  cppvar = GetHeaderGuardCPPVariable(filename)
4239
4382
  if (line.startswith('#ifndef %s' % cppvar) or
4240
4383
  line.startswith('#define %s' % cppvar) or
@@ -4583,7 +4726,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
4583
4726
  CheckGlobalStatic(filename, clean_lines, linenum, error)
4584
4727
  CheckPrintf(filename, clean_lines, linenum, error)
4585
4728
 
4586
- if file_extension == 'h':
4729
+ if IsHeaderExtension(file_extension):
4587
4730
  # TODO(unknown): check that 1-arg constructors are explicit.
4588
4731
  # How to tell it's a constructor?
4589
4732
  # (handled in CheckForNonStandardConstructs for now)
@@ -4690,12 +4833,12 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
4690
4833
  # Check for use of unnamed namespaces in header files. Registration
4691
4834
  # macros are typically OK, so we allow use of "namespace {" on lines
4692
4835
  # that end with backslashes.
4693
- if (file_extension == 'h'
4836
+ if (IsHeaderExtension(file_extension)
4694
4837
  and Search(r'\bnamespace\s*{', line)
4695
4838
  and line[-1] != '\\'):
4696
4839
  error(filename, linenum, 'build/namespaces', 4,
4697
4840
  'Do not use unnamed namespaces in header files. See '
4698
- 'https://google.github.io/styleguide/cppguide.html#Namespaces'
4841
+ 'https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
4699
4842
  ' for more information.')
4700
4843
 
4701
4844
 
@@ -5780,7 +5923,7 @@ def ProcessFileData(filename, file_extension, lines, error,
5780
5923
  RemoveMultiLineComments(filename, lines, error)
5781
5924
  clean_lines = CleansedLines(lines)
5782
5925
 
5783
- if file_extension == 'h':
5926
+ if IsHeaderExtension(file_extension):
5784
5927
  CheckForHeaderGuard(filename, clean_lines, error)
5785
5928
 
5786
5929
  for line in xrange(clean_lines.NumLines()):
@@ -5849,6 +5992,9 @@ def ProcessConfigOverrides(filename):
5849
5992
  if base_name:
5850
5993
  pattern = re.compile(val)
5851
5994
  if pattern.match(base_name):
5995
+ if _cpplint_state.quiet:
5996
+ # Suppress "Ignoring file" warning when using --quiet.
5997
+ return False
5852
5998
  sys.stderr.write('Ignoring "%s": file excluded by "%s". '
5853
5999
  'File path component "%s" matches '
5854
6000
  'pattern "%s"\n' %
@@ -5860,6 +6006,12 @@ def ProcessConfigOverrides(filename):
5860
6006
  _line_length = int(val)
5861
6007
  except ValueError:
5862
6008
  sys.stderr.write('Line length must be numeric.')
6009
+ elif name == 'root':
6010
+ global _root
6011
+ # root directories are specified relative to CPPLINT.cfg dir.
6012
+ _root = os.path.join(os.path.dirname(cfg_file), val)
6013
+ elif name == 'headers':
6014
+ ProcessHppHeadersOption(val)
5863
6015
  else:
5864
6016
  sys.stderr.write(
5865
6017
  'Invalid configuration option (%s) in file %s\n' %
@@ -5894,6 +6046,7 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
5894
6046
 
5895
6047
  _SetVerboseLevel(vlevel)
5896
6048
  _BackupFilters()
6049
+ old_errors = _cpplint_state.error_count
5897
6050
 
5898
6051
  if not ProcessConfigOverrides(filename):
5899
6052
  _RestoreFilters()
@@ -5962,7 +6115,10 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
5962
6115
  Error(filename, linenum, 'whitespace/newline', 1,
5963
6116
  'Unexpected \\r (^M) found; better to use only \\n')
5964
6117
 
5965
- sys.stderr.write('Done processing %s\n' % filename)
6118
+ # Suppress printing anything if --quiet was passed unless the error
6119
+ # count has increased after processing this file.
6120
+ if not _cpplint_state.quiet or old_errors != _cpplint_state.error_count:
6121
+ sys.stdout.write('Done processing %s\n' % filename)
5966
6122
  _RestoreFilters()
5967
6123
 
5968
6124
 
@@ -6006,13 +6162,15 @@ def ParseArguments(args):
6006
6162
  'root=',
6007
6163
  'linelength=',
6008
6164
  'extensions=',
6009
- 'project_root='])
6165
+ 'headers=',
6166
+ 'quiet'])
6010
6167
  except getopt.GetoptError:
6011
6168
  PrintUsage('Invalid arguments.')
6012
6169
 
6013
6170
  verbosity = _VerboseLevel()
6014
6171
  output_format = _OutputFormat()
6015
6172
  filters = ''
6173
+ quiet = _Quiet()
6016
6174
  counting_style = ''
6017
6175
 
6018
6176
  for (opt, val) in opts:
@@ -6022,6 +6180,8 @@ def ParseArguments(args):
6022
6180
  if val not in ('emacs', 'vs7', 'eclipse'):
6023
6181
  PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.')
6024
6182
  output_format = val
6183
+ elif opt == '--quiet':
6184
+ quiet = True
6025
6185
  elif opt == '--verbose':
6026
6186
  verbosity = int(val)
6027
6187
  elif opt == '--filter':
@@ -6035,11 +6195,6 @@ def ParseArguments(args):
6035
6195
  elif opt == '--root':
6036
6196
  global _root
6037
6197
  _root = val
6038
- elif opt == '--project_root':
6039
- global _project_root
6040
- _project_root = val
6041
- if not os.path.isabs(_project_root):
6042
- PrintUsage('Project root must be an absolute path.')
6043
6198
  elif opt == '--linelength':
6044
6199
  global _line_length
6045
6200
  try:
@@ -6052,11 +6207,14 @@ def ParseArguments(args):
6052
6207
  _valid_extensions = set(val.split(','))
6053
6208
  except ValueError:
6054
6209
  PrintUsage('Extensions must be comma separated list.')
6210
+ elif opt == '--headers':
6211
+ ProcessHppHeadersOption(val)
6055
6212
 
6056
6213
  if not filenames:
6057
6214
  PrintUsage('No files were specified.')
6058
6215
 
6059
6216
  _SetOutputFormat(output_format)
6217
+ _SetQuiet(quiet)
6060
6218
  _SetVerboseLevel(verbosity)
6061
6219
  _SetFilters(filters)
6062
6220
  _SetCountingStyle(counting_style)
@@ -6077,7 +6235,9 @@ def main():
6077
6235
  _cpplint_state.ResetErrorCounts()
6078
6236
  for filename in filenames:
6079
6237
  ProcessFile(filename, _cpplint_state.verbose_level)
6080
- _cpplint_state.PrintErrorCounts()
6238
+ # If --quiet is passed, suppress printing error count unless there are errors.
6239
+ if not _cpplint_state.quiet or _cpplint_state.error_count > 0:
6240
+ _cpplint_state.PrintErrorCounts()
6081
6241
 
6082
6242
  sys.exit(_cpplint_state.error_count > 0)
6083
6243