libv8 7.3.492.27.0 → 8.4.255.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +11 -14
- data/CHANGELOG.md +10 -0
- data/README.md +10 -11
- data/Rakefile +30 -36
- data/ext/libv8/builder.rb +1 -1
- data/lib/libv8/version.rb +1 -1
- data/libv8.gemspec +1 -3
- data/vendor/depot_tools/{cipd.ps1 → .cipd_impl.ps1} +0 -0
- data/vendor/depot_tools/.gitattributes +1 -1
- data/vendor/depot_tools/.gitignore +7 -2
- data/vendor/depot_tools/.style.yapf +3 -1
- data/vendor/depot_tools/.vpython +55 -0
- data/vendor/depot_tools/.vpython3 +23 -0
- data/vendor/depot_tools/CROS_OWNERS +3 -1
- data/vendor/depot_tools/GOMA_OWNERS +9 -0
- data/vendor/depot_tools/LUCI_OWNERS +5 -0
- data/vendor/depot_tools/OWNERS +21 -6
- data/vendor/depot_tools/PRESUBMIT.py +35 -18
- data/vendor/depot_tools/README.git-cl.md +0 -14
- data/vendor/depot_tools/README.md +1 -1
- data/vendor/depot_tools/WATCHLISTS +2 -2
- data/vendor/depot_tools/auth.py +60 -772
- data/vendor/depot_tools/autoninja +12 -6
- data/vendor/depot_tools/autoninja.bat +14 -6
- data/vendor/depot_tools/autoninja.py +64 -27
- data/vendor/depot_tools/bb +1 -1
- data/vendor/depot_tools/bootstrap/{win/README.md → README.md} +28 -14
- data/vendor/depot_tools/bootstrap/{win/win_tools.py → bootstrap.py} +60 -43
- data/vendor/depot_tools/bootstrap/{win/git-bash.template.sh → git-bash.template.sh} +1 -1
- data/vendor/depot_tools/bootstrap/{win/git.template.bat → git.template.bat} +0 -0
- data/vendor/depot_tools/bootstrap/manifest.txt +27 -0
- data/vendor/depot_tools/bootstrap/manifest_bleeding_edge.txt +27 -0
- data/vendor/depot_tools/bootstrap/{win/profile.d.python.sh → profile.d.python.sh} +0 -0
- data/vendor/depot_tools/bootstrap/{win/python27.bleeding_edge.bat → python27.bat} +0 -0
- data/vendor/depot_tools/bootstrap/{win/python27.new.bat → python3.bat} +3 -3
- data/vendor/depot_tools/bootstrap/{win/win_tools.bat → win_tools.bat} +21 -16
- data/vendor/depot_tools/bootstrap_python3 +35 -0
- data/vendor/depot_tools/cbuildbot +1 -1
- data/vendor/depot_tools/chrome_set_ver +1 -1
- data/vendor/depot_tools/cipd +43 -39
- data/vendor/depot_tools/cipd.bat +2 -2
- data/vendor/depot_tools/cipd_client_version +1 -1
- data/vendor/depot_tools/cipd_client_version.digests +15 -14
- data/vendor/depot_tools/cipd_manifest.txt +31 -8
- data/vendor/depot_tools/cipd_manifest.versions +278 -158
- data/vendor/depot_tools/cit.py +9 -7
- data/vendor/depot_tools/clang_format.py +4 -1
- data/vendor/depot_tools/clang_format_merge_driver.py +10 -8
- data/vendor/depot_tools/compile_single_file.py +7 -2
- data/vendor/depot_tools/cpplint.py +51 -45
- data/vendor/depot_tools/cros +87 -0
- data/vendor/depot_tools/cros_sdk +1 -1
- data/vendor/depot_tools/crosjobs +13 -0
- data/vendor/depot_tools/detect_host_arch.py +0 -1
- data/vendor/depot_tools/dirmd +12 -0
- data/vendor/depot_tools/dirmd.bat +7 -0
- data/vendor/depot_tools/download_from_google_storage.py +47 -27
- data/vendor/depot_tools/ensure_bootstrap +14 -0
- data/vendor/depot_tools/fetch +14 -1
- data/vendor/depot_tools/fetch.bat +14 -1
- data/vendor/depot_tools/fetch.py +5 -7
- data/vendor/depot_tools/fetch_configs/chromium.py +6 -4
- data/vendor/depot_tools/fetch_configs/devtools-frontend.py +44 -0
- data/vendor/depot_tools/fetch_configs/ios_internal.py +10 -19
- data/vendor/depot_tools/fix_encoding.py +19 -5
- data/vendor/depot_tools/gclient +28 -12
- data/vendor/depot_tools/gclient-new-workdir.py +2 -0
- data/vendor/depot_tools/gclient.bat +18 -1
- data/vendor/depot_tools/gclient.py +160 -119
- data/vendor/depot_tools/gclient_eval.py +119 -107
- data/vendor/depot_tools/gclient_paths.py +67 -57
- data/vendor/depot_tools/gclient_scm.py +181 -159
- data/vendor/depot_tools/gclient_utils.py +177 -124
- data/vendor/depot_tools/gerrit_client.py +21 -13
- data/vendor/depot_tools/gerrit_util.py +188 -228
- data/vendor/depot_tools/git-cache +1 -1
- data/vendor/depot_tools/git-cl +1 -1
- data/vendor/depot_tools/git-drover +1 -1
- data/vendor/depot_tools/git-find-releases +1 -1
- data/vendor/depot_tools/git-footers +1 -1
- data/vendor/depot_tools/git-freeze +1 -1
- data/vendor/depot_tools/git-hyper-blame +1 -1
- data/vendor/depot_tools/git-map +1 -1
- data/vendor/depot_tools/git-map-branches +1 -1
- data/vendor/depot_tools/git-mark-merge-base +1 -1
- data/vendor/depot_tools/git-nav-downstream +1 -1
- data/vendor/depot_tools/git-new-branch +1 -1
- data/vendor/depot_tools/git-number +1 -1
- data/vendor/depot_tools/git-rebase-update +1 -1
- data/vendor/depot_tools/git-rename-branch +1 -1
- data/vendor/depot_tools/git-reparent-branch +1 -1
- data/vendor/depot_tools/git-retry +1 -1
- data/vendor/depot_tools/git-squash-branch +1 -1
- data/vendor/depot_tools/git-thaw +1 -1
- data/vendor/depot_tools/git-upstream-diff +1 -1
- data/vendor/depot_tools/git_cache.py +255 -360
- data/vendor/depot_tools/git_cl.py +1562 -2059
- data/vendor/depot_tools/git_cl_completion.sh +16 -2
- data/vendor/depot_tools/git_common.py +77 -32
- data/vendor/depot_tools/git_drover.py +17 -8
- data/vendor/depot_tools/git_find_releases.py +11 -9
- data/vendor/depot_tools/git_footers.py +13 -9
- data/vendor/depot_tools/git_freezer.py +3 -1
- data/vendor/depot_tools/git_hyper_blame.py +25 -32
- data/vendor/depot_tools/git_map.py +115 -93
- data/vendor/depot_tools/git_map_branches.py +11 -10
- data/vendor/depot_tools/git_mark_merge_base.py +8 -6
- data/vendor/depot_tools/git_nav_downstream.py +9 -6
- data/vendor/depot_tools/git_new_branch.py +39 -33
- data/vendor/depot_tools/git_number.py +28 -17
- data/vendor/depot_tools/git_rebase_update.py +50 -49
- data/vendor/depot_tools/git_rename_branch.py +2 -2
- data/vendor/depot_tools/git_reparent_branch.py +8 -6
- data/vendor/depot_tools/git_upstream_diff.py +4 -2
- data/vendor/depot_tools/gn.py +6 -4
- data/vendor/depot_tools/goma_auth +12 -0
- data/vendor/depot_tools/goma_auth.bat +8 -0
- data/vendor/depot_tools/goma_ctl +12 -0
- data/vendor/depot_tools/goma_ctl.bat +8 -0
- data/vendor/depot_tools/gsutil.py +5 -2
- data/vendor/depot_tools/gsutil.py.bat +8 -0
- data/vendor/depot_tools/gsutil.vpython +3 -1
- data/vendor/depot_tools/infra/config/OWNERS +2 -2
- data/vendor/depot_tools/infra/config/recipes.cfg +3 -2
- data/vendor/depot_tools/led +1 -1
- data/vendor/depot_tools/lockfile.py +116 -0
- data/vendor/depot_tools/luci-auth +1 -1
- data/vendor/depot_tools/lucicfg +1 -1
- data/vendor/depot_tools/mac_toolchain +1 -1
- data/vendor/depot_tools/man/html/depot_tools.html +1 -1
- data/vendor/depot_tools/man/html/depot_tools_tutorial.html +31 -25
- data/vendor/depot_tools/man/html/git-cl.html +1 -1
- data/vendor/depot_tools/man/html/git-drover.html +18 -18
- data/vendor/depot_tools/man/html/git-footers.html +1 -1
- data/vendor/depot_tools/man/html/git-freeze.html +3 -3
- data/vendor/depot_tools/man/html/git-hyper-blame.html +1 -1
- data/vendor/depot_tools/man/html/git-map-branches.html +2 -2
- data/vendor/depot_tools/man/html/git-map.html +1 -1
- data/vendor/depot_tools/man/html/git-mark-merge-base.html +1 -1
- data/vendor/depot_tools/man/html/git-nav-downstream.html +3 -3
- data/vendor/depot_tools/man/html/git-nav-upstream.html +12 -6
- data/vendor/depot_tools/man/html/git-new-branch.html +1 -1
- data/vendor/depot_tools/man/html/git-rebase-update.html +20 -1
- data/vendor/depot_tools/man/html/git-rename-branch.html +1 -1
- data/vendor/depot_tools/man/html/git-reparent-branch.html +1 -1
- data/vendor/depot_tools/man/html/git-retry.html +1 -1
- data/vendor/depot_tools/man/html/git-squash-branch.html +1 -1
- data/vendor/depot_tools/man/html/git-thaw.html +1 -1
- data/vendor/depot_tools/man/html/git-upstream-diff.html +10 -6
- data/vendor/depot_tools/man/man1/git-cl.1 +4 -4
- data/vendor/depot_tools/man/man1/git-drover.1 +21 -21
- data/vendor/depot_tools/man/man1/git-footers.1 +4 -4
- data/vendor/depot_tools/man/man1/git-freeze.1 +6 -6
- data/vendor/depot_tools/man/man1/git-hyper-blame.1 +4 -4
- data/vendor/depot_tools/man/man1/git-map-branches.1 +4 -4
- data/vendor/depot_tools/man/man1/git-map.1 +4 -4
- data/vendor/depot_tools/man/man1/git-mark-merge-base.1 +4 -4
- data/vendor/depot_tools/man/man1/git-nav-downstream.1 +6 -6
- data/vendor/depot_tools/man/man1/git-nav-upstream.1 +15 -9
- data/vendor/depot_tools/man/man1/git-new-branch.1 +3 -3
- data/vendor/depot_tools/man/man1/git-rebase-update.1 +14 -4
- data/vendor/depot_tools/man/man1/git-rename-branch.1 +4 -4
- data/vendor/depot_tools/man/man1/git-reparent-branch.1 +4 -4
- data/vendor/depot_tools/man/man1/git-retry.1 +4 -4
- data/vendor/depot_tools/man/man1/git-squash-branch.1 +4 -4
- data/vendor/depot_tools/man/man1/git-thaw.1 +4 -4
- data/vendor/depot_tools/man/man1/git-upstream-diff.1 +7 -13
- data/vendor/depot_tools/man/man7/depot_tools.7 +4 -4
- data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +31 -25
- data/vendor/depot_tools/man/src/common_demo_functions.sh +2 -2
- data/vendor/depot_tools/man/src/depot_tools_tutorial.txt +3 -3
- data/vendor/depot_tools/man/src/filter_demo_output.py +4 -2
- data/vendor/depot_tools/man/src/git-new-branch.txt +2 -1
- data/vendor/depot_tools/man/src/git-rebase-update.txt +8 -1
- data/vendor/depot_tools/metrics.README.md +8 -5
- data/vendor/depot_tools/metrics.py +7 -6
- data/vendor/depot_tools/metrics_utils.py +4 -14
- data/vendor/depot_tools/my_activity.py +85 -251
- data/vendor/depot_tools/ninja +1 -0
- data/vendor/depot_tools/ninja-mac +0 -0
- data/vendor/depot_tools/ninjalog_uploader.py +146 -145
- data/vendor/depot_tools/ninjalog_uploader_wrapper.py +69 -60
- data/vendor/depot_tools/owners.py +156 -43
- data/vendor/depot_tools/owners_finder.py +28 -14
- data/vendor/depot_tools/post_build_ninja_summary.py +76 -48
- data/vendor/depot_tools/presubmit_canned_checks.py +293 -106
- data/vendor/depot_tools/presubmit_support.py +527 -333
- data/vendor/depot_tools/prpc +1 -1
- data/vendor/depot_tools/pylint +2 -12
- data/vendor/depot_tools/pylint-1.5 +78 -0
- data/vendor/depot_tools/pylint-1.6 +78 -0
- data/vendor/depot_tools/pylint-1.7 +78 -0
- data/vendor/depot_tools/pylint-1.8 +78 -0
- data/vendor/depot_tools/pylint-1.9 +78 -0
- data/vendor/depot_tools/{depot-tools-auth.bat → pylint.bat} +2 -2
- data/vendor/depot_tools/pylint_main.py +45 -0
- data/vendor/depot_tools/pylintrc +14 -1
- data/vendor/depot_tools/python-bin/python3 +7 -0
- data/vendor/depot_tools/python_runner.sh +13 -8
- data/vendor/depot_tools/rdb +12 -0
- data/vendor/depot_tools/rdb.bat +7 -0
- data/vendor/depot_tools/recipes/OWNERS +0 -1
- data/vendor/depot_tools/recipes/README.recipes.md +218 -151
- data/vendor/depot_tools/recipes/recipe_modules/OWNERS +1 -1
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +17 -16
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +127 -78
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic.json +19 -4
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_luci.json +18 -3
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_with_branch_heads.json +19 -4
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/clobber.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +28 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_rebase_patch_ref.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_reset.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/input_commit_with_id_without_repo.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/multiple_patch_refs.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_apply_patch_on_gclient.json +35 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{with_manifest_name.json → no_cp_checkout_HEAD.json} +25 -15
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_a_branch_head.json +65 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_a_specific_commit.json +65 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_master.json +65 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/refs.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/reset_root_solution_revision.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/resolve_chromium_fixed_version.json +117 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +17 -11
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +41 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +24 -11
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle.json +35 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_branch_heads.json +35 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_feature_branch.json +38 -11
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8_feature_branch.json +36 -11
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_webrtc.json +35 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +35 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +35 -10
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/unrecognized_commit_repo.json +0 -5
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_tags.json +29 -8
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +95 -22
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +187 -114
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +2 -2
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/do_not_retry_patch_failures_in_cq.py +42 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/ensure_checkout.py +1 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/__init__.py +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/api.py +2 -2
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic_pkg.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-failed.json +2 -4
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-many-instances.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/mac64.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_file.json +26 -6
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_mode.json +23 -5
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_verfile.json +23 -5
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/win64.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk arch.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk bits.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_32.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_64.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_32.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_64.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_mips_64.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/mac_intel_64.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_32.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_64.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/cipd/test_api.py +1 -1
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/api.py +4 -1
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json +4 -2
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic_luci.json +3 -1
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/win.json +4 -2
- data/vendor/depot_tools/recipes/recipe_modules/gclient/__init__.py +2 -1
- data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +82 -13
- data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +23 -11
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +3 -4
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +3 -6
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +3 -4
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +7 -7
- data/vendor/depot_tools/recipes/recipe_modules/gclient/resources/diff_deps.py +16 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/test_api.py +4 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/basic.json +55 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/dont have revision yet.json +84 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/no change, exception.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/windows.json +55 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.py +88 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/patch_project.py +9 -21
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/sync_failure.py +24 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +2 -1
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +7 -12
- data/vendor/depot_tools/recipes/recipe_modules/git/__init__.py +0 -2
- data/vendor/depot_tools/recipes/recipe_modules/git/api.py +9 -17
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_branch.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_file_name.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_hash.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_ref.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_submodule_update_force.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_tags.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/can_fail_build.json +3 -13
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cannot_fail_build.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cat-file_test.json +4 -12
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_delta.json +2 -10
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_failed.json +1 -7
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output.json +1 -7
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output_fails_build.json +0 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/curl_trace_file.json +3 -10
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/git-cache-checkout.json +3 -11
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/platform_win.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/rebase_failed.json +3 -13
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/remote_not_origin.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/set_got_revision.json +2 -8
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.py +0 -5
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/__init__.py +1 -1
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/api.py +7 -13
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.expected/basic.json +21 -16
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.py +1 -2
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/api.py +1 -1
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.expected/basic.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/resources/gerrit_client.py +2 -2
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.expected/basic.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/api.py +23 -8
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.expected/basic.json +52 -1
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.py +15 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/__init__.py +1 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/api.py +32 -8
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/ancient_version.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/automatic_version.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/explicit_version.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/linux.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/mac.json +5 -4
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/win.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.py +21 -2
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/__init__.py +20 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/api.py +235 -3
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.expected/basic.json +13 -5
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.py +5 -1
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/properties.proto +14 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/test_api.py +19 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/tests/execute.py +247 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/tests/prepare.py +49 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +33 -45
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/basic_tags.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json +64 -21
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch_and_target_ref.json +64 -21
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +1 -22
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch_new.json +1 -22
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +5 -32
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_fetch_ref_timeout.py +29 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_owner.expected/basic.json +5 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_owner.py +22 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_target_ref.py +32 -0
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/linux.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/mac.json +0 -1
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/win.json +2 -1
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.py +1 -6
- data/vendor/depot_tools/recipes/recipes.py +49 -28
- data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.expected/basic.json +11 -6
- data/vendor/depot_tools/repo +698 -540
- data/vendor/depot_tools/roll-dep +14 -1
- data/vendor/depot_tools/roll-dep.bat +10 -1
- data/vendor/depot_tools/roll_dep.py +15 -10
- data/vendor/depot_tools/scm.py +95 -75
- data/vendor/depot_tools/setup_color.py +36 -2
- data/vendor/depot_tools/split_cl.py +44 -32
- data/vendor/depot_tools/subcommand.py +6 -6
- data/vendor/depot_tools/subprocess2.py +38 -322
- data/vendor/depot_tools/third_party/colorama/LICENSE.txt +0 -1
- data/vendor/depot_tools/third_party/colorama/README.chromium +4 -5
- data/vendor/depot_tools/third_party/colorama/README.rst +346 -0
- data/vendor/depot_tools/third_party/colorama/__init__.py +3 -4
- data/vendor/depot_tools/third_party/colorama/ansi.py +82 -30
- data/vendor/depot_tools/third_party/colorama/ansitowin32.py +105 -37
- data/vendor/depot_tools/third_party/colorama/initialise.py +39 -15
- data/vendor/depot_tools/third_party/colorama/win32.py +46 -28
- data/vendor/depot_tools/third_party/colorama/winterm.py +80 -31
- data/vendor/depot_tools/update_depot_tools +18 -8
- data/vendor/depot_tools/update_depot_tools.bat +19 -15
- data/vendor/depot_tools/upload_metrics.py +7 -6
- data/vendor/depot_tools/upload_to_google_storage.py +23 -16
- data/vendor/depot_tools/vpython +4 -4
- data/vendor/depot_tools/vpython.bat +1 -1
- data/vendor/depot_tools/vpython3 +55 -0
- data/vendor/depot_tools/vpython3.bat +12 -0
- data/vendor/depot_tools/watchlists.py +14 -11
- data/vendor/depot_tools/weekly +4 -2
- data/vendor/depot_tools/win32imports.py +61 -0
- data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +49 -41
- data/vendor/depot_tools/win_toolchain/package_from_installed.py +142 -149
- data/vendor/depot_tools/wtf +5 -3
- data/vendor/depot_tools/yapf +5 -1
- metadata +68 -343
- data/vendor/depot_tools/README.testing +0 -23
- data/vendor/depot_tools/annotated_gclient.py +0 -89
- data/vendor/depot_tools/appengine_mapper.py +0 -23
- data/vendor/depot_tools/bootstrap/win/manifest.txt +0 -20
- data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +0 -20
- data/vendor/depot_tools/bootstrap/win/pylint.new.bat +0 -7
- data/vendor/depot_tools/buildbucket.py +0 -186
- data/vendor/depot_tools/checkout.py +0 -431
- data/vendor/depot_tools/cros +0 -1
- data/vendor/depot_tools/dart_format.py +0 -58
- data/vendor/depot_tools/depot-tools-auth +0 -8
- data/vendor/depot_tools/depot-tools-auth.py +0 -102
- data/vendor/depot_tools/my_reviews.py +0 -396
- data/vendor/depot_tools/patch.py +0 -548
- data/vendor/depot_tools/pylint.py +0 -30
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +0 -239
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_luci.json +0 -222
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/__init__.py +0 -4
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/api.py +0 -29
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/basic.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_linux.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_mac.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_win.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_linux.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_mac.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_win.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_linux.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_mac.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_win.json +0 -15
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.py +0 -33
- data/vendor/depot_tools/recipes/recipe_modules/infra_paths/path_config.py +0 -66
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/set_failure_hash_with_no_steps.json +0 -11
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch.json +0 -45
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch_luci.json +0 -45
- data/vendor/depot_tools/rietveld.py +0 -779
- data/vendor/depot_tools/roll-dep-svn +0 -8
- data/vendor/depot_tools/roll-dep-svn.bat +0 -12
- data/vendor/depot_tools/roll_dep_svn.py +0 -430
- data/vendor/depot_tools/support/chromite_wrapper +0 -96
- data/vendor/depot_tools/third_party/boto/LICENSE +0 -18
- data/vendor/depot_tools/third_party/boto/README.chromium +0 -43
- data/vendor/depot_tools/third_party/boto/README.rst +0 -163
- data/vendor/depot_tools/third_party/boto/__init__.py +0 -793
- data/vendor/depot_tools/third_party/boto/auth.py +0 -682
- data/vendor/depot_tools/third_party/boto/auth_handler.py +0 -58
- data/vendor/depot_tools/third_party/boto/cacerts/__init__.py +0 -22
- data/vendor/depot_tools/third_party/boto/cacerts/cacerts.txt +0 -2183
- data/vendor/depot_tools/third_party/boto/compat.py +0 -28
- data/vendor/depot_tools/third_party/boto/connection.py +0 -1081
- data/vendor/depot_tools/third_party/boto/contrib/__init__.py +0 -22
- data/vendor/depot_tools/third_party/boto/contrib/ymlmessage.py +0 -52
- data/vendor/depot_tools/third_party/boto/core/README +0 -58
- data/vendor/depot_tools/third_party/boto/core/__init__.py +0 -23
- data/vendor/depot_tools/third_party/boto/core/auth.py +0 -78
- data/vendor/depot_tools/third_party/boto/core/credentials.py +0 -154
- data/vendor/depot_tools/third_party/boto/core/dictresponse.py +0 -178
- data/vendor/depot_tools/third_party/boto/core/service.py +0 -67
- data/vendor/depot_tools/third_party/boto/datapipeline/__init__.py +0 -0
- data/vendor/depot_tools/third_party/boto/datapipeline/exceptions.py +0 -42
- data/vendor/depot_tools/third_party/boto/datapipeline/layer1.py +0 -546
- data/vendor/depot_tools/third_party/boto/ecs/__init__.py +0 -90
- data/vendor/depot_tools/third_party/boto/ecs/item.py +0 -153
- data/vendor/depot_tools/third_party/boto/exception.py +0 -476
- data/vendor/depot_tools/third_party/boto/file/README +0 -49
- data/vendor/depot_tools/third_party/boto/file/__init__.py +0 -28
- data/vendor/depot_tools/third_party/boto/file/bucket.py +0 -112
- data/vendor/depot_tools/third_party/boto/file/connection.py +0 -33
- data/vendor/depot_tools/third_party/boto/file/key.py +0 -199
- data/vendor/depot_tools/third_party/boto/file/simpleresultset.py +0 -30
- data/vendor/depot_tools/third_party/boto/fps/__init__.py +0 -21
- data/vendor/depot_tools/third_party/boto/fps/connection.py +0 -369
- data/vendor/depot_tools/third_party/boto/fps/exception.py +0 -344
- data/vendor/depot_tools/third_party/boto/fps/response.py +0 -175
- data/vendor/depot_tools/third_party/boto/gs/__init__.py +0 -22
- data/vendor/depot_tools/third_party/boto/gs/acl.py +0 -304
- data/vendor/depot_tools/third_party/boto/gs/bucket.py +0 -870
- data/vendor/depot_tools/third_party/boto/gs/bucketlistresultset.py +0 -64
- data/vendor/depot_tools/third_party/boto/gs/connection.py +0 -103
- data/vendor/depot_tools/third_party/boto/gs/cors.py +0 -169
- data/vendor/depot_tools/third_party/boto/gs/key.py +0 -704
- data/vendor/depot_tools/third_party/boto/gs/resumable_upload_handler.py +0 -659
- data/vendor/depot_tools/third_party/boto/gs/user.py +0 -54
- data/vendor/depot_tools/third_party/boto/handler.py +0 -44
- data/vendor/depot_tools/third_party/boto/https_connection.py +0 -124
- data/vendor/depot_tools/third_party/boto/jsonresponse.py +0 -163
- data/vendor/depot_tools/third_party/boto/manage/__init__.py +0 -23
- data/vendor/depot_tools/third_party/boto/manage/cmdshell.py +0 -241
- data/vendor/depot_tools/third_party/boto/manage/propget.py +0 -64
- data/vendor/depot_tools/third_party/boto/manage/server.py +0 -556
- data/vendor/depot_tools/third_party/boto/manage/task.py +0 -175
- data/vendor/depot_tools/third_party/boto/manage/test_manage.py +0 -34
- data/vendor/depot_tools/third_party/boto/manage/volume.py +0 -420
- data/vendor/depot_tools/third_party/boto/mashups/__init__.py +0 -23
- data/vendor/depot_tools/third_party/boto/mashups/interactive.py +0 -97
- data/vendor/depot_tools/third_party/boto/mashups/iobject.py +0 -115
- data/vendor/depot_tools/third_party/boto/mashups/order.py +0 -211
- data/vendor/depot_tools/third_party/boto/mashups/server.py +0 -395
- data/vendor/depot_tools/third_party/boto/plugin.py +0 -90
- data/vendor/depot_tools/third_party/boto/provider.py +0 -337
- data/vendor/depot_tools/third_party/boto/pyami/__init__.py +0 -22
- data/vendor/depot_tools/third_party/boto/pyami/bootstrap.py +0 -134
- data/vendor/depot_tools/third_party/boto/pyami/config.py +0 -229
- data/vendor/depot_tools/third_party/boto/pyami/copybot.cfg +0 -60
- data/vendor/depot_tools/third_party/boto/pyami/copybot.py +0 -97
- data/vendor/depot_tools/third_party/boto/pyami/helloworld.py +0 -28
- data/vendor/depot_tools/third_party/boto/pyami/launch_ami.py +0 -178
- data/vendor/depot_tools/third_party/boto/pyami/scriptbase.py +0 -44
- data/vendor/depot_tools/third_party/boto/pyami/startup.py +0 -60
- data/vendor/depot_tools/third_party/boto/regioninfo.py +0 -63
- data/vendor/depot_tools/third_party/boto/resultset.py +0 -169
- data/vendor/depot_tools/third_party/boto/roboto/__init__.py +0 -1
- data/vendor/depot_tools/third_party/boto/roboto/awsqueryrequest.py +0 -504
- data/vendor/depot_tools/third_party/boto/roboto/awsqueryservice.py +0 -121
- data/vendor/depot_tools/third_party/boto/roboto/param.py +0 -147
- data/vendor/depot_tools/third_party/boto/s3/__init__.py +0 -84
- data/vendor/depot_tools/third_party/boto/s3/acl.py +0 -164
- data/vendor/depot_tools/third_party/boto/s3/bucket.py +0 -1634
- data/vendor/depot_tools/third_party/boto/s3/bucketlistresultset.py +0 -139
- data/vendor/depot_tools/third_party/boto/s3/bucketlogging.py +0 -83
- data/vendor/depot_tools/third_party/boto/s3/connection.py +0 -540
- data/vendor/depot_tools/third_party/boto/s3/cors.py +0 -210
- data/vendor/depot_tools/third_party/boto/s3/deletemarker.py +0 -55
- data/vendor/depot_tools/third_party/boto/s3/key.py +0 -1712
- data/vendor/depot_tools/third_party/boto/s3/keyfile.py +0 -134
- data/vendor/depot_tools/third_party/boto/s3/lifecycle.py +0 -231
- data/vendor/depot_tools/third_party/boto/s3/multidelete.py +0 -138
- data/vendor/depot_tools/third_party/boto/s3/multipart.py +0 -315
- data/vendor/depot_tools/third_party/boto/s3/prefix.py +0 -42
- data/vendor/depot_tools/third_party/boto/s3/resumable_download_handler.py +0 -339
- data/vendor/depot_tools/third_party/boto/s3/tagging.py +0 -71
- data/vendor/depot_tools/third_party/boto/s3/user.py +0 -49
- data/vendor/depot_tools/third_party/boto/s3/website.py +0 -237
- data/vendor/depot_tools/third_party/boto/services/__init__.py +0 -23
- data/vendor/depot_tools/third_party/boto/services/bs.py +0 -179
- data/vendor/depot_tools/third_party/boto/services/message.py +0 -58
- data/vendor/depot_tools/third_party/boto/services/result.py +0 -136
- data/vendor/depot_tools/third_party/boto/services/service.py +0 -161
- data/vendor/depot_tools/third_party/boto/services/servicedef.py +0 -91
- data/vendor/depot_tools/third_party/boto/services/sonofmmm.cfg +0 -43
- data/vendor/depot_tools/third_party/boto/services/sonofmmm.py +0 -81
- data/vendor/depot_tools/third_party/boto/services/submit.py +0 -88
- data/vendor/depot_tools/third_party/boto/ses/__init__.py +0 -54
- data/vendor/depot_tools/third_party/boto/ses/connection.py +0 -521
- data/vendor/depot_tools/third_party/boto/ses/exceptions.py +0 -77
- data/vendor/depot_tools/third_party/boto/storage_uri.py +0 -835
- data/vendor/depot_tools/third_party/boto/sts/__init__.py +0 -55
- data/vendor/depot_tools/third_party/boto/sts/connection.py +0 -207
- data/vendor/depot_tools/third_party/boto/sts/credentials.py +0 -215
- data/vendor/depot_tools/third_party/boto/utils.py +0 -927
- data/vendor/depot_tools/third_party/colorama/README.txt +0 -304
- data/vendor/depot_tools/third_party/fancy_urllib/README +0 -22
- data/vendor/depot_tools/third_party/fancy_urllib/__init__.py +0 -460
- data/vendor/depot_tools/third_party/logilab/README.chromium +0 -6
- data/vendor/depot_tools/third_party/logilab/__init__.py +0 -0
- data/vendor/depot_tools/third_party/logilab/astroid/LICENSE.txt +0 -340
- data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +0 -11
- data/vendor/depot_tools/third_party/logilab/astroid/__init__.py +0 -136
- data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +0 -42
- data/vendor/depot_tools/third_party/logilab/astroid/arguments.py +0 -233
- data/vendor/depot_tools/third_party/logilab/astroid/as_string.py +0 -548
- data/vendor/depot_tools/third_party/logilab/astroid/astpeephole.py +0 -86
- data/vendor/depot_tools/third_party/logilab/astroid/bases.py +0 -636
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_builtin_inference.py +0 -336
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_dateutil.py +0 -15
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_gi.py +0 -195
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_mechanize.py +0 -18
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_nose.py +0 -82
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_numpy.py +0 -62
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_pytest.py +0 -76
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_qt.py +0 -44
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_six.py +0 -288
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_ssl.py +0 -65
- data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_stdlib.py +0 -473
- data/vendor/depot_tools/third_party/logilab/astroid/builder.py +0 -263
- data/vendor/depot_tools/third_party/logilab/astroid/context.py +0 -81
- data/vendor/depot_tools/third_party/logilab/astroid/decorators.py +0 -75
- data/vendor/depot_tools/third_party/logilab/astroid/exceptions.py +0 -71
- data/vendor/depot_tools/third_party/logilab/astroid/inference.py +0 -359
- data/vendor/depot_tools/third_party/logilab/astroid/manager.py +0 -267
- data/vendor/depot_tools/third_party/logilab/astroid/mixins.py +0 -147
- data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +0 -741
- data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +0 -1053
- data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +0 -87
- data/vendor/depot_tools/third_party/logilab/astroid/objects.py +0 -186
- data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +0 -470
- data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +0 -390
- data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +0 -989
- data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +0 -1716
- data/vendor/depot_tools/third_party/logilab/astroid/test_utils.py +0 -201
- data/vendor/depot_tools/third_party/logilab/astroid/transforms.py +0 -96
- data/vendor/depot_tools/third_party/logilab/astroid/util.py +0 -89
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/LICENSE +0 -19
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/README.chromium +0 -11
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/__init__.py +0 -20
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/cext.c +0 -1421
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/compat.py +0 -9
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/simple.py +0 -246
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/slots.py +0 -414
- data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/utils.py +0 -13
- data/vendor/depot_tools/third_party/logilab/wrapt/LICENSE +0 -24
- data/vendor/depot_tools/third_party/logilab/wrapt/README.chromium +0 -11
- data/vendor/depot_tools/third_party/logilab/wrapt/__init__.py +0 -19
- data/vendor/depot_tools/third_party/logilab/wrapt/_wrappers.c +0 -2729
- data/vendor/depot_tools/third_party/logilab/wrapt/arguments.py +0 -96
- data/vendor/depot_tools/third_party/logilab/wrapt/decorators.py +0 -512
- data/vendor/depot_tools/third_party/logilab/wrapt/importer.py +0 -228
- data/vendor/depot_tools/third_party/logilab/wrapt/wrappers.py +0 -901
- data/vendor/depot_tools/third_party/mock/LICENSE.txt +0 -26
- data/vendor/depot_tools/third_party/mock/README.chromium +0 -24
- data/vendor/depot_tools/third_party/mock/__init__.py +0 -2366
- data/vendor/depot_tools/third_party/oauth2client/LICENSE +0 -202
- data/vendor/depot_tools/third_party/oauth2client/MODIFICATIONS.diff +0 -66
- data/vendor/depot_tools/third_party/oauth2client/README.chromium +0 -15
- data/vendor/depot_tools/third_party/oauth2client/__init__.py +0 -5
- data/vendor/depot_tools/third_party/oauth2client/anyjson.py +0 -32
- data/vendor/depot_tools/third_party/oauth2client/appengine.py +0 -963
- data/vendor/depot_tools/third_party/oauth2client/client.py +0 -1363
- data/vendor/depot_tools/third_party/oauth2client/clientsecrets.py +0 -153
- data/vendor/depot_tools/third_party/oauth2client/crypt.py +0 -377
- data/vendor/depot_tools/third_party/oauth2client/django_orm.py +0 -134
- data/vendor/depot_tools/third_party/oauth2client/file.py +0 -124
- data/vendor/depot_tools/third_party/oauth2client/gce.py +0 -90
- data/vendor/depot_tools/third_party/oauth2client/keyring_storage.py +0 -109
- data/vendor/depot_tools/third_party/oauth2client/locked_file.py +0 -373
- data/vendor/depot_tools/third_party/oauth2client/multistore_file.py +0 -465
- data/vendor/depot_tools/third_party/oauth2client/old_run.py +0 -160
- data/vendor/depot_tools/third_party/oauth2client/tools.py +0 -243
- data/vendor/depot_tools/third_party/oauth2client/util.py +0 -196
- data/vendor/depot_tools/third_party/oauth2client/xsrfutil.py +0 -113
- data/vendor/depot_tools/third_party/protobuf26/README.chromium +0 -23
- data/vendor/depot_tools/third_party/protobuf26/__init__.py +0 -0
- data/vendor/depot_tools/third_party/protobuf26/compiler/__init__.py +0 -0
- data/vendor/depot_tools/third_party/protobuf26/compiler/plugin_pb2.py +0 -184
- data/vendor/depot_tools/third_party/protobuf26/descriptor.py +0 -849
- data/vendor/depot_tools/third_party/protobuf26/descriptor_database.py +0 -137
- data/vendor/depot_tools/third_party/protobuf26/descriptor_pb2.py +0 -1522
- data/vendor/depot_tools/third_party/protobuf26/descriptor_pool.py +0 -643
- data/vendor/depot_tools/third_party/protobuf26/internal/__init__.py +0 -0
- data/vendor/depot_tools/third_party/protobuf26/internal/api_implementation.py +0 -89
- data/vendor/depot_tools/third_party/protobuf26/internal/containers.py +0 -269
- data/vendor/depot_tools/third_party/protobuf26/internal/cpp_message.py +0 -663
- data/vendor/depot_tools/third_party/protobuf26/internal/decoder.py +0 -831
- data/vendor/depot_tools/third_party/protobuf26/internal/encoder.py +0 -788
- data/vendor/depot_tools/third_party/protobuf26/internal/enum_type_wrapper.py +0 -89
- data/vendor/depot_tools/third_party/protobuf26/internal/message_listener.py +0 -78
- data/vendor/depot_tools/third_party/protobuf26/internal/python_message.py +0 -1247
- data/vendor/depot_tools/third_party/protobuf26/internal/type_checkers.py +0 -328
- data/vendor/depot_tools/third_party/protobuf26/internal/wire_format.py +0 -268
- data/vendor/depot_tools/third_party/protobuf26/message.py +0 -284
- data/vendor/depot_tools/third_party/protobuf26/message_factory.py +0 -155
- data/vendor/depot_tools/third_party/protobuf26/reflection.py +0 -205
- data/vendor/depot_tools/third_party/protobuf26/service.py +0 -226
- data/vendor/depot_tools/third_party/protobuf26/service_reflection.py +0 -284
- data/vendor/depot_tools/third_party/protobuf26/symbol_database.py +0 -185
- data/vendor/depot_tools/third_party/protobuf26/text_encoding.py +0 -110
- data/vendor/depot_tools/third_party/protobuf26/text_format.py +0 -873
- data/vendor/depot_tools/third_party/pylint.py +0 -37
- data/vendor/depot_tools/third_party/pylint/LICENSE.txt +0 -340
- data/vendor/depot_tools/third_party/pylint/README.chromium +0 -30
- data/vendor/depot_tools/third_party/pylint/__init__.py +0 -46
- data/vendor/depot_tools/third_party/pylint/__main__.py +0 -3
- data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +0 -80
- data/vendor/depot_tools/third_party/pylint/checkers/__init__.py +0 -123
- data/vendor/depot_tools/third_party/pylint/checkers/async.py +0 -82
- data/vendor/depot_tools/third_party/pylint/checkers/base.py +0 -2010
- data/vendor/depot_tools/third_party/pylint/checkers/classes.py +0 -1120
- data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +0 -348
- data/vendor/depot_tools/third_party/pylint/checkers/exceptions.py +0 -369
- data/vendor/depot_tools/third_party/pylint/checkers/format.py +0 -993
- data/vendor/depot_tools/third_party/pylint/checkers/imports.py +0 -654
- data/vendor/depot_tools/third_party/pylint/checkers/logging.py +0 -258
- data/vendor/depot_tools/third_party/pylint/checkers/misc.py +0 -105
- data/vendor/depot_tools/third_party/pylint/checkers/newstyle.py +0 -169
- data/vendor/depot_tools/third_party/pylint/checkers/python3.py +0 -591
- data/vendor/depot_tools/third_party/pylint/checkers/raw_metrics.py +0 -129
- data/vendor/depot_tools/third_party/pylint/checkers/similar.py +0 -371
- data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +0 -264
- data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +0 -280
- data/vendor/depot_tools/third_party/pylint/checkers/strings.py +0 -618
- data/vendor/depot_tools/third_party/pylint/checkers/typecheck.py +0 -974
- data/vendor/depot_tools/third_party/pylint/checkers/utils.py +0 -741
- data/vendor/depot_tools/third_party/pylint/checkers/variables.py +0 -1191
- data/vendor/depot_tools/third_party/pylint/config.py +0 -820
- data/vendor/depot_tools/third_party/pylint/epylint.py +0 -181
- data/vendor/depot_tools/third_party/pylint/extensions/__init__.py +0 -0
- data/vendor/depot_tools/third_party/pylint/extensions/check_docs.py +0 -311
- data/vendor/depot_tools/third_party/pylint/extensions/check_elif.py +0 -62
- data/vendor/depot_tools/third_party/pylint/graph.py +0 -179
- data/vendor/depot_tools/third_party/pylint/gui.py +0 -531
- data/vendor/depot_tools/third_party/pylint/interfaces.py +0 -102
- data/vendor/depot_tools/third_party/pylint/lint.py +0 -1381
- data/vendor/depot_tools/third_party/pylint/pyreverse/__init__.py +0 -5
- data/vendor/depot_tools/third_party/pylint/pyreverse/diadefslib.py +0 -230
- data/vendor/depot_tools/third_party/pylint/pyreverse/diagrams.py +0 -258
- data/vendor/depot_tools/third_party/pylint/pyreverse/inspector.py +0 -372
- data/vendor/depot_tools/third_party/pylint/pyreverse/main.py +0 -147
- data/vendor/depot_tools/third_party/pylint/pyreverse/utils.py +0 -210
- data/vendor/depot_tools/third_party/pylint/pyreverse/vcgutils.py +0 -198
- data/vendor/depot_tools/third_party/pylint/pyreverse/writer.py +0 -198
- data/vendor/depot_tools/third_party/pylint/reporters/__init__.py +0 -149
- data/vendor/depot_tools/third_party/pylint/reporters/guireporter.py +0 -27
- data/vendor/depot_tools/third_party/pylint/reporters/html.py +0 -108
- data/vendor/depot_tools/third_party/pylint/reporters/json.py +0 -64
- data/vendor/depot_tools/third_party/pylint/reporters/text.py +0 -237
- data/vendor/depot_tools/third_party/pylint/reporters/ureports/__init__.py +0 -106
- data/vendor/depot_tools/third_party/pylint/reporters/ureports/html_writer.py +0 -93
- data/vendor/depot_tools/third_party/pylint/reporters/ureports/nodes.py +0 -181
- data/vendor/depot_tools/third_party/pylint/reporters/ureports/text_writer.py +0 -99
- data/vendor/depot_tools/third_party/pylint/testutils.py +0 -414
- data/vendor/depot_tools/third_party/pylint/utils.py +0 -1148
- data/vendor/depot_tools/third_party/pymox/COPYING +0 -202
- data/vendor/depot_tools/third_party/pymox/MANIFEST.in +0 -5
- data/vendor/depot_tools/third_party/pymox/README +0 -56
- data/vendor/depot_tools/third_party/pymox/__init__.py +0 -0
- data/vendor/depot_tools/third_party/pymox/mox.py +0 -1643
- data/vendor/depot_tools/third_party/pymox/mox_test.py +0 -1708
- data/vendor/depot_tools/third_party/pymox/mox_test_helper.py +0 -76
- data/vendor/depot_tools/third_party/pymox/setup.py +0 -14
- data/vendor/depot_tools/third_party/pymox/stubout.py +0 -142
- data/vendor/depot_tools/third_party/pymox/stubout_test.py +0 -47
- data/vendor/depot_tools/third_party/pymox/stubout_testee.py +0 -2
- data/vendor/depot_tools/third_party/simplejson/LICENSE.txt +0 -19
- data/vendor/depot_tools/third_party/simplejson/PKG-INFO +0 -29
- data/vendor/depot_tools/third_party/simplejson/__init__.py +0 -437
- data/vendor/depot_tools/third_party/simplejson/decoder.py +0 -421
- data/vendor/depot_tools/third_party/simplejson/encoder.py +0 -501
- data/vendor/depot_tools/third_party/simplejson/ordered_dict.py +0 -119
- data/vendor/depot_tools/third_party/simplejson/scanner.py +0 -77
- data/vendor/depot_tools/third_party/simplejson/tool.py +0 -39
- 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
|
|
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()
|
|
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,
|
|
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
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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 =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
|
171
|
-
|
|
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' % (
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
|
287
|
-
|
|
288
|
-
|
|
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
|
-
|
|
322
|
+
sys.stdout.write(' ')
|
|
291
323
|
# Write separately in case it's unicode.
|
|
292
|
-
|
|
324
|
+
sys.stdout.write(str(item))
|
|
293
325
|
if index < len(self._items) - 1:
|
|
294
|
-
|
|
295
|
-
|
|
326
|
+
sys.stdout.write(' \\')
|
|
327
|
+
sys.stdout.write('\n')
|
|
296
328
|
if self._long_text:
|
|
297
|
-
|
|
329
|
+
sys.stdout.write('\n***************\n')
|
|
298
330
|
# Write separately in case it's unicode.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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'].
|
|
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
|
|
454
|
-
# Note that ALL CAPS files are
|
|
455
|
-
|
|
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
|
|
458
|
-
r
|
|
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
|
|
501
|
+
r'.+\.js$', r'.+\.py$', r'.+\.sh$', r'.+\.rb$', r'.+\.pl$', r'.+\.pm$',
|
|
461
502
|
# Other
|
|
462
|
-
r
|
|
463
|
-
r
|
|
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
|
-
|
|
469
|
-
r
|
|
470
|
-
r
|
|
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
|
|
514
|
+
r'.*\bthird_party[\\\/](?!(WebKit|blink)[\\\/]).*',
|
|
474
515
|
# Output directories (just in case)
|
|
475
|
-
r
|
|
476
|
-
r
|
|
477
|
-
r
|
|
478
|
-
r
|
|
516
|
+
r'.*\bDebug[\\\/].*',
|
|
517
|
+
r'.*\bRelease[\\\/].*',
|
|
518
|
+
r'.*\bxcodebuild[\\\/].*',
|
|
519
|
+
r'.*\bout[\\\/].*',
|
|
479
520
|
# All caps files like README and LICENCE.
|
|
480
|
-
r
|
|
521
|
+
r'.*\b[A-Z0-9_]{2,}$',
|
|
481
522
|
# SCM (can happen in dual SCM configuration). (Slightly over aggressive)
|
|
482
|
-
r
|
|
483
|
-
r
|
|
523
|
+
r'(|.*[\\\/])\.git[\\\/].*',
|
|
524
|
+
r'(|.*[\\\/])\.svn[\\\/].*',
|
|
484
525
|
# There is no point in processing a patch file.
|
|
485
|
-
r
|
|
486
|
-
r
|
|
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
|
-
|
|
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 '
|
|
544
|
-
#
|
|
545
|
-
#
|
|
546
|
-
|
|
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=
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
622
|
-
|
|
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(
|
|
626
|
-
|
|
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,
|
|
633
|
-
|
|
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
|
|
636
|
-
and InputApi.
|
|
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,
|
|
650
|
-
not Find(affected_file,
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
1041
|
-
|
|
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
|
|
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(
|
|
1056
|
-
# determined by self-CR+1s.
|
|
1057
|
-
footers =
|
|
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(
|
|
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(
|
|
1095
|
-
|
|
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(
|
|
1099
|
-
|
|
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
|
|
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
|
|
1220
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
1251
|
-
|
|
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(
|
|
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.
|
|
1269
|
-
masters2.
|
|
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.
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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
|
-
|
|
1329
|
-
|
|
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
|
-
|
|
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(),
|
|
1465
|
+
change.LocalPaths(), change.RepositoryRoot())
|
|
1343
1466
|
if not presubmit_files and verbose:
|
|
1344
|
-
|
|
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
|
-
|
|
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,
|
|
1360
|
-
|
|
1361
|
-
if results:
|
|
1362
|
-
|
|
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.
|
|
1365
|
-
|
|
1492
|
+
if result.fatal:
|
|
1493
|
+
exit_code = 1
|
|
1494
|
+
result.handle()
|
|
1495
|
+
sys.stdout.write('\n')
|
|
1366
1496
|
|
|
1367
|
-
return
|
|
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
|
|
1416
|
-
|
|
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
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1621
|
+
sys.stdout.write('Running presubmit commit checks ...\n')
|
|
1500
1622
|
else:
|
|
1501
|
-
|
|
1502
|
-
start_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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
warnings = []
|
|
1648
|
+
messages = {}
|
|
1649
|
+
should_prompt = False
|
|
1650
|
+
presubmits_failed = False
|
|
1530
1651
|
for result in results:
|
|
1531
1652
|
if result.fatal:
|
|
1532
|
-
|
|
1653
|
+
presubmits_failed = True
|
|
1654
|
+
messages.setdefault('ERRORS', []).append(result)
|
|
1533
1655
|
elif result.should_prompt:
|
|
1534
|
-
|
|
1656
|
+
should_prompt = True
|
|
1657
|
+
messages.setdefault('Warnings', []).append(result)
|
|
1535
1658
|
else:
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
for name, items in (
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
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
|
-
|
|
1670
|
+
sys.stdout.write(
|
|
1671
|
+
'Presubmit checks took %.1fs to calculate.\n\n' % total_time)
|
|
1551
1672
|
|
|
1552
|
-
if
|
|
1553
|
-
|
|
1554
|
-
elif
|
|
1555
|
-
|
|
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
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1710
|
+
|
|
1711
|
+
return 1 if presubmits_failed else 0
|
|
1570
1712
|
finally:
|
|
1571
1713
|
os.environ = old_environ
|
|
1572
1714
|
|
|
1573
1715
|
|
|
1574
|
-
def
|
|
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
|
|
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
|
|
1736
|
+
files.extend([('M', f) for f in _scan_sub_dirs(arg, recursive)])
|
|
1595
1737
|
return files
|
|
1596
1738
|
|
|
1597
1739
|
|
|
1598
|
-
def
|
|
1599
|
-
"""
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
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
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
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
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
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.
|
|
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 =
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
parser.
|
|
1643
|
-
|
|
1644
|
-
parser.
|
|
1645
|
-
|
|
1646
|
-
parser.
|
|
1647
|
-
parser.
|
|
1648
|
-
parser.
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
parser.
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
parser.
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
parser.
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
parser.
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
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
|
-
|
|
1882
|
+
log_level = logging.DEBUG
|
|
1676
1883
|
elif options.verbose:
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
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
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
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
|
-
|
|
1699
|
-
|
|
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
|
-
|
|
1717
|
-
except PresubmitFailure
|
|
1718
|
-
print
|
|
1719
|
-
print
|
|
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
|
|