libv8 7.3.492.27.1 → 8.4.255.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (718) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +11 -14
  4. data/CHANGELOG.md +10 -0
  5. data/README.md +10 -11
  6. data/Rakefile +30 -36
  7. data/ext/libv8/builder.rb +1 -1
  8. data/lib/libv8/version.rb +1 -1
  9. data/libv8.gemspec +1 -3
  10. data/vendor/depot_tools/{cipd.ps1 → .cipd_impl.ps1} +0 -0
  11. data/vendor/depot_tools/.gitattributes +1 -1
  12. data/vendor/depot_tools/.gitignore +7 -2
  13. data/vendor/depot_tools/.style.yapf +3 -1
  14. data/vendor/depot_tools/.vpython +55 -0
  15. data/vendor/depot_tools/.vpython3 +23 -0
  16. data/vendor/depot_tools/CROS_OWNERS +3 -1
  17. data/vendor/depot_tools/GOMA_OWNERS +9 -0
  18. data/vendor/depot_tools/LUCI_OWNERS +5 -0
  19. data/vendor/depot_tools/OWNERS +21 -6
  20. data/vendor/depot_tools/PRESUBMIT.py +35 -18
  21. data/vendor/depot_tools/README.git-cl.md +0 -14
  22. data/vendor/depot_tools/README.md +1 -1
  23. data/vendor/depot_tools/WATCHLISTS +2 -2
  24. data/vendor/depot_tools/auth.py +60 -772
  25. data/vendor/depot_tools/autoninja +12 -6
  26. data/vendor/depot_tools/autoninja.bat +14 -6
  27. data/vendor/depot_tools/autoninja.py +64 -27
  28. data/vendor/depot_tools/bb +1 -1
  29. data/vendor/depot_tools/bootstrap/{win/README.md → README.md} +28 -14
  30. data/vendor/depot_tools/bootstrap/{win/win_tools.py → bootstrap.py} +60 -43
  31. data/vendor/depot_tools/bootstrap/{win/git-bash.template.sh → git-bash.template.sh} +1 -1
  32. data/vendor/depot_tools/bootstrap/{win/git.template.bat → git.template.bat} +0 -0
  33. data/vendor/depot_tools/bootstrap/manifest.txt +27 -0
  34. data/vendor/depot_tools/bootstrap/manifest_bleeding_edge.txt +27 -0
  35. data/vendor/depot_tools/bootstrap/{win/profile.d.python.sh → profile.d.python.sh} +0 -0
  36. data/vendor/depot_tools/bootstrap/{win/python27.bleeding_edge.bat → python27.bat} +0 -0
  37. data/vendor/depot_tools/bootstrap/{win/python27.new.bat → python3.bat} +3 -3
  38. data/vendor/depot_tools/bootstrap/{win/win_tools.bat → win_tools.bat} +21 -16
  39. data/vendor/depot_tools/bootstrap_python3 +35 -0
  40. data/vendor/depot_tools/cbuildbot +1 -1
  41. data/vendor/depot_tools/chrome_set_ver +1 -1
  42. data/vendor/depot_tools/cipd +43 -39
  43. data/vendor/depot_tools/cipd.bat +2 -2
  44. data/vendor/depot_tools/cipd_client_version +1 -1
  45. data/vendor/depot_tools/cipd_client_version.digests +15 -14
  46. data/vendor/depot_tools/cipd_manifest.txt +31 -8
  47. data/vendor/depot_tools/cipd_manifest.versions +278 -158
  48. data/vendor/depot_tools/cit.py +9 -7
  49. data/vendor/depot_tools/clang_format.py +4 -1
  50. data/vendor/depot_tools/clang_format_merge_driver.py +10 -8
  51. data/vendor/depot_tools/compile_single_file.py +7 -2
  52. data/vendor/depot_tools/cpplint.py +51 -45
  53. data/vendor/depot_tools/cros +87 -0
  54. data/vendor/depot_tools/cros_sdk +1 -1
  55. data/vendor/depot_tools/crosjobs +13 -0
  56. data/vendor/depot_tools/detect_host_arch.py +0 -1
  57. data/vendor/depot_tools/dirmd +12 -0
  58. data/vendor/depot_tools/dirmd.bat +7 -0
  59. data/vendor/depot_tools/download_from_google_storage.py +47 -27
  60. data/vendor/depot_tools/ensure_bootstrap +14 -0
  61. data/vendor/depot_tools/fetch +14 -1
  62. data/vendor/depot_tools/fetch.bat +14 -1
  63. data/vendor/depot_tools/fetch.py +5 -7
  64. data/vendor/depot_tools/fetch_configs/chromium.py +6 -4
  65. data/vendor/depot_tools/fetch_configs/devtools-frontend.py +44 -0
  66. data/vendor/depot_tools/fetch_configs/ios_internal.py +10 -19
  67. data/vendor/depot_tools/fix_encoding.py +19 -5
  68. data/vendor/depot_tools/gclient +28 -12
  69. data/vendor/depot_tools/gclient-new-workdir.py +2 -0
  70. data/vendor/depot_tools/gclient.bat +18 -1
  71. data/vendor/depot_tools/gclient.py +160 -119
  72. data/vendor/depot_tools/gclient_eval.py +119 -107
  73. data/vendor/depot_tools/gclient_paths.py +67 -57
  74. data/vendor/depot_tools/gclient_scm.py +181 -159
  75. data/vendor/depot_tools/gclient_utils.py +177 -124
  76. data/vendor/depot_tools/gerrit_client.py +21 -13
  77. data/vendor/depot_tools/gerrit_util.py +188 -228
  78. data/vendor/depot_tools/git-cache +1 -1
  79. data/vendor/depot_tools/git-cl +1 -1
  80. data/vendor/depot_tools/git-drover +1 -1
  81. data/vendor/depot_tools/git-find-releases +1 -1
  82. data/vendor/depot_tools/git-footers +1 -1
  83. data/vendor/depot_tools/git-freeze +1 -1
  84. data/vendor/depot_tools/git-hyper-blame +1 -1
  85. data/vendor/depot_tools/git-map +1 -1
  86. data/vendor/depot_tools/git-map-branches +1 -1
  87. data/vendor/depot_tools/git-mark-merge-base +1 -1
  88. data/vendor/depot_tools/git-nav-downstream +1 -1
  89. data/vendor/depot_tools/git-new-branch +1 -1
  90. data/vendor/depot_tools/git-number +1 -1
  91. data/vendor/depot_tools/git-rebase-update +1 -1
  92. data/vendor/depot_tools/git-rename-branch +1 -1
  93. data/vendor/depot_tools/git-reparent-branch +1 -1
  94. data/vendor/depot_tools/git-retry +1 -1
  95. data/vendor/depot_tools/git-squash-branch +1 -1
  96. data/vendor/depot_tools/git-thaw +1 -1
  97. data/vendor/depot_tools/git-upstream-diff +1 -1
  98. data/vendor/depot_tools/git_cache.py +255 -360
  99. data/vendor/depot_tools/git_cl.py +1562 -2059
  100. data/vendor/depot_tools/git_cl_completion.sh +16 -2
  101. data/vendor/depot_tools/git_common.py +77 -32
  102. data/vendor/depot_tools/git_drover.py +17 -8
  103. data/vendor/depot_tools/git_find_releases.py +11 -9
  104. data/vendor/depot_tools/git_footers.py +13 -9
  105. data/vendor/depot_tools/git_freezer.py +3 -1
  106. data/vendor/depot_tools/git_hyper_blame.py +25 -32
  107. data/vendor/depot_tools/git_map.py +115 -93
  108. data/vendor/depot_tools/git_map_branches.py +11 -10
  109. data/vendor/depot_tools/git_mark_merge_base.py +8 -6
  110. data/vendor/depot_tools/git_nav_downstream.py +9 -6
  111. data/vendor/depot_tools/git_new_branch.py +39 -33
  112. data/vendor/depot_tools/git_number.py +28 -17
  113. data/vendor/depot_tools/git_rebase_update.py +50 -49
  114. data/vendor/depot_tools/git_rename_branch.py +2 -2
  115. data/vendor/depot_tools/git_reparent_branch.py +8 -6
  116. data/vendor/depot_tools/git_upstream_diff.py +4 -2
  117. data/vendor/depot_tools/gn.py +6 -4
  118. data/vendor/depot_tools/goma_auth +12 -0
  119. data/vendor/depot_tools/goma_auth.bat +8 -0
  120. data/vendor/depot_tools/goma_ctl +12 -0
  121. data/vendor/depot_tools/goma_ctl.bat +8 -0
  122. data/vendor/depot_tools/gsutil.py +5 -2
  123. data/vendor/depot_tools/gsutil.py.bat +8 -0
  124. data/vendor/depot_tools/gsutil.vpython +3 -1
  125. data/vendor/depot_tools/infra/config/OWNERS +2 -2
  126. data/vendor/depot_tools/infra/config/recipes.cfg +3 -2
  127. data/vendor/depot_tools/led +1 -1
  128. data/vendor/depot_tools/lockfile.py +116 -0
  129. data/vendor/depot_tools/luci-auth +1 -1
  130. data/vendor/depot_tools/lucicfg +1 -1
  131. data/vendor/depot_tools/mac_toolchain +1 -1
  132. data/vendor/depot_tools/man/html/depot_tools.html +1 -1
  133. data/vendor/depot_tools/man/html/depot_tools_tutorial.html +31 -25
  134. data/vendor/depot_tools/man/html/git-cl.html +1 -1
  135. data/vendor/depot_tools/man/html/git-drover.html +18 -18
  136. data/vendor/depot_tools/man/html/git-footers.html +1 -1
  137. data/vendor/depot_tools/man/html/git-freeze.html +3 -3
  138. data/vendor/depot_tools/man/html/git-hyper-blame.html +1 -1
  139. data/vendor/depot_tools/man/html/git-map-branches.html +2 -2
  140. data/vendor/depot_tools/man/html/git-map.html +1 -1
  141. data/vendor/depot_tools/man/html/git-mark-merge-base.html +1 -1
  142. data/vendor/depot_tools/man/html/git-nav-downstream.html +3 -3
  143. data/vendor/depot_tools/man/html/git-nav-upstream.html +12 -6
  144. data/vendor/depot_tools/man/html/git-new-branch.html +1 -1
  145. data/vendor/depot_tools/man/html/git-rebase-update.html +20 -1
  146. data/vendor/depot_tools/man/html/git-rename-branch.html +1 -1
  147. data/vendor/depot_tools/man/html/git-reparent-branch.html +1 -1
  148. data/vendor/depot_tools/man/html/git-retry.html +1 -1
  149. data/vendor/depot_tools/man/html/git-squash-branch.html +1 -1
  150. data/vendor/depot_tools/man/html/git-thaw.html +1 -1
  151. data/vendor/depot_tools/man/html/git-upstream-diff.html +10 -6
  152. data/vendor/depot_tools/man/man1/git-cl.1 +4 -4
  153. data/vendor/depot_tools/man/man1/git-drover.1 +21 -21
  154. data/vendor/depot_tools/man/man1/git-footers.1 +4 -4
  155. data/vendor/depot_tools/man/man1/git-freeze.1 +6 -6
  156. data/vendor/depot_tools/man/man1/git-hyper-blame.1 +4 -4
  157. data/vendor/depot_tools/man/man1/git-map-branches.1 +4 -4
  158. data/vendor/depot_tools/man/man1/git-map.1 +4 -4
  159. data/vendor/depot_tools/man/man1/git-mark-merge-base.1 +4 -4
  160. data/vendor/depot_tools/man/man1/git-nav-downstream.1 +6 -6
  161. data/vendor/depot_tools/man/man1/git-nav-upstream.1 +15 -9
  162. data/vendor/depot_tools/man/man1/git-new-branch.1 +3 -3
  163. data/vendor/depot_tools/man/man1/git-rebase-update.1 +14 -4
  164. data/vendor/depot_tools/man/man1/git-rename-branch.1 +4 -4
  165. data/vendor/depot_tools/man/man1/git-reparent-branch.1 +4 -4
  166. data/vendor/depot_tools/man/man1/git-retry.1 +4 -4
  167. data/vendor/depot_tools/man/man1/git-squash-branch.1 +4 -4
  168. data/vendor/depot_tools/man/man1/git-thaw.1 +4 -4
  169. data/vendor/depot_tools/man/man1/git-upstream-diff.1 +7 -13
  170. data/vendor/depot_tools/man/man7/depot_tools.7 +4 -4
  171. data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +31 -25
  172. data/vendor/depot_tools/man/src/common_demo_functions.sh +2 -2
  173. data/vendor/depot_tools/man/src/depot_tools_tutorial.txt +3 -3
  174. data/vendor/depot_tools/man/src/filter_demo_output.py +4 -2
  175. data/vendor/depot_tools/man/src/git-new-branch.txt +2 -1
  176. data/vendor/depot_tools/man/src/git-rebase-update.txt +8 -1
  177. data/vendor/depot_tools/metrics.README.md +8 -5
  178. data/vendor/depot_tools/metrics.py +7 -6
  179. data/vendor/depot_tools/metrics_utils.py +4 -14
  180. data/vendor/depot_tools/my_activity.py +85 -251
  181. data/vendor/depot_tools/ninja +1 -0
  182. data/vendor/depot_tools/ninja-mac +0 -0
  183. data/vendor/depot_tools/ninjalog_uploader.py +146 -145
  184. data/vendor/depot_tools/ninjalog_uploader_wrapper.py +69 -60
  185. data/vendor/depot_tools/owners.py +156 -43
  186. data/vendor/depot_tools/owners_finder.py +28 -14
  187. data/vendor/depot_tools/post_build_ninja_summary.py +76 -48
  188. data/vendor/depot_tools/presubmit_canned_checks.py +293 -106
  189. data/vendor/depot_tools/presubmit_support.py +527 -333
  190. data/vendor/depot_tools/prpc +1 -1
  191. data/vendor/depot_tools/pylint +2 -12
  192. data/vendor/depot_tools/pylint-1.5 +78 -0
  193. data/vendor/depot_tools/pylint-1.6 +78 -0
  194. data/vendor/depot_tools/pylint-1.7 +78 -0
  195. data/vendor/depot_tools/pylint-1.8 +78 -0
  196. data/vendor/depot_tools/pylint-1.9 +78 -0
  197. data/vendor/depot_tools/{depot-tools-auth.bat → pylint.bat} +2 -2
  198. data/vendor/depot_tools/pylint_main.py +45 -0
  199. data/vendor/depot_tools/pylintrc +14 -1
  200. data/vendor/depot_tools/python-bin/python3 +7 -0
  201. data/vendor/depot_tools/python_runner.sh +13 -8
  202. data/vendor/depot_tools/rdb +12 -0
  203. data/vendor/depot_tools/rdb.bat +7 -0
  204. data/vendor/depot_tools/recipes/OWNERS +0 -1
  205. data/vendor/depot_tools/recipes/README.recipes.md +218 -151
  206. data/vendor/depot_tools/recipes/recipe_modules/OWNERS +1 -1
  207. data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +17 -16
  208. data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +127 -78
  209. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic.json +19 -4
  210. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_luci.json +18 -3
  211. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_with_branch_heads.json +19 -4
  212. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/clobber.json +29 -8
  213. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +28 -10
  214. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_rebase_patch_ref.json +29 -8
  215. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_reset.json +29 -8
  216. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/input_commit_with_id_without_repo.json +29 -8
  217. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/multiple_patch_refs.json +29 -8
  218. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_apply_patch_on_gclient.json +35 -10
  219. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{with_manifest_name.json → no_cp_checkout_HEAD.json} +25 -15
  220. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_a_branch_head.json +65 -0
  221. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_a_specific_commit.json +65 -0
  222. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_master.json +65 -0
  223. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/refs.json +29 -8
  224. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/reset_root_solution_revision.json +29 -8
  225. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/resolve_chromium_fixed_version.json +117 -0
  226. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +17 -11
  227. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +41 -10
  228. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +24 -11
  229. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle.json +35 -10
  230. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_branch_heads.json +35 -10
  231. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_feature_branch.json +38 -11
  232. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8_feature_branch.json +36 -11
  233. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_webrtc.json +35 -10
  234. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +35 -10
  235. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +35 -10
  236. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/unrecognized_commit_repo.json +0 -5
  237. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_tags.json +29 -8
  238. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +95 -22
  239. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +187 -114
  240. data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +2 -2
  241. data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/do_not_retry_patch_failures_in_cq.py +42 -0
  242. data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/ensure_checkout.py +1 -0
  243. data/vendor/depot_tools/recipes/recipe_modules/cipd/__init__.py +0 -1
  244. data/vendor/depot_tools/recipes/recipe_modules/cipd/api.py +2 -2
  245. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic.json +0 -1
  246. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic_pkg.json +0 -1
  247. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-failed.json +2 -4
  248. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-many-instances.json +0 -1
  249. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/mac64.json +0 -1
  250. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_file.json +26 -6
  251. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_mode.json +23 -5
  252. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_verfile.json +23 -5
  253. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/win64.json +0 -1
  254. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk arch.json +0 -1
  255. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk bits.json +0 -1
  256. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_32.json +0 -1
  257. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_64.json +0 -1
  258. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_32.json +0 -1
  259. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_64.json +0 -1
  260. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_mips_64.json +0 -1
  261. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/mac_intel_64.json +0 -1
  262. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_32.json +0 -1
  263. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_64.json +0 -1
  264. data/vendor/depot_tools/recipes/recipe_modules/cipd/test_api.py +1 -1
  265. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/api.py +4 -1
  266. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json +4 -2
  267. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic_luci.json +3 -1
  268. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/win.json +4 -2
  269. data/vendor/depot_tools/recipes/recipe_modules/gclient/__init__.py +2 -1
  270. data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +82 -13
  271. data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +23 -11
  272. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +3 -4
  273. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +3 -6
  274. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +3 -4
  275. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +7 -7
  276. data/vendor/depot_tools/recipes/recipe_modules/gclient/resources/diff_deps.py +16 -0
  277. data/vendor/depot_tools/recipes/recipe_modules/gclient/test_api.py +4 -0
  278. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/basic.json +55 -0
  279. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/dont have revision yet.json +84 -0
  280. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/no change, exception.json +83 -0
  281. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/windows.json +55 -0
  282. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.py +88 -0
  283. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/patch_project.py +9 -21
  284. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/sync_failure.py +24 -0
  285. data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +2 -1
  286. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +7 -12
  287. data/vendor/depot_tools/recipes/recipe_modules/git/__init__.py +0 -2
  288. data/vendor/depot_tools/recipes/recipe_modules/git/api.py +9 -17
  289. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic.json +2 -8
  290. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_branch.json +2 -8
  291. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_file_name.json +2 -8
  292. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_hash.json +2 -8
  293. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_ref.json +2 -8
  294. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_submodule_update_force.json +2 -8
  295. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_tags.json +2 -8
  296. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/can_fail_build.json +3 -13
  297. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cannot_fail_build.json +2 -8
  298. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cat-file_test.json +4 -12
  299. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_delta.json +2 -10
  300. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_failed.json +1 -7
  301. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output.json +1 -7
  302. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output_fails_build.json +0 -8
  303. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/curl_trace_file.json +3 -10
  304. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/git-cache-checkout.json +3 -11
  305. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/platform_win.json +2 -8
  306. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/rebase_failed.json +3 -13
  307. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/remote_not_origin.json +2 -8
  308. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/set_got_revision.json +2 -8
  309. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.py +0 -5
  310. data/vendor/depot_tools/recipes/recipe_modules/git_cl/__init__.py +1 -1
  311. data/vendor/depot_tools/recipes/recipe_modules/git_cl/api.py +7 -13
  312. data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.expected/basic.json +21 -16
  313. data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.py +1 -2
  314. data/vendor/depot_tools/recipes/recipe_modules/gitiles/api.py +1 -1
  315. data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.expected/basic.json +0 -1
  316. data/vendor/depot_tools/recipes/recipe_modules/gitiles/resources/gerrit_client.py +2 -2
  317. data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.expected/basic.json +0 -1
  318. data/vendor/depot_tools/recipes/recipe_modules/gsutil/api.py +23 -8
  319. data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.expected/basic.json +52 -1
  320. data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.py +15 -0
  321. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/__init__.py +1 -0
  322. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/api.py +32 -8
  323. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/ancient_version.json +83 -0
  324. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/automatic_version.json +83 -0
  325. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/explicit_version.json +83 -0
  326. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/linux.json +0 -1
  327. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/mac.json +5 -4
  328. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/win.json +0 -1
  329. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.py +21 -2
  330. data/vendor/depot_tools/recipes/recipe_modules/presubmit/__init__.py +20 -0
  331. data/vendor/depot_tools/recipes/recipe_modules/presubmit/api.py +235 -3
  332. data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.expected/basic.json +13 -5
  333. data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.py +5 -1
  334. data/vendor/depot_tools/recipes/recipe_modules/presubmit/properties.proto +14 -0
  335. data/vendor/depot_tools/recipes/recipe_modules/presubmit/test_api.py +19 -0
  336. data/vendor/depot_tools/recipes/recipe_modules/presubmit/tests/execute.py +247 -0
  337. data/vendor/depot_tools/recipes/recipe_modules/presubmit/tests/prepare.py +49 -0
  338. data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +33 -45
  339. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/basic_tags.json +0 -1
  340. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json +64 -21
  341. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch_and_target_ref.json +64 -21
  342. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +1 -22
  343. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch_new.json +1 -22
  344. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +5 -32
  345. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_fetch_ref_timeout.py +29 -0
  346. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_owner.expected/basic.json +5 -0
  347. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_owner.py +22 -0
  348. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_target_ref.py +32 -0
  349. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/linux.json +0 -1
  350. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/mac.json +0 -1
  351. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/win.json +2 -1
  352. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.py +1 -6
  353. data/vendor/depot_tools/recipes/recipes.py +49 -28
  354. data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.expected/basic.json +11 -6
  355. data/vendor/depot_tools/repo +698 -540
  356. data/vendor/depot_tools/roll-dep +14 -1
  357. data/vendor/depot_tools/roll-dep.bat +10 -1
  358. data/vendor/depot_tools/roll_dep.py +15 -10
  359. data/vendor/depot_tools/scm.py +95 -75
  360. data/vendor/depot_tools/setup_color.py +36 -2
  361. data/vendor/depot_tools/split_cl.py +44 -32
  362. data/vendor/depot_tools/subcommand.py +6 -6
  363. data/vendor/depot_tools/subprocess2.py +38 -322
  364. data/vendor/depot_tools/third_party/colorama/LICENSE.txt +0 -1
  365. data/vendor/depot_tools/third_party/colorama/README.chromium +4 -5
  366. data/vendor/depot_tools/third_party/colorama/README.rst +346 -0
  367. data/vendor/depot_tools/third_party/colorama/__init__.py +3 -4
  368. data/vendor/depot_tools/third_party/colorama/ansi.py +82 -30
  369. data/vendor/depot_tools/third_party/colorama/ansitowin32.py +105 -37
  370. data/vendor/depot_tools/third_party/colorama/initialise.py +39 -15
  371. data/vendor/depot_tools/third_party/colorama/win32.py +46 -28
  372. data/vendor/depot_tools/third_party/colorama/winterm.py +80 -31
  373. data/vendor/depot_tools/update_depot_tools +18 -8
  374. data/vendor/depot_tools/update_depot_tools.bat +19 -15
  375. data/vendor/depot_tools/upload_metrics.py +7 -6
  376. data/vendor/depot_tools/upload_to_google_storage.py +23 -16
  377. data/vendor/depot_tools/vpython +4 -4
  378. data/vendor/depot_tools/vpython.bat +1 -1
  379. data/vendor/depot_tools/vpython3 +55 -0
  380. data/vendor/depot_tools/vpython3.bat +12 -0
  381. data/vendor/depot_tools/watchlists.py +14 -11
  382. data/vendor/depot_tools/weekly +4 -2
  383. data/vendor/depot_tools/win32imports.py +61 -0
  384. data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +49 -41
  385. data/vendor/depot_tools/win_toolchain/package_from_installed.py +142 -149
  386. data/vendor/depot_tools/wtf +5 -3
  387. data/vendor/depot_tools/yapf +5 -1
  388. metadata +68 -343
  389. data/vendor/depot_tools/README.testing +0 -23
  390. data/vendor/depot_tools/annotated_gclient.py +0 -89
  391. data/vendor/depot_tools/appengine_mapper.py +0 -23
  392. data/vendor/depot_tools/bootstrap/win/manifest.txt +0 -20
  393. data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +0 -20
  394. data/vendor/depot_tools/bootstrap/win/pylint.new.bat +0 -7
  395. data/vendor/depot_tools/buildbucket.py +0 -186
  396. data/vendor/depot_tools/checkout.py +0 -431
  397. data/vendor/depot_tools/cros +0 -1
  398. data/vendor/depot_tools/dart_format.py +0 -58
  399. data/vendor/depot_tools/depot-tools-auth +0 -8
  400. data/vendor/depot_tools/depot-tools-auth.py +0 -102
  401. data/vendor/depot_tools/my_reviews.py +0 -396
  402. data/vendor/depot_tools/patch.py +0 -548
  403. data/vendor/depot_tools/pylint.py +0 -30
  404. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +0 -239
  405. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_luci.json +0 -222
  406. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/__init__.py +0 -4
  407. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/api.py +0 -29
  408. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/basic.json +0 -15
  409. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_linux.json +0 -15
  410. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_mac.json +0 -15
  411. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_win.json +0 -15
  412. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_linux.json +0 -15
  413. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_mac.json +0 -15
  414. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_win.json +0 -15
  415. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_linux.json +0 -15
  416. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_mac.json +0 -15
  417. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_win.json +0 -15
  418. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.py +0 -33
  419. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/path_config.py +0 -66
  420. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/set_failure_hash_with_no_steps.json +0 -11
  421. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch.json +0 -45
  422. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch_luci.json +0 -45
  423. data/vendor/depot_tools/rietveld.py +0 -779
  424. data/vendor/depot_tools/roll-dep-svn +0 -8
  425. data/vendor/depot_tools/roll-dep-svn.bat +0 -12
  426. data/vendor/depot_tools/roll_dep_svn.py +0 -430
  427. data/vendor/depot_tools/support/chromite_wrapper +0 -96
  428. data/vendor/depot_tools/third_party/boto/LICENSE +0 -18
  429. data/vendor/depot_tools/third_party/boto/README.chromium +0 -43
  430. data/vendor/depot_tools/third_party/boto/README.rst +0 -163
  431. data/vendor/depot_tools/third_party/boto/__init__.py +0 -793
  432. data/vendor/depot_tools/third_party/boto/auth.py +0 -682
  433. data/vendor/depot_tools/third_party/boto/auth_handler.py +0 -58
  434. data/vendor/depot_tools/third_party/boto/cacerts/__init__.py +0 -22
  435. data/vendor/depot_tools/third_party/boto/cacerts/cacerts.txt +0 -2183
  436. data/vendor/depot_tools/third_party/boto/compat.py +0 -28
  437. data/vendor/depot_tools/third_party/boto/connection.py +0 -1081
  438. data/vendor/depot_tools/third_party/boto/contrib/__init__.py +0 -22
  439. data/vendor/depot_tools/third_party/boto/contrib/ymlmessage.py +0 -52
  440. data/vendor/depot_tools/third_party/boto/core/README +0 -58
  441. data/vendor/depot_tools/third_party/boto/core/__init__.py +0 -23
  442. data/vendor/depot_tools/third_party/boto/core/auth.py +0 -78
  443. data/vendor/depot_tools/third_party/boto/core/credentials.py +0 -154
  444. data/vendor/depot_tools/third_party/boto/core/dictresponse.py +0 -178
  445. data/vendor/depot_tools/third_party/boto/core/service.py +0 -67
  446. data/vendor/depot_tools/third_party/boto/datapipeline/__init__.py +0 -0
  447. data/vendor/depot_tools/third_party/boto/datapipeline/exceptions.py +0 -42
  448. data/vendor/depot_tools/third_party/boto/datapipeline/layer1.py +0 -546
  449. data/vendor/depot_tools/third_party/boto/ecs/__init__.py +0 -90
  450. data/vendor/depot_tools/third_party/boto/ecs/item.py +0 -153
  451. data/vendor/depot_tools/third_party/boto/exception.py +0 -476
  452. data/vendor/depot_tools/third_party/boto/file/README +0 -49
  453. data/vendor/depot_tools/third_party/boto/file/__init__.py +0 -28
  454. data/vendor/depot_tools/third_party/boto/file/bucket.py +0 -112
  455. data/vendor/depot_tools/third_party/boto/file/connection.py +0 -33
  456. data/vendor/depot_tools/third_party/boto/file/key.py +0 -199
  457. data/vendor/depot_tools/third_party/boto/file/simpleresultset.py +0 -30
  458. data/vendor/depot_tools/third_party/boto/fps/__init__.py +0 -21
  459. data/vendor/depot_tools/third_party/boto/fps/connection.py +0 -369
  460. data/vendor/depot_tools/third_party/boto/fps/exception.py +0 -344
  461. data/vendor/depot_tools/third_party/boto/fps/response.py +0 -175
  462. data/vendor/depot_tools/third_party/boto/gs/__init__.py +0 -22
  463. data/vendor/depot_tools/third_party/boto/gs/acl.py +0 -304
  464. data/vendor/depot_tools/third_party/boto/gs/bucket.py +0 -870
  465. data/vendor/depot_tools/third_party/boto/gs/bucketlistresultset.py +0 -64
  466. data/vendor/depot_tools/third_party/boto/gs/connection.py +0 -103
  467. data/vendor/depot_tools/third_party/boto/gs/cors.py +0 -169
  468. data/vendor/depot_tools/third_party/boto/gs/key.py +0 -704
  469. data/vendor/depot_tools/third_party/boto/gs/resumable_upload_handler.py +0 -659
  470. data/vendor/depot_tools/third_party/boto/gs/user.py +0 -54
  471. data/vendor/depot_tools/third_party/boto/handler.py +0 -44
  472. data/vendor/depot_tools/third_party/boto/https_connection.py +0 -124
  473. data/vendor/depot_tools/third_party/boto/jsonresponse.py +0 -163
  474. data/vendor/depot_tools/third_party/boto/manage/__init__.py +0 -23
  475. data/vendor/depot_tools/third_party/boto/manage/cmdshell.py +0 -241
  476. data/vendor/depot_tools/third_party/boto/manage/propget.py +0 -64
  477. data/vendor/depot_tools/third_party/boto/manage/server.py +0 -556
  478. data/vendor/depot_tools/third_party/boto/manage/task.py +0 -175
  479. data/vendor/depot_tools/third_party/boto/manage/test_manage.py +0 -34
  480. data/vendor/depot_tools/third_party/boto/manage/volume.py +0 -420
  481. data/vendor/depot_tools/third_party/boto/mashups/__init__.py +0 -23
  482. data/vendor/depot_tools/third_party/boto/mashups/interactive.py +0 -97
  483. data/vendor/depot_tools/third_party/boto/mashups/iobject.py +0 -115
  484. data/vendor/depot_tools/third_party/boto/mashups/order.py +0 -211
  485. data/vendor/depot_tools/third_party/boto/mashups/server.py +0 -395
  486. data/vendor/depot_tools/third_party/boto/plugin.py +0 -90
  487. data/vendor/depot_tools/third_party/boto/provider.py +0 -337
  488. data/vendor/depot_tools/third_party/boto/pyami/__init__.py +0 -22
  489. data/vendor/depot_tools/third_party/boto/pyami/bootstrap.py +0 -134
  490. data/vendor/depot_tools/third_party/boto/pyami/config.py +0 -229
  491. data/vendor/depot_tools/third_party/boto/pyami/copybot.cfg +0 -60
  492. data/vendor/depot_tools/third_party/boto/pyami/copybot.py +0 -97
  493. data/vendor/depot_tools/third_party/boto/pyami/helloworld.py +0 -28
  494. data/vendor/depot_tools/third_party/boto/pyami/launch_ami.py +0 -178
  495. data/vendor/depot_tools/third_party/boto/pyami/scriptbase.py +0 -44
  496. data/vendor/depot_tools/third_party/boto/pyami/startup.py +0 -60
  497. data/vendor/depot_tools/third_party/boto/regioninfo.py +0 -63
  498. data/vendor/depot_tools/third_party/boto/resultset.py +0 -169
  499. data/vendor/depot_tools/third_party/boto/roboto/__init__.py +0 -1
  500. data/vendor/depot_tools/third_party/boto/roboto/awsqueryrequest.py +0 -504
  501. data/vendor/depot_tools/third_party/boto/roboto/awsqueryservice.py +0 -121
  502. data/vendor/depot_tools/third_party/boto/roboto/param.py +0 -147
  503. data/vendor/depot_tools/third_party/boto/s3/__init__.py +0 -84
  504. data/vendor/depot_tools/third_party/boto/s3/acl.py +0 -164
  505. data/vendor/depot_tools/third_party/boto/s3/bucket.py +0 -1634
  506. data/vendor/depot_tools/third_party/boto/s3/bucketlistresultset.py +0 -139
  507. data/vendor/depot_tools/third_party/boto/s3/bucketlogging.py +0 -83
  508. data/vendor/depot_tools/third_party/boto/s3/connection.py +0 -540
  509. data/vendor/depot_tools/third_party/boto/s3/cors.py +0 -210
  510. data/vendor/depot_tools/third_party/boto/s3/deletemarker.py +0 -55
  511. data/vendor/depot_tools/third_party/boto/s3/key.py +0 -1712
  512. data/vendor/depot_tools/third_party/boto/s3/keyfile.py +0 -134
  513. data/vendor/depot_tools/third_party/boto/s3/lifecycle.py +0 -231
  514. data/vendor/depot_tools/third_party/boto/s3/multidelete.py +0 -138
  515. data/vendor/depot_tools/third_party/boto/s3/multipart.py +0 -315
  516. data/vendor/depot_tools/third_party/boto/s3/prefix.py +0 -42
  517. data/vendor/depot_tools/third_party/boto/s3/resumable_download_handler.py +0 -339
  518. data/vendor/depot_tools/third_party/boto/s3/tagging.py +0 -71
  519. data/vendor/depot_tools/third_party/boto/s3/user.py +0 -49
  520. data/vendor/depot_tools/third_party/boto/s3/website.py +0 -237
  521. data/vendor/depot_tools/third_party/boto/services/__init__.py +0 -23
  522. data/vendor/depot_tools/third_party/boto/services/bs.py +0 -179
  523. data/vendor/depot_tools/third_party/boto/services/message.py +0 -58
  524. data/vendor/depot_tools/third_party/boto/services/result.py +0 -136
  525. data/vendor/depot_tools/third_party/boto/services/service.py +0 -161
  526. data/vendor/depot_tools/third_party/boto/services/servicedef.py +0 -91
  527. data/vendor/depot_tools/third_party/boto/services/sonofmmm.cfg +0 -43
  528. data/vendor/depot_tools/third_party/boto/services/sonofmmm.py +0 -81
  529. data/vendor/depot_tools/third_party/boto/services/submit.py +0 -88
  530. data/vendor/depot_tools/third_party/boto/ses/__init__.py +0 -54
  531. data/vendor/depot_tools/third_party/boto/ses/connection.py +0 -521
  532. data/vendor/depot_tools/third_party/boto/ses/exceptions.py +0 -77
  533. data/vendor/depot_tools/third_party/boto/storage_uri.py +0 -835
  534. data/vendor/depot_tools/third_party/boto/sts/__init__.py +0 -55
  535. data/vendor/depot_tools/third_party/boto/sts/connection.py +0 -207
  536. data/vendor/depot_tools/third_party/boto/sts/credentials.py +0 -215
  537. data/vendor/depot_tools/third_party/boto/utils.py +0 -927
  538. data/vendor/depot_tools/third_party/colorama/README.txt +0 -304
  539. data/vendor/depot_tools/third_party/fancy_urllib/README +0 -22
  540. data/vendor/depot_tools/third_party/fancy_urllib/__init__.py +0 -460
  541. data/vendor/depot_tools/third_party/logilab/README.chromium +0 -6
  542. data/vendor/depot_tools/third_party/logilab/__init__.py +0 -0
  543. data/vendor/depot_tools/third_party/logilab/astroid/LICENSE.txt +0 -340
  544. data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +0 -11
  545. data/vendor/depot_tools/third_party/logilab/astroid/__init__.py +0 -136
  546. data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +0 -42
  547. data/vendor/depot_tools/third_party/logilab/astroid/arguments.py +0 -233
  548. data/vendor/depot_tools/third_party/logilab/astroid/as_string.py +0 -548
  549. data/vendor/depot_tools/third_party/logilab/astroid/astpeephole.py +0 -86
  550. data/vendor/depot_tools/third_party/logilab/astroid/bases.py +0 -636
  551. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_builtin_inference.py +0 -336
  552. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_dateutil.py +0 -15
  553. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_gi.py +0 -195
  554. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_mechanize.py +0 -18
  555. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_nose.py +0 -82
  556. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_numpy.py +0 -62
  557. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_pytest.py +0 -76
  558. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_qt.py +0 -44
  559. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_six.py +0 -288
  560. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_ssl.py +0 -65
  561. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_stdlib.py +0 -473
  562. data/vendor/depot_tools/third_party/logilab/astroid/builder.py +0 -263
  563. data/vendor/depot_tools/third_party/logilab/astroid/context.py +0 -81
  564. data/vendor/depot_tools/third_party/logilab/astroid/decorators.py +0 -75
  565. data/vendor/depot_tools/third_party/logilab/astroid/exceptions.py +0 -71
  566. data/vendor/depot_tools/third_party/logilab/astroid/inference.py +0 -359
  567. data/vendor/depot_tools/third_party/logilab/astroid/manager.py +0 -267
  568. data/vendor/depot_tools/third_party/logilab/astroid/mixins.py +0 -147
  569. data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +0 -741
  570. data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +0 -1053
  571. data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +0 -87
  572. data/vendor/depot_tools/third_party/logilab/astroid/objects.py +0 -186
  573. data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +0 -470
  574. data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +0 -390
  575. data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +0 -989
  576. data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +0 -1716
  577. data/vendor/depot_tools/third_party/logilab/astroid/test_utils.py +0 -201
  578. data/vendor/depot_tools/third_party/logilab/astroid/transforms.py +0 -96
  579. data/vendor/depot_tools/third_party/logilab/astroid/util.py +0 -89
  580. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/LICENSE +0 -19
  581. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/README.chromium +0 -11
  582. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/__init__.py +0 -20
  583. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/cext.c +0 -1421
  584. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/compat.py +0 -9
  585. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/simple.py +0 -246
  586. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/slots.py +0 -414
  587. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/utils.py +0 -13
  588. data/vendor/depot_tools/third_party/logilab/wrapt/LICENSE +0 -24
  589. data/vendor/depot_tools/third_party/logilab/wrapt/README.chromium +0 -11
  590. data/vendor/depot_tools/third_party/logilab/wrapt/__init__.py +0 -19
  591. data/vendor/depot_tools/third_party/logilab/wrapt/_wrappers.c +0 -2729
  592. data/vendor/depot_tools/third_party/logilab/wrapt/arguments.py +0 -96
  593. data/vendor/depot_tools/third_party/logilab/wrapt/decorators.py +0 -512
  594. data/vendor/depot_tools/third_party/logilab/wrapt/importer.py +0 -228
  595. data/vendor/depot_tools/third_party/logilab/wrapt/wrappers.py +0 -901
  596. data/vendor/depot_tools/third_party/mock/LICENSE.txt +0 -26
  597. data/vendor/depot_tools/third_party/mock/README.chromium +0 -24
  598. data/vendor/depot_tools/third_party/mock/__init__.py +0 -2366
  599. data/vendor/depot_tools/third_party/oauth2client/LICENSE +0 -202
  600. data/vendor/depot_tools/third_party/oauth2client/MODIFICATIONS.diff +0 -66
  601. data/vendor/depot_tools/third_party/oauth2client/README.chromium +0 -15
  602. data/vendor/depot_tools/third_party/oauth2client/__init__.py +0 -5
  603. data/vendor/depot_tools/third_party/oauth2client/anyjson.py +0 -32
  604. data/vendor/depot_tools/third_party/oauth2client/appengine.py +0 -963
  605. data/vendor/depot_tools/third_party/oauth2client/client.py +0 -1363
  606. data/vendor/depot_tools/third_party/oauth2client/clientsecrets.py +0 -153
  607. data/vendor/depot_tools/third_party/oauth2client/crypt.py +0 -377
  608. data/vendor/depot_tools/third_party/oauth2client/django_orm.py +0 -134
  609. data/vendor/depot_tools/third_party/oauth2client/file.py +0 -124
  610. data/vendor/depot_tools/third_party/oauth2client/gce.py +0 -90
  611. data/vendor/depot_tools/third_party/oauth2client/keyring_storage.py +0 -109
  612. data/vendor/depot_tools/third_party/oauth2client/locked_file.py +0 -373
  613. data/vendor/depot_tools/third_party/oauth2client/multistore_file.py +0 -465
  614. data/vendor/depot_tools/third_party/oauth2client/old_run.py +0 -160
  615. data/vendor/depot_tools/third_party/oauth2client/tools.py +0 -243
  616. data/vendor/depot_tools/third_party/oauth2client/util.py +0 -196
  617. data/vendor/depot_tools/third_party/oauth2client/xsrfutil.py +0 -113
  618. data/vendor/depot_tools/third_party/protobuf26/README.chromium +0 -23
  619. data/vendor/depot_tools/third_party/protobuf26/__init__.py +0 -0
  620. data/vendor/depot_tools/third_party/protobuf26/compiler/__init__.py +0 -0
  621. data/vendor/depot_tools/third_party/protobuf26/compiler/plugin_pb2.py +0 -184
  622. data/vendor/depot_tools/third_party/protobuf26/descriptor.py +0 -849
  623. data/vendor/depot_tools/third_party/protobuf26/descriptor_database.py +0 -137
  624. data/vendor/depot_tools/third_party/protobuf26/descriptor_pb2.py +0 -1522
  625. data/vendor/depot_tools/third_party/protobuf26/descriptor_pool.py +0 -643
  626. data/vendor/depot_tools/third_party/protobuf26/internal/__init__.py +0 -0
  627. data/vendor/depot_tools/third_party/protobuf26/internal/api_implementation.py +0 -89
  628. data/vendor/depot_tools/third_party/protobuf26/internal/containers.py +0 -269
  629. data/vendor/depot_tools/third_party/protobuf26/internal/cpp_message.py +0 -663
  630. data/vendor/depot_tools/third_party/protobuf26/internal/decoder.py +0 -831
  631. data/vendor/depot_tools/third_party/protobuf26/internal/encoder.py +0 -788
  632. data/vendor/depot_tools/third_party/protobuf26/internal/enum_type_wrapper.py +0 -89
  633. data/vendor/depot_tools/third_party/protobuf26/internal/message_listener.py +0 -78
  634. data/vendor/depot_tools/third_party/protobuf26/internal/python_message.py +0 -1247
  635. data/vendor/depot_tools/third_party/protobuf26/internal/type_checkers.py +0 -328
  636. data/vendor/depot_tools/third_party/protobuf26/internal/wire_format.py +0 -268
  637. data/vendor/depot_tools/third_party/protobuf26/message.py +0 -284
  638. data/vendor/depot_tools/third_party/protobuf26/message_factory.py +0 -155
  639. data/vendor/depot_tools/third_party/protobuf26/reflection.py +0 -205
  640. data/vendor/depot_tools/third_party/protobuf26/service.py +0 -226
  641. data/vendor/depot_tools/third_party/protobuf26/service_reflection.py +0 -284
  642. data/vendor/depot_tools/third_party/protobuf26/symbol_database.py +0 -185
  643. data/vendor/depot_tools/third_party/protobuf26/text_encoding.py +0 -110
  644. data/vendor/depot_tools/third_party/protobuf26/text_format.py +0 -873
  645. data/vendor/depot_tools/third_party/pylint.py +0 -37
  646. data/vendor/depot_tools/third_party/pylint/LICENSE.txt +0 -340
  647. data/vendor/depot_tools/third_party/pylint/README.chromium +0 -30
  648. data/vendor/depot_tools/third_party/pylint/__init__.py +0 -46
  649. data/vendor/depot_tools/third_party/pylint/__main__.py +0 -3
  650. data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +0 -80
  651. data/vendor/depot_tools/third_party/pylint/checkers/__init__.py +0 -123
  652. data/vendor/depot_tools/third_party/pylint/checkers/async.py +0 -82
  653. data/vendor/depot_tools/third_party/pylint/checkers/base.py +0 -2010
  654. data/vendor/depot_tools/third_party/pylint/checkers/classes.py +0 -1120
  655. data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +0 -348
  656. data/vendor/depot_tools/third_party/pylint/checkers/exceptions.py +0 -369
  657. data/vendor/depot_tools/third_party/pylint/checkers/format.py +0 -993
  658. data/vendor/depot_tools/third_party/pylint/checkers/imports.py +0 -654
  659. data/vendor/depot_tools/third_party/pylint/checkers/logging.py +0 -258
  660. data/vendor/depot_tools/third_party/pylint/checkers/misc.py +0 -105
  661. data/vendor/depot_tools/third_party/pylint/checkers/newstyle.py +0 -169
  662. data/vendor/depot_tools/third_party/pylint/checkers/python3.py +0 -591
  663. data/vendor/depot_tools/third_party/pylint/checkers/raw_metrics.py +0 -129
  664. data/vendor/depot_tools/third_party/pylint/checkers/similar.py +0 -371
  665. data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +0 -264
  666. data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +0 -280
  667. data/vendor/depot_tools/third_party/pylint/checkers/strings.py +0 -618
  668. data/vendor/depot_tools/third_party/pylint/checkers/typecheck.py +0 -974
  669. data/vendor/depot_tools/third_party/pylint/checkers/utils.py +0 -741
  670. data/vendor/depot_tools/third_party/pylint/checkers/variables.py +0 -1191
  671. data/vendor/depot_tools/third_party/pylint/config.py +0 -820
  672. data/vendor/depot_tools/third_party/pylint/epylint.py +0 -181
  673. data/vendor/depot_tools/third_party/pylint/extensions/__init__.py +0 -0
  674. data/vendor/depot_tools/third_party/pylint/extensions/check_docs.py +0 -311
  675. data/vendor/depot_tools/third_party/pylint/extensions/check_elif.py +0 -62
  676. data/vendor/depot_tools/third_party/pylint/graph.py +0 -179
  677. data/vendor/depot_tools/third_party/pylint/gui.py +0 -531
  678. data/vendor/depot_tools/third_party/pylint/interfaces.py +0 -102
  679. data/vendor/depot_tools/third_party/pylint/lint.py +0 -1381
  680. data/vendor/depot_tools/third_party/pylint/pyreverse/__init__.py +0 -5
  681. data/vendor/depot_tools/third_party/pylint/pyreverse/diadefslib.py +0 -230
  682. data/vendor/depot_tools/third_party/pylint/pyreverse/diagrams.py +0 -258
  683. data/vendor/depot_tools/third_party/pylint/pyreverse/inspector.py +0 -372
  684. data/vendor/depot_tools/third_party/pylint/pyreverse/main.py +0 -147
  685. data/vendor/depot_tools/third_party/pylint/pyreverse/utils.py +0 -210
  686. data/vendor/depot_tools/third_party/pylint/pyreverse/vcgutils.py +0 -198
  687. data/vendor/depot_tools/third_party/pylint/pyreverse/writer.py +0 -198
  688. data/vendor/depot_tools/third_party/pylint/reporters/__init__.py +0 -149
  689. data/vendor/depot_tools/third_party/pylint/reporters/guireporter.py +0 -27
  690. data/vendor/depot_tools/third_party/pylint/reporters/html.py +0 -108
  691. data/vendor/depot_tools/third_party/pylint/reporters/json.py +0 -64
  692. data/vendor/depot_tools/third_party/pylint/reporters/text.py +0 -237
  693. data/vendor/depot_tools/third_party/pylint/reporters/ureports/__init__.py +0 -106
  694. data/vendor/depot_tools/third_party/pylint/reporters/ureports/html_writer.py +0 -93
  695. data/vendor/depot_tools/third_party/pylint/reporters/ureports/nodes.py +0 -181
  696. data/vendor/depot_tools/third_party/pylint/reporters/ureports/text_writer.py +0 -99
  697. data/vendor/depot_tools/third_party/pylint/testutils.py +0 -414
  698. data/vendor/depot_tools/third_party/pylint/utils.py +0 -1148
  699. data/vendor/depot_tools/third_party/pymox/COPYING +0 -202
  700. data/vendor/depot_tools/third_party/pymox/MANIFEST.in +0 -5
  701. data/vendor/depot_tools/third_party/pymox/README +0 -56
  702. data/vendor/depot_tools/third_party/pymox/__init__.py +0 -0
  703. data/vendor/depot_tools/third_party/pymox/mox.py +0 -1643
  704. data/vendor/depot_tools/third_party/pymox/mox_test.py +0 -1708
  705. data/vendor/depot_tools/third_party/pymox/mox_test_helper.py +0 -76
  706. data/vendor/depot_tools/third_party/pymox/setup.py +0 -14
  707. data/vendor/depot_tools/third_party/pymox/stubout.py +0 -142
  708. data/vendor/depot_tools/third_party/pymox/stubout_test.py +0 -47
  709. data/vendor/depot_tools/third_party/pymox/stubout_testee.py +0 -2
  710. data/vendor/depot_tools/third_party/simplejson/LICENSE.txt +0 -19
  711. data/vendor/depot_tools/third_party/simplejson/PKG-INFO +0 -29
  712. data/vendor/depot_tools/third_party/simplejson/__init__.py +0 -437
  713. data/vendor/depot_tools/third_party/simplejson/decoder.py +0 -421
  714. data/vendor/depot_tools/third_party/simplejson/encoder.py +0 -501
  715. data/vendor/depot_tools/third_party/simplejson/ordered_dict.py +0 -119
  716. data/vendor/depot_tools/third_party/simplejson/scanner.py +0 -77
  717. data/vendor/depot_tools/third_party/simplejson/tool.py +0 -39
  718. data/vendor/depot_tools/third_party/upload.py +0 -2565
@@ -6,28 +6,26 @@
6
6
  """Enables directory-specific presubmit checks to run at upload and/or commit.
7
7
  """
8
8
 
9
+ from __future__ import print_function
10
+
9
11
  __version__ = '1.8.0'
10
12
 
11
13
  # TODO(joi) Add caching where appropriate/needed. The API is designed to allow
12
14
  # caching (between all different invocations of presubmit scripts for a given
13
15
  # change). We should add it as our presubmit scripts start feeling slow.
14
16
 
17
+ import argparse
15
18
  import ast # Exposed through the API.
16
19
  import contextlib
17
- import cPickle # Exposed through the API.
18
20
  import cpplint
19
- import cStringIO # Exposed through the API.
20
21
  import fnmatch # Exposed through the API.
21
22
  import glob
22
23
  import inspect
23
24
  import itertools
24
25
  import json # Exposed through the API.
25
26
  import logging
26
- import marshal # Exposed through the API.
27
27
  import multiprocessing
28
- import optparse
29
28
  import os # Somewhat exposed through the API.
30
- import pickle # Exposed through the API.
31
29
  import random
32
30
  import re # Exposed through the API.
33
31
  import signal
@@ -35,11 +33,8 @@ import sys # Parts exposed through API.
35
33
  import tempfile # Exposed through the API.
36
34
  import threading
37
35
  import time
38
- import traceback # Exposed through the API.
39
- import types
36
+ import traceback
40
37
  import unittest # Exposed through the API.
41
- import urllib2 # Exposed through the API.
42
- import urlparse
43
38
  from warnings import warn
44
39
 
45
40
  # Local imports.
@@ -54,26 +49,43 @@ import presubmit_canned_checks
54
49
  import scm
55
50
  import subprocess2 as subprocess # Exposed through the API.
56
51
 
52
+ if sys.version_info.major == 2:
53
+ # TODO(1009814): Expose urllib2 only through urllib_request and urllib_error
54
+ import urllib2 # Exposed through the API.
55
+ import urlparse
56
+ import urllib2 as urllib_request
57
+ import urllib2 as urllib_error
58
+ else:
59
+ import urllib.parse as urlparse
60
+ import urllib.request as urllib_request
61
+ import urllib.error as urllib_error
57
62
 
58
63
  # Ask for feedback only once in program lifetime.
59
64
  _ASKED_FOR_FEEDBACK = False
60
65
 
61
66
 
67
+ def time_time():
68
+ # Use this so that it can be mocked in tests without interfering with python
69
+ # system machinery.
70
+ return time.time()
71
+
72
+
62
73
  class PresubmitFailure(Exception):
63
74
  pass
64
75
 
65
76
 
66
77
  class CommandData(object):
67
- def __init__(self, name, cmd, kwargs, message):
78
+ def __init__(self, name, cmd, kwargs, message, python3=False):
68
79
  self.name = name
69
80
  self.cmd = cmd
70
81
  self.stdin = kwargs.get('stdin', None)
71
- self.kwargs = kwargs
82
+ self.kwargs = kwargs.copy()
72
83
  self.kwargs['stdout'] = subprocess.PIPE
73
84
  self.kwargs['stderr'] = subprocess.STDOUT
74
85
  self.kwargs['stdin'] = subprocess.PIPE
75
86
  self.message = message
76
87
  self.info = None
88
+ self.python3 = python3
77
89
 
78
90
 
79
91
  # Adapted from
@@ -87,11 +99,8 @@ class CommandData(object):
87
99
  # Before a SIGINT is seen, wait(p) will simply call p.wait() and
88
100
  # return the result. Once a SIGINT has been seen (in the main process
89
101
  # or a subprocess, including the one the current call is waiting for),
90
- # wait(p) will call p.terminate() and raise ProcessWasInterrupted.
102
+ # wait(p) will call p.terminate().
91
103
  class SigintHandler(object):
92
- class ProcessWasInterrupted(Exception):
93
- pass
94
-
95
104
  sigint_returncodes = {-signal.SIGINT, # Unix
96
105
  -1073741510, # Windows
97
106
  }
@@ -99,7 +108,7 @@ class SigintHandler(object):
99
108
  self.__lock = threading.Lock()
100
109
  self.__processes = set()
101
110
  self.__got_sigint = False
102
- signal.signal(signal.SIGINT, lambda signal_num, frame: self.interrupt())
111
+ self.__previous_signal = signal.signal(signal.SIGINT, self.interrupt)
103
112
 
104
113
  def __on_sigint(self):
105
114
  self.__got_sigint = True
@@ -109,9 +118,10 @@ class SigintHandler(object):
109
118
  except OSError:
110
119
  pass
111
120
 
112
- def interrupt(self):
121
+ def interrupt(self, signal_num, frame):
113
122
  with self.__lock:
114
123
  self.__on_sigint()
124
+ self.__previous_signal(signal_num, frame)
115
125
 
116
126
  def got_sigint(self):
117
127
  with self.__lock:
@@ -128,15 +138,34 @@ class SigintHandler(object):
128
138
  self.__processes.discard(p)
129
139
  if code in self.sigint_returncodes:
130
140
  self.__on_sigint()
131
- if self.__got_sigint:
132
- raise self.ProcessWasInterrupted
133
141
  return stdout, stderr
134
142
 
135
143
  sigint_handler = SigintHandler()
136
144
 
137
145
 
146
+ class Timer(object):
147
+ def __init__(self, timeout, fn):
148
+ self.completed = False
149
+ self._fn = fn
150
+ self._timer = threading.Timer(timeout, self._onTimer) if timeout else None
151
+
152
+ def __enter__(self):
153
+ if self._timer:
154
+ self._timer.start()
155
+ return self
156
+
157
+ def __exit__(self, _type, _value, _traceback):
158
+ if self._timer:
159
+ self._timer.cancel()
160
+
161
+ def _onTimer(self):
162
+ self._fn()
163
+ self.completed = True
164
+
165
+
138
166
  class ThreadPool(object):
139
- def __init__(self, pool_size=None):
167
+ def __init__(self, pool_size=None, timeout=None):
168
+ self.timeout = timeout
140
169
  self._pool_size = pool_size or multiprocessing.cpu_count()
141
170
  self._messages = []
142
171
  self._messages_lock = threading.Lock()
@@ -144,13 +173,12 @@ class ThreadPool(object):
144
173
  self._tests_lock = threading.Lock()
145
174
  self._nonparallel_tests = []
146
175
 
147
- def CallCommand(self, test):
148
- """Runs an external program.
149
-
150
- This function converts invocation of .py files and invocations of "python"
151
- to vpython invocations.
152
- """
153
- vpython = 'vpython.bat' if sys.platform == 'win32' else 'vpython'
176
+ def _GetCommand(self, test):
177
+ vpython = 'vpython'
178
+ if test.python3:
179
+ vpython += '3'
180
+ if sys.platform == 'win32':
181
+ vpython += '.bat'
154
182
 
155
183
  cmd = test.cmd
156
184
  if cmd[0] == 'python':
@@ -159,20 +187,51 @@ class ThreadPool(object):
159
187
  elif cmd[0].endswith('.py'):
160
188
  cmd = [vpython] + cmd
161
189
 
190
+ # On Windows, scripts on the current directory take precedence over PATH, so
191
+ # that when testing depot_tools on Windows, calling `vpython.bat` will
192
+ # execute the copy of vpython of the depot_tools under test instead of the
193
+ # one in the bot.
194
+ # As a workaround, we run the tests from the parent directory instead.
195
+ if (cmd[0] == vpython and
196
+ 'cwd' in test.kwargs and
197
+ os.path.basename(test.kwargs['cwd']) == 'depot_tools'):
198
+ test.kwargs['cwd'] = os.path.dirname(test.kwargs['cwd'])
199
+ cmd[1] = os.path.join('depot_tools', cmd[1])
200
+
201
+ return cmd
202
+
203
+ def _RunWithTimeout(self, cmd, stdin, kwargs):
204
+ p = subprocess.Popen(cmd, **kwargs)
205
+ with Timer(self.timeout, p.terminate) as timer:
206
+ stdout, _ = sigint_handler.wait(p, stdin)
207
+ if timer.completed:
208
+ stdout = 'Process timed out after %ss\n%s' % (self.timeout, stdout)
209
+ return p.returncode, stdout
210
+
211
+ def CallCommand(self, test):
212
+ """Runs an external program.
213
+
214
+ This function converts invocation of .py files and invocations of 'python'
215
+ to vpython invocations.
216
+ """
217
+ cmd = self._GetCommand(test)
162
218
  try:
163
- start = time.time()
164
- p = subprocess.Popen(cmd, **test.kwargs)
165
- stdout, _ = sigint_handler.wait(p, test.stdin)
166
- duration = time.time() - start
167
- except OSError as e:
168
- duration = time.time() - start
219
+ start = time_time()
220
+ returncode, stdout = self._RunWithTimeout(cmd, test.stdin, test.kwargs)
221
+ duration = time_time() - start
222
+ except Exception:
223
+ duration = time_time() - start
169
224
  return test.message(
170
- '%s exec failure (%4.2fs)\n %s' % (test.name, duration, e))
171
- if p.returncode != 0:
225
+ '%s\n%s exec failure (%4.2fs)\n%s' % (
226
+ test.name, ' '.join(cmd), duration, traceback.format_exc()))
227
+
228
+ if returncode != 0:
172
229
  return test.message(
173
- '%s (%4.2fs) failed\n%s' % (test.name, duration, stdout))
230
+ '%s\n%s (%4.2fs) failed\n%s' % (
231
+ test.name, ' '.join(cmd), duration, stdout))
232
+
174
233
  if test.info:
175
- return test.info('%s (%4.2fs)' % (test.name, duration))
234
+ return test.info('%s\n%s (%4.2fs)' % (test.name, ' '.join(cmd), duration))
176
235
 
177
236
  def AddTests(self, tests, parallel=True):
178
237
  if parallel:
@@ -233,37 +292,10 @@ def _RightHandSideLinesImpl(affected_files):
233
292
  yield (af, line[0], line[1])
234
293
 
235
294
 
236
- class PresubmitOutput(object):
237
- def __init__(self, input_stream=None, output_stream=None):
238
- self.input_stream = input_stream
239
- self.output_stream = output_stream
240
- self.reviewers = []
241
- self.more_cc = []
242
- self.written_output = []
243
- self.error_count = 0
244
-
245
- def prompt_yes_no(self, prompt_string):
246
- self.write(prompt_string)
247
- if self.input_stream:
248
- response = self.input_stream.readline().strip().lower()
249
- if response not in ('y', 'yes'):
250
- self.fail()
251
- else:
252
- self.fail()
253
-
254
- def fail(self):
255
- self.error_count += 1
256
-
257
- def should_continue(self):
258
- return not self.error_count
259
-
260
- def write(self, s):
261
- self.written_output.append(s)
262
- if self.output_stream:
263
- self.output_stream.write(s)
264
-
265
- def getvalue(self):
266
- return ''.join(self.written_output)
295
+ def prompt_should_continue(prompt_string):
296
+ sys.stdout.write(prompt_string)
297
+ response = sys.stdin.readline().strip().lower()
298
+ return response in ('y', 'yes')
267
299
 
268
300
 
269
301
  # Top level object so multiprocessing can pickle
@@ -283,23 +315,29 @@ class _PresubmitResult(object):
283
315
  self._items = items or []
284
316
  self._long_text = long_text.rstrip()
285
317
 
286
- def handle(self, output):
287
- output.write(self._message)
288
- output.write('\n')
318
+ def handle(self):
319
+ sys.stdout.write(self._message)
320
+ sys.stdout.write('\n')
289
321
  for index, item in enumerate(self._items):
290
- output.write(' ')
322
+ sys.stdout.write(' ')
291
323
  # Write separately in case it's unicode.
292
- output.write(str(item))
324
+ sys.stdout.write(str(item))
293
325
  if index < len(self._items) - 1:
294
- output.write(' \\')
295
- output.write('\n')
326
+ sys.stdout.write(' \\')
327
+ sys.stdout.write('\n')
296
328
  if self._long_text:
297
- output.write('\n***************\n')
329
+ sys.stdout.write('\n***************\n')
298
330
  # Write separately in case it's unicode.
299
- output.write(self._long_text)
300
- output.write('\n***************\n')
301
- if self.fatal:
302
- output.fail()
331
+ sys.stdout.write(self._long_text)
332
+ sys.stdout.write('\n***************\n')
333
+
334
+ def json_format(self):
335
+ return {
336
+ 'message': self._message,
337
+ 'items': [str(item) for item in self._items],
338
+ 'long_text': self._long_text,
339
+ 'fatal': self.fatal
340
+ }
303
341
 
304
342
 
305
343
  # Top level object so multiprocessing can pickle
@@ -375,7 +413,7 @@ class GerritAccessor(object):
375
413
 
376
414
  # Find revision info for the patchset we want.
377
415
  if patchset is not None:
378
- for rev, rev_info in info['revisions'].iteritems():
416
+ for rev, rev_info in info['revisions'].items():
379
417
  if str(rev_info['_number']) == str(patchset):
380
418
  break
381
419
  else:
@@ -413,6 +451,9 @@ class GerritAccessor(object):
413
451
  reviewers = changeinfo.get('reviewers', {}).get('REVIEWER', [])
414
452
  return [r.get('email') for r in reviewers]
415
453
 
454
+ def UpdateDescription(self, description, issue):
455
+ gerrit_util.SetCommitMessage(self.host, issue, description, notify='NONE')
456
+
416
457
 
417
458
  class OutputApi(object):
418
459
  """An instance of OutputApi gets passed to presubmit scripts so that they
@@ -450,42 +491,82 @@ class InputApi(object):
450
491
  # perspective. Don't modify this list from a presubmit script!
451
492
  #
452
493
  # Files without an extension aren't included in the list. If you want to
453
- # filter them as source files, add r"(^|.*?[\\\/])[^.]+$" to the white list.
454
- # Note that ALL CAPS files are black listed in DEFAULT_BLACK_LIST below.
455
- DEFAULT_WHITE_LIST = (
494
+ # filter them as source files, add r'(^|.*?[\\\/])[^.]+$' to the allow list.
495
+ # Note that ALL CAPS files are skipped in DEFAULT_FILES_TO_SKIP below.
496
+ DEFAULT_FILES_TO_CHECK = (
456
497
  # C++ and friends
457
- r".+\.c$", r".+\.cc$", r".+\.cpp$", r".+\.h$", r".+\.m$", r".+\.mm$",
458
- r".+\.inl$", r".+\.asm$", r".+\.hxx$", r".+\.hpp$", r".+\.s$", r".+\.S$",
498
+ r'.+\.c$', r'.+\.cc$', r'.+\.cpp$', r'.+\.h$', r'.+\.m$', r'.+\.mm$',
499
+ r'.+\.inl$', r'.+\.asm$', r'.+\.hxx$', r'.+\.hpp$', r'.+\.s$', r'.+\.S$',
459
500
  # Scripts
460
- r".+\.js$", r".+\.py$", r".+\.sh$", r".+\.rb$", r".+\.pl$", r".+\.pm$",
501
+ r'.+\.js$', r'.+\.py$', r'.+\.sh$', r'.+\.rb$', r'.+\.pl$', r'.+\.pm$',
461
502
  # Other
462
- r".+\.java$", r".+\.mk$", r".+\.am$", r".+\.css$", r".+\.mojom$",
463
- r".+\.fidl$"
503
+ r'.+\.java$', r'.+\.mk$', r'.+\.am$', r'.+\.css$', r'.+\.mojom$',
504
+ r'.+\.fidl$'
464
505
  )
465
506
 
466
507
  # Path regexp that should be excluded from being considered containing source
467
508
  # files. Don't modify this list from a presubmit script!
468
- DEFAULT_BLACK_LIST = (
469
- r"testing_support[\\\/]google_appengine[\\\/].*",
470
- r".*\bexperimental[\\\/].*",
509
+ DEFAULT_FILES_TO_SKIP = (
510
+ r'testing_support[\\\/]google_appengine[\\\/].*',
511
+ r'.*\bexperimental[\\\/].*',
471
512
  # Exclude third_party/.* but NOT third_party/{WebKit,blink}
472
513
  # (crbug.com/539768 and crbug.com/836555).
473
- r".*\bthird_party[\\\/](?!(WebKit|blink)[\\\/]).*",
514
+ r'.*\bthird_party[\\\/](?!(WebKit|blink)[\\\/]).*',
474
515
  # Output directories (just in case)
475
- r".*\bDebug[\\\/].*",
476
- r".*\bRelease[\\\/].*",
477
- r".*\bxcodebuild[\\\/].*",
478
- r".*\bout[\\\/].*",
516
+ r'.*\bDebug[\\\/].*',
517
+ r'.*\bRelease[\\\/].*',
518
+ r'.*\bxcodebuild[\\\/].*',
519
+ r'.*\bout[\\\/].*',
479
520
  # All caps files like README and LICENCE.
480
- r".*\b[A-Z0-9_]{2,}$",
521
+ r'.*\b[A-Z0-9_]{2,}$',
481
522
  # SCM (can happen in dual SCM configuration). (Slightly over aggressive)
482
- r"(|.*[\\\/])\.git[\\\/].*",
483
- r"(|.*[\\\/])\.svn[\\\/].*",
523
+ r'(|.*[\\\/])\.git[\\\/].*',
524
+ r'(|.*[\\\/])\.svn[\\\/].*',
484
525
  # There is no point in processing a patch file.
485
- r".+\.diff$",
486
- r".+\.patch$",
526
+ r'.+\.diff$',
527
+ r'.+\.patch$',
487
528
  )
488
529
 
530
+ # TODO(https://crbug.com/1098562): Remove once no longer used
531
+ @property
532
+ def DEFAULT_WHITE_LIST(self):
533
+ return self.DEFAULT_FILES_TO_CHECK
534
+
535
+ # TODO(https://crbug.com/1098562): Remove once no longer used
536
+ @DEFAULT_WHITE_LIST.setter
537
+ def DEFAULT_WHITE_LIST(self, value):
538
+ self.DEFAULT_FILES_TO_CHECK = value
539
+
540
+ # TODO(https://crbug.com/1098562): Remove once no longer used
541
+ @property
542
+ def DEFAULT_ALLOW_LIST(self):
543
+ return self.DEFAULT_FILES_TO_CHECK
544
+
545
+ # TODO(https://crbug.com/1098562): Remove once no longer used
546
+ @DEFAULT_ALLOW_LIST.setter
547
+ def DEFAULT_ALLOW_LIST(self, value):
548
+ self.DEFAULT_FILES_TO_CHECK = value
549
+
550
+ # TODO(https://crbug.com/1098562): Remove once no longer used
551
+ @property
552
+ def DEFAULT_BLACK_LIST(self):
553
+ return self.DEFAULT_FILES_TO_SKIP
554
+
555
+ # TODO(https://crbug.com/1098562): Remove once no longer used
556
+ @DEFAULT_BLACK_LIST.setter
557
+ def DEFAULT_BLACK_LIST(self, value):
558
+ self.DEFAULT_FILES_TO_SKIP = value
559
+
560
+ # TODO(https://crbug.com/1098562): Remove once no longer used
561
+ @property
562
+ def DEFAULT_BLOCK_LIST(self):
563
+ return self.DEFAULT_FILES_TO_SKIP
564
+
565
+ # TODO(https://crbug.com/1098562): Remove once no longer used
566
+ @DEFAULT_BLOCK_LIST.setter
567
+ def DEFAULT_BLOCK_LIST(self, value):
568
+ self.DEFAULT_FILES_TO_SKIP = value
569
+
489
570
  def __init__(self, change, presubmit_path, is_committing,
490
571
  verbose, gerrit_obj, dry_run=None, thread_pool=None, parallel=False):
491
572
  """Builds an InputApi object.
@@ -513,9 +594,7 @@ class InputApi(object):
513
594
  # so that presubmit scripts don't have to import them.
514
595
  self.ast = ast
515
596
  self.basename = os.path.basename
516
- self.cPickle = cPickle
517
597
  self.cpplint = cpplint
518
- self.cStringIO = cStringIO
519
598
  self.fnmatch = fnmatch
520
599
  self.gclient_paths = gclient_paths
521
600
  # TODO(yyanagisawa): stop exposing this when python3 become default.
@@ -524,27 +603,27 @@ class InputApi(object):
524
603
  self.glob = glob.glob
525
604
  self.json = json
526
605
  self.logging = logging.getLogger('PRESUBMIT')
527
- self.marshal = marshal
528
606
  self.os_listdir = os.listdir
529
607
  self.os_path = os.path
530
608
  self.os_stat = os.stat
531
609
  self.os_walk = os.walk
532
- self.pickle = pickle
533
610
  self.re = re
534
611
  self.subprocess = subprocess
612
+ self.sys = sys
535
613
  self.tempfile = tempfile
536
614
  self.time = time
537
- self.traceback = traceback
538
615
  self.unittest = unittest
539
- self.urllib2 = urllib2
616
+ if sys.version_info.major == 2:
617
+ self.urllib2 = urllib2
618
+ self.urllib_request = urllib_request
619
+ self.urllib_error = urllib_error
540
620
 
541
621
  self.is_windows = sys.platform == 'win32'
542
622
 
543
- # Set python_executable to 'python'. This is interpreted in CallCommand to
544
- # convert to vpython in order to allow scripts in other repos (e.g. src.git)
545
- # to automatically pick up that repo's .vpython file, instead of inheriting
546
- # the one in depot_tools.
547
- self.python_executable = 'python'
623
+ # Set python_executable to 'vpython' in order to allow scripts in other
624
+ # repos (e.g. src.git) to automatically pick up that repo's .vpython file,
625
+ # instead of inheriting the one in depot_tools.
626
+ self.python_executable = 'vpython'
548
627
  self.environ = os.environ
549
628
 
550
629
  # InputApi.platform is the platform you're currently running on.
@@ -564,13 +643,13 @@ class InputApi(object):
564
643
  # TODO(dpranke): figure out a list of all approved owners for a repo
565
644
  # in order to be able to handle wildcard OWNERS files?
566
645
  self.owners_db = owners.Database(change.RepositoryRoot(),
567
- fopen=file, os_path=self.os_path)
646
+ fopen=open, os_path=self.os_path)
568
647
  self.owners_finder = owners_finder.OwnersFinder
569
648
  self.verbose = verbose
570
649
  self.Command = CommandData
571
650
 
572
651
  # Replace <hash_map> and <hash_set> as headers that need to be included
573
- # with "base/containers/hash_tables.h" instead.
652
+ # with 'base/containers/hash_tables.h' instead.
574
653
  # Access to a protected member _XX of a client class
575
654
  # pylint: disable=protected-access
576
655
  self.cpplint._re_pattern_templates = [
@@ -579,6 +658,9 @@ class InputApi(object):
579
658
  for (a, b, header) in cpplint._re_pattern_templates
580
659
  ]
581
660
 
661
+ def SetTimeout(self, timeout):
662
+ self.thread_pool.timeout = timeout
663
+
582
664
  def PresubmitLocalPath(self):
583
665
  """Returns the local path of the presubmit script currently being run.
584
666
 
@@ -592,20 +674,21 @@ class InputApi(object):
592
674
  def AffectedFiles(self, include_deletes=True, file_filter=None):
593
675
  """Same as input_api.change.AffectedFiles() except only lists files
594
676
  (and optionally directories) in the same directory as the current presubmit
595
- script, or subdirectories thereof.
677
+ script, or subdirectories thereof. Note that files are listed using the OS
678
+ path separator, so backslashes are used as separators on Windows.
596
679
  """
597
- dir_with_slash = normpath("%s/" % self.PresubmitLocalPath())
680
+ dir_with_slash = normpath('%s/' % self.PresubmitLocalPath())
598
681
  if len(dir_with_slash) == 1:
599
682
  dir_with_slash = ''
600
683
 
601
- return filter(
684
+ return list(filter(
602
685
  lambda x: normpath(x.AbsoluteLocalPath()).startswith(dir_with_slash),
603
- self.change.AffectedFiles(include_deletes, file_filter))
686
+ self.change.AffectedFiles(include_deletes, file_filter)))
604
687
 
605
688
  def LocalPaths(self):
606
689
  """Returns local paths of input_api.AffectedFiles()."""
607
690
  paths = [af.LocalPath() for af in self.AffectedFiles()]
608
- logging.debug("LocalPaths: %s", paths)
691
+ logging.debug('LocalPaths: %s', paths)
609
692
  return paths
610
693
 
611
694
  def AbsoluteLocalPaths(self):
@@ -618,36 +701,54 @@ class InputApi(object):
618
701
  thereof.
619
702
  """
620
703
  if include_deletes is not None:
621
- warn("AffectedTestableFiles(include_deletes=%s)"
622
- " is deprecated and ignored" % str(include_deletes),
704
+ warn('AffectedTestableFiles(include_deletes=%s)'
705
+ ' is deprecated and ignored' % str(include_deletes),
623
706
  category=DeprecationWarning,
624
707
  stacklevel=2)
625
- return filter(lambda x: x.IsTestableFile(),
626
- self.AffectedFiles(include_deletes=False, **kwargs))
708
+ return list(filter(
709
+ lambda x: x.IsTestableFile(),
710
+ self.AffectedFiles(include_deletes=False, **kwargs)))
627
711
 
628
712
  def AffectedTextFiles(self, include_deletes=None):
629
713
  """An alias to AffectedTestableFiles for backwards compatibility."""
630
714
  return self.AffectedTestableFiles(include_deletes=include_deletes)
631
715
 
632
- def FilterSourceFile(self, affected_file, white_list=None, black_list=None):
633
- """Filters out files that aren't considered "source file".
716
+ def FilterSourceFile(self, affected_file, files_to_check=None,
717
+ files_to_skip=None, allow_list=None, block_list=None,
718
+ white_list=None, black_list=None):
719
+ """Filters out files that aren't considered 'source file'.
634
720
 
635
- If white_list or black_list is None, InputApi.DEFAULT_WHITE_LIST
636
- and InputApi.DEFAULT_BLACK_LIST is used respectively.
721
+ If files_to_check or files_to_skip is None, InputApi.DEFAULT_FILES_TO_CHECK
722
+ and InputApi.DEFAULT_FILES_TO_SKIP is used respectively.
637
723
 
638
724
  The lists will be compiled as regular expression and
639
725
  AffectedFile.LocalPath() needs to pass both list.
640
726
 
727
+ Note: if files_to_check or files_to_skip is not set, and
728
+ white_list/allow_list or black_list/block_list is, then those values are
729
+ used. This is used for backward compatibility reasons.
730
+
641
731
  Note: Copy-paste this function to suit your needs or use a lambda function.
642
732
  """
733
+ # TODO(https://crbug.com/1098560): Add warnings before removing bc.
734
+ if files_to_check is None:
735
+ files_to_check = allow_list or white_list
736
+ if files_to_skip is None:
737
+ files_to_skip = block_list or black_list
738
+
739
+ if files_to_check is None:
740
+ files_to_check = self.DEFAULT_FILES_TO_CHECK
741
+ if files_to_skip is None:
742
+ files_to_skip = self.DEFAULT_FILES_TO_SKIP
743
+
643
744
  def Find(affected_file, items):
644
745
  local_path = affected_file.LocalPath()
645
746
  for item in items:
646
747
  if self.re.match(item, local_path):
647
748
  return True
648
749
  return False
649
- return (Find(affected_file, white_list or self.DEFAULT_WHITE_LIST) and
650
- not Find(affected_file, black_list or self.DEFAULT_BLACK_LIST))
750
+ return (Find(affected_file, files_to_check) and
751
+ not Find(affected_file, files_to_skip))
651
752
 
652
753
  def AffectedSourceFiles(self, source_file):
653
754
  """Filter the list of AffectedTestableFiles by the function source_file.
@@ -656,10 +757,10 @@ class InputApi(object):
656
757
  """
657
758
  if not source_file:
658
759
  source_file = self.FilterSourceFile
659
- return filter(source_file, self.AffectedTestableFiles())
760
+ return list(filter(source_file, self.AffectedTestableFiles()))
660
761
 
661
762
  def RightHandSideLines(self, source_file_filter=None):
662
- """An iterator over all text lines in "new" version of changed files.
763
+ """An iterator over all text lines in 'new' version of changed files.
663
764
 
664
765
  Only lists lines from new or modified text files in the change that are
665
766
  contained by the directory of the currently executing presubmit script.
@@ -729,11 +830,8 @@ class InputApi(object):
729
830
  return 'TBR' in self.change.tags or self.change.TBRsFromDescription()
730
831
 
731
832
  def RunTests(self, tests_mix, parallel=True):
732
- # RunTests doesn't actually run tests. It adds them to a ThreadPool that
733
- # will run all tests once all PRESUBMIT files are processed.
734
833
  tests = []
735
834
  msgs = []
736
- parallel = parallel and self.parallel
737
835
  for t in tests_mix:
738
836
  if isinstance(t, OutputApi.PresubmitResult) and t:
739
837
  msgs.append(t)
@@ -745,7 +843,11 @@ class InputApi(object):
745
843
  if not t.kwargs.get('cwd'):
746
844
  t.kwargs['cwd'] = self.PresubmitLocalPath()
747
845
  self.thread_pool.AddTests(tests, parallel)
748
- if not parallel:
846
+ # When self.parallel is True (i.e. --parallel is passed as an option)
847
+ # RunTests doesn't actually run tests. It adds them to a ThreadPool that
848
+ # will run all tests once all PRESUBMIT files are processed.
849
+ # Otherwise, it will run them and return the results.
850
+ if not self.parallel:
749
851
  msgs.extend(self.thread_pool.RunAsync())
750
852
  return msgs
751
853
 
@@ -859,7 +961,7 @@ class AffectedFile(object):
859
961
  """Returns an iterator over the lines in the old version of file.
860
962
 
861
963
  The old version is the file before any modifications in the user's
862
- workspace, i.e. the "left hand side".
964
+ workspace, i.e. the 'left hand side'.
863
965
 
864
966
  Contents will be empty if the file is a directory or does not exist.
865
967
  Note: The carriage returns (LF or CR) are stripped off.
@@ -870,8 +972,8 @@ class AffectedFile(object):
870
972
  def NewContents(self):
871
973
  """Returns an iterator over the lines in the new version of file.
872
974
 
873
- The new version is the file in the user's workspace, i.e. the "right hand
874
- side".
975
+ The new version is the file in the user's workspace, i.e. the 'right hand
976
+ side'.
875
977
 
876
978
  Contents will be empty if the file is a directory or does not exist.
877
979
  Note: The carriage returns (LF or CR) are stripped off.
@@ -951,7 +1053,7 @@ class Change(object):
951
1053
 
952
1054
  _AFFECTED_FILES = AffectedFile
953
1055
 
954
- # Matches key/value (or "tag") lines in changelist descriptions.
1056
+ # Matches key/value (or 'tag') lines in changelist descriptions.
955
1057
  TAG_LINE_RE = re.compile(
956
1058
  '^[ \t]*(?P<key>[A-Z][A-Z_0-9]*)[ \t]*=[ \t]*(?P<value>.*?)[ \t]*$')
957
1059
  scm = ''
@@ -990,7 +1092,7 @@ class Change(object):
990
1092
  def DescriptionText(self):
991
1093
  """Returns the user-entered changelist description, minus tags.
992
1094
 
993
- Any line in the user-provided description starting with e.g. "FOO="
1095
+ Any line in the user-provided description starting with e.g. 'FOO='
994
1096
  (whitespace permitted before and around) is considered a tag line. Such
995
1097
  lines are stripped out of the description this function returns.
996
1098
  """
@@ -1007,7 +1109,7 @@ class Change(object):
1007
1109
  self._full_description = description
1008
1110
 
1009
1111
  # From the description text, build up a dictionary of key/value pairs
1010
- # plus the description minus all key/value or "tag" lines.
1112
+ # plus the description minus all key/value or 'tag' lines.
1011
1113
  description_without_tags = []
1012
1114
  self.tags = {}
1013
1115
  for line in self._full_description.splitlines():
@@ -1021,6 +1123,19 @@ class Change(object):
1021
1123
  self._description_without_tags = (
1022
1124
  '\n'.join(description_without_tags).rstrip())
1023
1125
 
1126
+ def AddDescriptionFooter(self, key, value):
1127
+ """Adds the given footer to the change description.
1128
+
1129
+ Args:
1130
+ key: A string with the key for the git footer. It must conform to
1131
+ the git footers format (i.e. 'List-Of-Tokens') and will be case
1132
+ normalized so that each token is title-cased.
1133
+ value: A string with the value for the git footer.
1134
+ """
1135
+ description = git_footers.add_footer(
1136
+ self.FullDescriptionText(), git_footers.normalize_name(key), value)
1137
+ self.SetDescriptionText(description)
1138
+
1024
1139
  def RepositoryRoot(self):
1025
1140
  """Returns the repository (checkout) root directory for this change,
1026
1141
  as an absolute path.
@@ -1029,35 +1144,44 @@ class Change(object):
1029
1144
 
1030
1145
  def __getattr__(self, attr):
1031
1146
  """Return tags directly as attributes on the object."""
1032
- if not re.match(r"^[A-Z_]*$", attr):
1147
+ if not re.match(r'^[A-Z_]*$', attr):
1033
1148
  raise AttributeError(self, attr)
1034
1149
  return self.tags.get(attr)
1035
1150
 
1151
+ def GitFootersFromDescription(self):
1152
+ """Return the git footers present in the description.
1153
+
1154
+ Returns:
1155
+ footers: A dict of {footer: [values]} containing a multimap of the footers
1156
+ in the change description.
1157
+ """
1158
+ return git_footers.parse_footers(self.FullDescriptionText())
1159
+
1036
1160
  def BugsFromDescription(self):
1037
1161
  """Returns all bugs referenced in the commit description."""
1038
1162
  tags = [b.strip() for b in self.tags.get('BUG', '').split(',') if b.strip()]
1039
1163
  footers = []
1040
- unsplit_footers = git_footers.parse_footers(self._full_description).get(
1041
- 'Bug', [])
1164
+ parsed = self.GitFootersFromDescription()
1165
+ unsplit_footers = parsed.get('Bug', []) + parsed.get('Fixed', [])
1042
1166
  for unsplit_footer in unsplit_footers:
1043
1167
  footers += [b.strip() for b in unsplit_footer.split(',')]
1044
1168
  return sorted(set(tags + footers))
1045
1169
 
1046
1170
  def ReviewersFromDescription(self):
1047
1171
  """Returns all reviewers listed in the commit description."""
1048
- # We don't support a "R:" git-footer for reviewers; that is in metadata.
1172
+ # We don't support a 'R:' git-footer for reviewers; that is in metadata.
1049
1173
  tags = [r.strip() for r in self.tags.get('R', '').split(',') if r.strip()]
1050
1174
  return sorted(set(tags))
1051
1175
 
1052
1176
  def TBRsFromDescription(self):
1053
1177
  """Returns all TBR reviewers listed in the commit description."""
1054
1178
  tags = [r.strip() for r in self.tags.get('TBR', '').split(',') if r.strip()]
1055
- # TODO(agable): Remove support for 'Tbr:' when TBRs are programmatically
1056
- # determined by self-CR+1s.
1057
- footers = git_footers.parse_footers(self._full_description).get('Tbr', [])
1179
+ # TODO(crbug.com/839208): Remove support for 'Tbr:' when TBRs are
1180
+ # programmatically determined by self-CR+1s.
1181
+ footers = self.GitFootersFromDescription().get('Tbr', [])
1058
1182
  return sorted(set(tags + footers))
1059
1183
 
1060
- # TODO(agable): Delete these once we're sure they're unused.
1184
+ # TODO(crbug.com/753425): Delete these once we're sure they're unused.
1061
1185
  @property
1062
1186
  def BUG(self):
1063
1187
  return ','.join(self.BugsFromDescription())
@@ -1082,21 +1206,22 @@ class Change(object):
1082
1206
  Returns:
1083
1207
  [AffectedFile(path, action), AffectedFile(path, action)]
1084
1208
  """
1085
- affected = filter(file_filter, self._affected_files)
1209
+ affected = list(filter(file_filter, self._affected_files))
1086
1210
 
1087
1211
  if include_deletes:
1088
1212
  return affected
1089
- return filter(lambda x: x.Action() != 'D', affected)
1213
+ return list(filter(lambda x: x.Action() != 'D', affected))
1090
1214
 
1091
1215
  def AffectedTestableFiles(self, include_deletes=None, **kwargs):
1092
1216
  """Return a list of the existing text files in a change."""
1093
1217
  if include_deletes is not None:
1094
- warn("AffectedTeestableFiles(include_deletes=%s)"
1095
- " is deprecated and ignored" % str(include_deletes),
1218
+ warn('AffectedTeestableFiles(include_deletes=%s)'
1219
+ ' is deprecated and ignored' % str(include_deletes),
1096
1220
  category=DeprecationWarning,
1097
1221
  stacklevel=2)
1098
- return filter(lambda x: x.IsTestableFile(),
1099
- self.AffectedFiles(include_deletes=False, **kwargs))
1222
+ return list(filter(
1223
+ lambda x: x.IsTestableFile(),
1224
+ self.AffectedFiles(include_deletes=False, **kwargs)))
1100
1225
 
1101
1226
  def AffectedTextFiles(self, include_deletes=None):
1102
1227
  """An alias to AffectedTestableFiles for backwards compatibility."""
@@ -1111,7 +1236,7 @@ class Change(object):
1111
1236
  return [af.AbsoluteLocalPath() for af in self.AffectedFiles()]
1112
1237
 
1113
1238
  def RightHandSideLines(self):
1114
- """An iterator over all text lines in "new" version of changed files.
1239
+ """An iterator over all text lines in 'new' version of changed files.
1115
1240
 
1116
1241
  Lists lines from new or modified text files in the change.
1117
1242
 
@@ -1216,8 +1341,9 @@ class GetTryMastersExecuter(object):
1216
1341
  """
1217
1342
  context = {}
1218
1343
  try:
1219
- exec script_text in context
1220
- except Exception, e:
1344
+ exec(compile(script_text, 'PRESUBMIT.py', 'exec', dont_inherit=True),
1345
+ context)
1346
+ except Exception as e:
1221
1347
  raise PresubmitFailure('"%s" had an exception.\n%s'
1222
1348
  % (presubmit_path, e))
1223
1349
 
@@ -1233,13 +1359,13 @@ class GetTryMastersExecuter(object):
1233
1359
 
1234
1360
  class GetPostUploadExecuter(object):
1235
1361
  @staticmethod
1236
- def ExecPresubmitScript(script_text, presubmit_path, cl, change):
1362
+ def ExecPresubmitScript(script_text, presubmit_path, gerrit_obj, change):
1237
1363
  """Executes PostUploadHook() from a single presubmit script.
1238
1364
 
1239
1365
  Args:
1240
1366
  script_text: The text of the presubmit script.
1241
1367
  presubmit_path: Project script to run.
1242
- cl: The Changelist object.
1368
+ gerrit_obj: The GerritAccessor object.
1243
1369
  change: The Change object.
1244
1370
 
1245
1371
  Return:
@@ -1247,8 +1373,9 @@ class GetPostUploadExecuter(object):
1247
1373
  """
1248
1374
  context = {}
1249
1375
  try:
1250
- exec script_text in context
1251
- except Exception, e:
1376
+ exec(compile(script_text, 'PRESUBMIT.py', 'exec', dont_inherit=True),
1377
+ context)
1378
+ except Exception as e:
1252
1379
  raise PresubmitFailure('"%s" had an exception.\n%s'
1253
1380
  % (presubmit_path, e))
1254
1381
 
@@ -1259,16 +1386,16 @@ class GetPostUploadExecuter(object):
1259
1386
  if not len(inspect.getargspec(post_upload_hook)[0]) == 3:
1260
1387
  raise PresubmitFailure(
1261
1388
  'Expected function "PostUploadHook" to take three arguments.')
1262
- return post_upload_hook(cl, change, OutputApi(False))
1389
+ return post_upload_hook(gerrit_obj, change, OutputApi(False))
1263
1390
 
1264
1391
 
1265
1392
  def _MergeMasters(masters1, masters2):
1266
1393
  """Merges two master maps. Merges also the tests of each builder."""
1267
1394
  result = {}
1268
- for (master, builders) in itertools.chain(masters1.iteritems(),
1269
- masters2.iteritems()):
1395
+ for (master, builders) in itertools.chain(masters1.items(),
1396
+ masters2.items()):
1270
1397
  new_builders = result.setdefault(master, {})
1271
- for (builder, tests) in builders.iteritems():
1398
+ for (builder, tests) in builders.items():
1272
1399
  new_builders.setdefault(builder, set([])).update(tests)
1273
1400
  return result
1274
1401
 
@@ -1295,27 +1422,27 @@ def DoGetTryMasters(change,
1295
1422
  """
1296
1423
  presubmit_files = ListRelevantPresubmitFiles(changed_files, repository_root)
1297
1424
  if not presubmit_files and verbose:
1298
- output_stream.write("Warning, no PRESUBMIT.py found.\n")
1425
+ output_stream.write('Warning, no PRESUBMIT.py found.\n')
1299
1426
  results = {}
1300
1427
  executer = GetTryMastersExecuter()
1301
1428
 
1302
1429
  if default_presubmit:
1303
1430
  if verbose:
1304
- output_stream.write("Running default presubmit script.\n")
1431
+ output_stream.write('Running default presubmit script.\n')
1305
1432
  fake_path = os.path.join(repository_root, 'PRESUBMIT.py')
1306
1433
  results = _MergeMasters(results, executer.ExecPresubmitScript(
1307
1434
  default_presubmit, fake_path, project, change))
1308
1435
  for filename in presubmit_files:
1309
1436
  filename = os.path.abspath(filename)
1310
1437
  if verbose:
1311
- output_stream.write("Running %s\n" % filename)
1438
+ output_stream.write('Running %s\n' % filename)
1312
1439
  # Accept CRLF presubmit script.
1313
1440
  presubmit_script = gclient_utils.FileRead(filename, 'rU')
1314
1441
  results = _MergeMasters(results, executer.ExecPresubmitScript(
1315
1442
  presubmit_script, filename, project, change))
1316
1443
 
1317
1444
  # Make sets to lists again for later JSON serialization.
1318
- for builders in results.itervalues():
1445
+ for builders in results.values():
1319
1446
  for builder in builders:
1320
1447
  builders[builder] = list(builders[builder])
1321
1448
 
@@ -1325,23 +1452,19 @@ def DoGetTryMasters(change,
1325
1452
 
1326
1453
 
1327
1454
  def DoPostUploadExecuter(change,
1328
- cl,
1329
- repository_root,
1330
- verbose,
1331
- output_stream):
1455
+ gerrit_obj,
1456
+ verbose):
1332
1457
  """Execute the post upload hook.
1333
1458
 
1334
1459
  Args:
1335
1460
  change: The Change object.
1336
- cl: The Changelist object.
1337
- repository_root: The repository root.
1461
+ gerrit_obj: The GerritAccessor object.
1338
1462
  verbose: Prints debug info.
1339
- output_stream: A stream to write debug output to.
1340
1463
  """
1341
1464
  presubmit_files = ListRelevantPresubmitFiles(
1342
- change.LocalPaths(), repository_root)
1465
+ change.LocalPaths(), change.RepositoryRoot())
1343
1466
  if not presubmit_files and verbose:
1344
- output_stream.write("Warning, no PRESUBMIT.py found.\n")
1467
+ sys.stdout.write('Warning, no PRESUBMIT.py found.\n')
1345
1468
  results = []
1346
1469
  executer = GetPostUploadExecuter()
1347
1470
  # The root presubmit file should be executed after the ones in subdirectories.
@@ -1352,19 +1475,26 @@ def DoPostUploadExecuter(change,
1352
1475
  for filename in presubmit_files:
1353
1476
  filename = os.path.abspath(filename)
1354
1477
  if verbose:
1355
- output_stream.write("Running %s\n" % filename)
1478
+ sys.stdout.write('Running %s\n' % filename)
1356
1479
  # Accept CRLF presubmit script.
1357
1480
  presubmit_script = gclient_utils.FileRead(filename, 'rU')
1358
1481
  results.extend(executer.ExecPresubmitScript(
1359
- presubmit_script, filename, cl, change))
1360
- output_stream.write('\n')
1361
- if results:
1362
- output_stream.write('** Post Upload Hook Messages **\n')
1482
+ presubmit_script, filename, gerrit_obj, change))
1483
+
1484
+ if not results:
1485
+ return 0
1486
+
1487
+ sys.stdout.write('\n')
1488
+ sys.stdout.write('** Post Upload Hook Messages **\n')
1489
+
1490
+ exit_code = 0
1363
1491
  for result in results:
1364
- result.handle(output_stream)
1365
- output_stream.write('\n')
1492
+ if result.fatal:
1493
+ exit_code = 1
1494
+ result.handle()
1495
+ sys.stdout.write('\n')
1366
1496
 
1367
- return results
1497
+ return exit_code
1368
1498
 
1369
1499
 
1370
1500
  class PresubmitExecuter(object):
@@ -1412,8 +1542,9 @@ class PresubmitExecuter(object):
1412
1542
  output_api = OutputApi(self.committing)
1413
1543
  context = {}
1414
1544
  try:
1415
- exec script_text in context
1416
- except Exception, e:
1545
+ exec(compile(script_text, 'PRESUBMIT.py', 'exec', dont_inherit=True),
1546
+ context)
1547
+ except Exception as e:
1417
1548
  raise PresubmitFailure('"%s" had an exception.\n%s' % (presubmit_path, e))
1418
1549
 
1419
1550
  # These function names must change if we make substantial changes to
@@ -1430,9 +1561,9 @@ class PresubmitExecuter(object):
1430
1561
  logging.debug('Running %s done.', function_name)
1431
1562
  self.more_cc.extend(output_api.more_cc)
1432
1563
  finally:
1433
- map(os.remove, input_api._named_temporary_files)
1434
- if not (isinstance(result, types.TupleType) or
1435
- isinstance(result, types.ListType)):
1564
+ for f in input_api._named_temporary_files:
1565
+ os.remove(f)
1566
+ if not isinstance(result, (tuple, list)):
1436
1567
  raise PresubmitFailure(
1437
1568
  'Presubmit functions must return a tuple or list')
1438
1569
  for item in result:
@@ -1450,13 +1581,12 @@ class PresubmitExecuter(object):
1450
1581
  def DoPresubmitChecks(change,
1451
1582
  committing,
1452
1583
  verbose,
1453
- output_stream,
1454
- input_stream,
1455
1584
  default_presubmit,
1456
1585
  may_prompt,
1457
1586
  gerrit_obj,
1458
1587
  dry_run=None,
1459
- parallel=False):
1588
+ parallel=False,
1589
+ json_output=None):
1460
1590
  """Runs all presubmit checks that apply to the files in the change.
1461
1591
 
1462
1592
  This finds all PRESUBMIT.py files in directories enclosing the files in the
@@ -1470,8 +1600,6 @@ def DoPresubmitChecks(change,
1470
1600
  change: The Change object.
1471
1601
  committing: True if 'git cl land' is running, False if 'git cl upload' is.
1472
1602
  verbose: Prints debug info.
1473
- output_stream: A stream to write output from presubmit tests to.
1474
- input_stream: A stream to read input from the user.
1475
1603
  default_presubmit: A default presubmit script to execute in any case.
1476
1604
  may_prompt: Enable (y/n) questions on warning or error. If False,
1477
1605
  any questions are answered with yes by default.
@@ -1480,13 +1608,8 @@ def DoPresubmitChecks(change,
1480
1608
  parallel: if true, all tests specified by input_api.RunTests in all
1481
1609
  PRESUBMIT files will be run in parallel.
1482
1610
 
1483
- Warning:
1484
- If may_prompt is true, output_stream SHOULD be sys.stdout and input_stream
1485
- SHOULD be sys.stdin.
1486
-
1487
1611
  Return:
1488
- A PresubmitOutput object. Use output.should_continue() to figure out
1489
- if there were errors or warnings and the caller should abort.
1612
+ 1 if presubmit checks failed or 0 otherwise.
1490
1613
  """
1491
1614
  old_environ = os.environ
1492
1615
  try:
@@ -1494,84 +1617,103 @@ def DoPresubmitChecks(change,
1494
1617
  os.environ = os.environ.copy()
1495
1618
  os.environ['PYTHONDONTWRITEBYTECODE'] = '1'
1496
1619
 
1497
- output = PresubmitOutput(input_stream, output_stream)
1498
1620
  if committing:
1499
- output.write("Running presubmit commit checks ...\n")
1621
+ sys.stdout.write('Running presubmit commit checks ...\n')
1500
1622
  else:
1501
- output.write("Running presubmit upload checks ...\n")
1502
- start_time = time.time()
1623
+ sys.stdout.write('Running presubmit upload checks ...\n')
1624
+ start_time = time_time()
1503
1625
  presubmit_files = ListRelevantPresubmitFiles(
1504
1626
  change.AbsoluteLocalPaths(), change.RepositoryRoot())
1505
1627
  if not presubmit_files and verbose:
1506
- output.write("Warning, no PRESUBMIT.py found.\n")
1628
+ sys.stdout.write('Warning, no PRESUBMIT.py found.\n')
1507
1629
  results = []
1508
1630
  thread_pool = ThreadPool()
1509
1631
  executer = PresubmitExecuter(change, committing, verbose, gerrit_obj,
1510
1632
  dry_run, thread_pool, parallel)
1511
1633
  if default_presubmit:
1512
1634
  if verbose:
1513
- output.write("Running default presubmit script.\n")
1635
+ sys.stdout.write('Running default presubmit script.\n')
1514
1636
  fake_path = os.path.join(change.RepositoryRoot(), 'PRESUBMIT.py')
1515
1637
  results += executer.ExecPresubmitScript(default_presubmit, fake_path)
1516
1638
  for filename in presubmit_files:
1517
1639
  filename = os.path.abspath(filename)
1518
1640
  if verbose:
1519
- output.write("Running %s\n" % filename)
1641
+ sys.stdout.write('Running %s\n' % filename)
1520
1642
  # Accept CRLF presubmit script.
1521
1643
  presubmit_script = gclient_utils.FileRead(filename, 'rU')
1522
1644
  results += executer.ExecPresubmitScript(presubmit_script, filename)
1523
1645
 
1524
1646
  results += thread_pool.RunAsync()
1525
1647
 
1526
- output.more_cc.extend(executer.more_cc)
1527
- errors = []
1528
- notifications = []
1529
- warnings = []
1648
+ messages = {}
1649
+ should_prompt = False
1650
+ presubmits_failed = False
1530
1651
  for result in results:
1531
1652
  if result.fatal:
1532
- errors.append(result)
1653
+ presubmits_failed = True
1654
+ messages.setdefault('ERRORS', []).append(result)
1533
1655
  elif result.should_prompt:
1534
- warnings.append(result)
1656
+ should_prompt = True
1657
+ messages.setdefault('Warnings', []).append(result)
1535
1658
  else:
1536
- notifications.append(result)
1537
-
1538
- output.write('\n')
1539
- for name, items in (('Messages', notifications),
1540
- ('Warnings', warnings),
1541
- ('ERRORS', errors)):
1542
- if items:
1543
- output.write('** Presubmit %s **\n' % name)
1544
- for item in items:
1545
- item.handle(output)
1546
- output.write('\n')
1547
-
1548
- total_time = time.time() - start_time
1659
+ messages.setdefault('Messages', []).append(result)
1660
+
1661
+ sys.stdout.write('\n')
1662
+ for name, items in messages.items():
1663
+ sys.stdout.write('** Presubmit %s **\n' % name)
1664
+ for item in items:
1665
+ item.handle()
1666
+ sys.stdout.write('\n')
1667
+
1668
+ total_time = time_time() - start_time
1549
1669
  if total_time > 1.0:
1550
- output.write("Presubmit checks took %.1fs to calculate.\n\n" % total_time)
1670
+ sys.stdout.write(
1671
+ 'Presubmit checks took %.1fs to calculate.\n\n' % total_time)
1551
1672
 
1552
- if errors:
1553
- output.fail()
1554
- elif warnings:
1555
- output.write('There were presubmit warnings. ')
1673
+ if not should_prompt and not presubmits_failed:
1674
+ sys.stdout.write('Presubmit checks passed.\n')
1675
+ elif should_prompt:
1676
+ sys.stdout.write('There were presubmit warnings. ')
1556
1677
  if may_prompt:
1557
- output.prompt_yes_no('Are you sure you wish to continue? (y/N): ')
1558
- else:
1559
- output.write('Presubmit checks passed.\n')
1678
+ presubmits_failed = not prompt_should_continue(
1679
+ 'Are you sure you wish to continue? (y/N): ')
1680
+
1681
+ if json_output:
1682
+ # Write the presubmit results to json output
1683
+ presubmit_results = {
1684
+ 'errors': [
1685
+ error.json_format()
1686
+ for error in messages.get('ERRORS', [])
1687
+ ],
1688
+ 'notifications': [
1689
+ notification.json_format()
1690
+ for notification in messages.get('Messages', [])
1691
+ ],
1692
+ 'warnings': [
1693
+ warning.json_format()
1694
+ for warning in messages.get('Warnings', [])
1695
+ ],
1696
+ 'more_cc': executer.more_cc,
1697
+ }
1698
+
1699
+ gclient_utils.FileWrite(
1700
+ json_output, json.dumps(presubmit_results, sort_keys=True))
1560
1701
 
1561
1702
  global _ASKED_FOR_FEEDBACK
1562
1703
  # Ask for feedback one time out of 5.
1563
1704
  if (len(results) and random.randint(0, 4) == 0 and not _ASKED_FOR_FEEDBACK):
1564
- output.write(
1705
+ sys.stdout.write(
1565
1706
  'Was the presubmit check useful? If not, run "git cl presubmit -v"\n'
1566
1707
  'to figure out which PRESUBMIT.py was run, then run git blame\n'
1567
1708
  'on the file to figure out who to ask for help.\n')
1568
1709
  _ASKED_FOR_FEEDBACK = True
1569
- return output
1710
+
1711
+ return 1 if presubmits_failed else 0
1570
1712
  finally:
1571
1713
  os.environ = old_environ
1572
1714
 
1573
1715
 
1574
- def ScanSubDirs(mask, recursive):
1716
+ def _scan_sub_dirs(mask, recursive):
1575
1717
  if not recursive:
1576
1718
  return [x for x in glob.glob(mask) if x not in ('.svn', '.git')]
1577
1719
 
@@ -1587,31 +1729,83 @@ def ScanSubDirs(mask, recursive):
1587
1729
  return results
1588
1730
 
1589
1731
 
1590
- def ParseFiles(args, recursive):
1732
+ def _parse_files(args, recursive):
1591
1733
  logging.debug('Searching for %s', args)
1592
1734
  files = []
1593
1735
  for arg in args:
1594
- files.extend([('M', f) for f in ScanSubDirs(arg, recursive)])
1736
+ files.extend([('M', f) for f in _scan_sub_dirs(arg, recursive)])
1595
1737
  return files
1596
1738
 
1597
1739
 
1598
- def load_files(options, args):
1599
- """Tries to determine the SCM."""
1600
- files = []
1601
- if args:
1602
- files = ParseFiles(args, options.recursive)
1740
+ def _parse_change(parser, options):
1741
+ """Process change options.
1742
+
1743
+ Args:
1744
+ parser: The parser used to parse the arguments from command line.
1745
+ options: The arguments parsed from command line.
1746
+ Returns:
1747
+ A GitChange if the change root is a git repository, or a Change otherwise.
1748
+ """
1749
+ if options.files and options.all_files:
1750
+ parser.error('<files> cannot be specified when --all-files is set.')
1751
+
1603
1752
  change_scm = scm.determine_scm(options.root)
1604
- if change_scm == 'git':
1605
- change_class = GitChange
1606
- upstream = options.upstream or None
1607
- if not files:
1608
- files = scm.GIT.CaptureStatus([], options.root, upstream)
1753
+ if change_scm != 'git' and not options.files:
1754
+ parser.error('<files> is not optional for unversioned directories.')
1755
+
1756
+ if options.files:
1757
+ change_files = _parse_files(options.files, options.recursive)
1758
+ elif options.all_files:
1759
+ change_files = [('M', f) for f in scm.GIT.GetAllFiles(options.root)]
1609
1760
  else:
1610
- logging.info('Doesn\'t seem under source control. Got %d files', len(args))
1611
- if not files:
1612
- return None, None
1613
- change_class = Change
1614
- return change_class, files
1761
+ change_files = scm.GIT.CaptureStatus(
1762
+ options.root, options.upstream or None)
1763
+
1764
+ logging.info('Found %d file(s).', len(change_files))
1765
+
1766
+ change_class = GitChange if change_scm == 'git' else Change
1767
+ return change_class(
1768
+ options.name,
1769
+ options.description,
1770
+ options.root,
1771
+ change_files,
1772
+ options.issue,
1773
+ options.patchset,
1774
+ options.author,
1775
+ upstream=options.upstream)
1776
+
1777
+
1778
+ def _parse_gerrit_options(parser, options):
1779
+ """Process gerrit options.
1780
+
1781
+ SIDE EFFECTS: Modifies options.author and options.description from Gerrit if
1782
+ options.gerrit_fetch is set.
1783
+
1784
+ Args:
1785
+ parser: The parser used to parse the arguments from command line.
1786
+ options: The arguments parsed from command line.
1787
+ Returns:
1788
+ A GerritAccessor object if options.gerrit_url is set, or None otherwise.
1789
+ """
1790
+ gerrit_obj = None
1791
+ if options.gerrit_url:
1792
+ gerrit_obj = GerritAccessor(urlparse.urlparse(options.gerrit_url).netloc)
1793
+
1794
+ if not options.gerrit_fetch:
1795
+ return gerrit_obj
1796
+
1797
+ if not options.gerrit_url or not options.issue or not options.patchset:
1798
+ parser.error(
1799
+ '--gerrit_fetch requires --gerrit_url, --issue and --patchset.')
1800
+
1801
+ options.author = gerrit_obj.GetChangeOwner(options.issue)
1802
+ options.description = gerrit_obj.GetChangeDescription(
1803
+ options.issue, options.patchset)
1804
+
1805
+ logging.info('Got author: "%s"', options.author)
1806
+ logging.info('Got description: """\n%s\n"""', options.description)
1807
+
1808
+ return gerrit_obj
1615
1809
 
1616
1810
 
1617
1811
  @contextlib.contextmanager
@@ -1626,97 +1820,97 @@ def canned_check_filter(method_names):
1626
1820
  setattr(presubmit_canned_checks, method_name, lambda *_a, **_kw: [])
1627
1821
  yield
1628
1822
  finally:
1629
- for name, method in filtered.iteritems():
1823
+ for name, method in filtered.items():
1630
1824
  setattr(presubmit_canned_checks, name, method)
1631
1825
 
1632
1826
 
1633
1827
  def main(argv=None):
1634
- parser = optparse.OptionParser(usage="%prog [options] <files...>",
1635
- version="%prog " + str(__version__))
1636
- parser.add_option("-c", "--commit", action="store_true", default=False,
1637
- help="Use commit instead of upload checks")
1638
- parser.add_option("-u", "--upload", action="store_false", dest='commit',
1639
- help="Use upload instead of commit checks")
1640
- parser.add_option("-r", "--recursive", action="store_true",
1641
- help="Act recursively")
1642
- parser.add_option("-v", "--verbose", action="count", default=0,
1643
- help="Use 2 times for more debug info")
1644
- parser.add_option("--name", default='no name')
1645
- parser.add_option("--author")
1646
- parser.add_option("--description", default='')
1647
- parser.add_option("--issue", type='int', default=0)
1648
- parser.add_option("--patchset", type='int', default=0)
1649
- parser.add_option("--root", default=os.getcwd(),
1650
- help="Search for PRESUBMIT.py up to this directory. "
1651
- "If inherit-review-settings-ok is present in this "
1652
- "directory, parent directories up to the root file "
1653
- "system directories will also be searched.")
1654
- parser.add_option("--upstream",
1655
- help="Git only: the base ref or upstream branch against "
1656
- "which the diff should be computed.")
1657
- parser.add_option("--default_presubmit")
1658
- parser.add_option("--may_prompt", action='store_true', default=False)
1659
- parser.add_option("--skip_canned", action='append', default=[],
1660
- help="A list of checks to skip which appear in "
1661
- "presubmit_canned_checks. Can be provided multiple times "
1662
- "to skip multiple canned checks.")
1663
- parser.add_option("--dry_run", action='store_true',
1664
- help=optparse.SUPPRESS_HELP)
1665
- parser.add_option("--gerrit_url", help=optparse.SUPPRESS_HELP)
1666
- parser.add_option("--gerrit_fetch", action='store_true',
1667
- help=optparse.SUPPRESS_HELP)
1668
- parser.add_option('--parallel', action='store_true',
1669
- help='Run all tests specified by input_api.RunTests in all '
1670
- 'PRESUBMIT files in parallel.')
1671
-
1672
- options, args = parser.parse_args(argv)
1673
-
1828
+ parser = argparse.ArgumentParser(usage='%(prog)s [options] <files...>')
1829
+ hooks = parser.add_mutually_exclusive_group()
1830
+ hooks.add_argument('-c', '--commit', action='store_true',
1831
+ help='Use commit instead of upload checks.')
1832
+ hooks.add_argument('-u', '--upload', action='store_false', dest='commit',
1833
+ help='Use upload instead of commit checks.')
1834
+ hooks.add_argument('--post_upload', action='store_true',
1835
+ help='Run post-upload commit hooks.')
1836
+ parser.add_argument('-r', '--recursive', action='store_true',
1837
+ help='Act recursively.')
1838
+ parser.add_argument('-v', '--verbose', action='count', default=0,
1839
+ help='Use 2 times for more debug info.')
1840
+ parser.add_argument('--name', default='no name')
1841
+ parser.add_argument('--author')
1842
+ desc = parser.add_mutually_exclusive_group()
1843
+ desc.add_argument('--description', default='', help='The change description.')
1844
+ desc.add_argument('--description_file',
1845
+ help='File to read change description from.')
1846
+ parser.add_argument('--issue', type=int, default=0)
1847
+ parser.add_argument('--patchset', type=int, default=0)
1848
+ parser.add_argument('--root', default=os.getcwd(),
1849
+ help='Search for PRESUBMIT.py up to this directory. '
1850
+ 'If inherit-review-settings-ok is present in this '
1851
+ 'directory, parent directories up to the root file '
1852
+ 'system directories will also be searched.')
1853
+ parser.add_argument('--upstream',
1854
+ help='Git only: the base ref or upstream branch against '
1855
+ 'which the diff should be computed.')
1856
+ parser.add_argument('--default_presubmit')
1857
+ parser.add_argument('--may_prompt', action='store_true', default=False)
1858
+ parser.add_argument('--skip_canned', action='append', default=[],
1859
+ help='A list of checks to skip which appear in '
1860
+ 'presubmit_canned_checks. Can be provided multiple times '
1861
+ 'to skip multiple canned checks.')
1862
+ parser.add_argument('--dry_run', action='store_true', help=argparse.SUPPRESS)
1863
+ parser.add_argument('--gerrit_url', help=argparse.SUPPRESS)
1864
+ parser.add_argument('--gerrit_fetch', action='store_true',
1865
+ help=argparse.SUPPRESS)
1866
+ parser.add_argument('--parallel', action='store_true',
1867
+ help='Run all tests specified by input_api.RunTests in '
1868
+ 'all PRESUBMIT files in parallel.')
1869
+ parser.add_argument('--json_output',
1870
+ help='Write presubmit errors to json output.')
1871
+ parser.add_argument('--all_files', action='store_true',
1872
+ help='Mark all files under source control as modified.')
1873
+ parser.add_argument('files', nargs='*',
1874
+ help='List of files to be marked as modified when '
1875
+ 'executing presubmit or post-upload hooks. fnmatch '
1876
+ 'wildcards can also be used.')
1877
+
1878
+ options = parser.parse_args(argv)
1879
+
1880
+ log_level = logging.ERROR
1674
1881
  if options.verbose >= 2:
1675
- logging.basicConfig(level=logging.DEBUG)
1882
+ log_level = logging.DEBUG
1676
1883
  elif options.verbose:
1677
- logging.basicConfig(level=logging.INFO)
1678
- else:
1679
- logging.basicConfig(level=logging.ERROR)
1680
-
1681
- change_class, files = load_files(options, args)
1682
- if not change_class:
1683
- parser.error('For unversioned directory, <files> is not optional.')
1684
- logging.info('Found %d file(s).', len(files))
1884
+ log_level = logging.INFO
1885
+ log_format = ('[%(levelname).1s%(asctime)s %(process)d %(thread)d '
1886
+ '%(filename)s] %(message)s')
1887
+ logging.basicConfig(format=log_format, level=log_level)
1685
1888
 
1686
- gerrit_obj = None
1687
- if options.gerrit_url and options.gerrit_fetch:
1688
- assert options.issue and options.patchset
1689
- gerrit_obj = GerritAccessor(urlparse.urlparse(options.gerrit_url).netloc)
1690
- options.author = gerrit_obj.GetChangeOwner(options.issue)
1691
- options.description = gerrit_obj.GetChangeDescription(options.issue,
1692
- options.patchset)
1693
- logging.info('Got author: "%s"', options.author)
1694
- logging.info('Got description: """\n%s\n"""', options.description)
1889
+ if options.description_file:
1890
+ options.description = gclient_utils.FileRead(options.description_file)
1891
+ gerrit_obj = _parse_gerrit_options(parser, options)
1892
+ change = _parse_change(parser, options)
1695
1893
 
1696
1894
  try:
1895
+ if options.post_upload:
1896
+ return DoPostUploadExecuter(
1897
+ change,
1898
+ gerrit_obj,
1899
+ options.verbose)
1697
1900
  with canned_check_filter(options.skip_canned):
1698
- results = DoPresubmitChecks(
1699
- change_class(options.name,
1700
- options.description,
1701
- options.root,
1702
- files,
1703
- options.issue,
1704
- options.patchset,
1705
- options.author,
1706
- upstream=options.upstream),
1901
+ return DoPresubmitChecks(
1902
+ change,
1707
1903
  options.commit,
1708
1904
  options.verbose,
1709
- sys.stdout,
1710
- sys.stdin,
1711
1905
  options.default_presubmit,
1712
1906
  options.may_prompt,
1713
1907
  gerrit_obj,
1714
1908
  options.dry_run,
1715
- options.parallel)
1716
- return not results.should_continue()
1717
- except PresubmitFailure, e:
1718
- print >> sys.stderr, e
1719
- print >> sys.stderr, 'Maybe your depot_tools is out of date?'
1909
+ options.parallel,
1910
+ options.json_output)
1911
+ except PresubmitFailure as e:
1912
+ print(e, file=sys.stderr)
1913
+ print('Maybe your depot_tools is out of date?', file=sys.stderr)
1720
1914
  return 2
1721
1915
 
1722
1916