libv8 8.4.255.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.gitmodules +3 -0
- data/.rspec +3 -0
- data/.travis.yml +45 -0
- data/CHANGELOG.md +111 -0
- data/Gemfile +4 -0
- data/README.md +152 -0
- data/Rakefile +125 -0
- data/appveyor.yml.disabled +36 -0
- data/ext/libv8/arch.rb +20 -0
- data/ext/libv8/builder.rb +106 -0
- data/ext/libv8/extconf.rb +7 -0
- data/ext/libv8/location.rb +89 -0
- data/ext/libv8/paths.rb +28 -0
- data/lib/libv8.rb +9 -0
- data/lib/libv8/version.rb +3 -0
- data/libv8.gemspec +30 -0
- data/scaleway.png +0 -0
- data/spec/location_spec.rb +69 -0
- data/spec/spec_helper.rb +4 -0
- data/thefrontside.png +0 -0
- data/vendor/depot_tools/.cipd_impl.ps1 +129 -0
- data/vendor/depot_tools/.gitattributes +55 -0
- data/vendor/depot_tools/.gitignore +92 -0
- data/vendor/depot_tools/.style.yapf +4 -0
- data/vendor/depot_tools/.vpython +55 -0
- data/vendor/depot_tools/.vpython3 +23 -0
- data/vendor/depot_tools/CROS_OWNERS +7 -0
- data/vendor/depot_tools/GOMA_OWNERS +9 -0
- data/vendor/depot_tools/LICENSE +27 -0
- data/vendor/depot_tools/LUCI_OWNERS +5 -0
- data/vendor/depot_tools/OWNERS +39 -0
- data/vendor/depot_tools/PRESUBMIT.py +150 -0
- data/vendor/depot_tools/README.gclient.md +67 -0
- data/vendor/depot_tools/README.git-cl.md +99 -0
- data/vendor/depot_tools/README.md +78 -0
- data/vendor/depot_tools/WATCHLISTS +26 -0
- data/vendor/depot_tools/auth.py +163 -0
- data/vendor/depot_tools/autoninja +36 -0
- data/vendor/depot_tools/autoninja.bat +33 -0
- data/vendor/depot_tools/autoninja.py +148 -0
- data/vendor/depot_tools/bb +12 -0
- data/vendor/depot_tools/bb.bat +7 -0
- data/vendor/depot_tools/bootstrap/README.md +155 -0
- data/vendor/depot_tools/bootstrap/bootstrap.py +356 -0
- data/vendor/depot_tools/bootstrap/git-bash.template.sh +12 -0
- data/vendor/depot_tools/bootstrap/git.template.bat +5 -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/profile.d.python.sh +20 -0
- data/vendor/depot_tools/bootstrap/python27.bat +46 -0
- data/vendor/depot_tools/bootstrap/python3.bat +46 -0
- data/vendor/depot_tools/bootstrap/win_tools.bat +79 -0
- data/vendor/depot_tools/bootstrap_python3 +35 -0
- data/vendor/depot_tools/breakpad.py +12 -0
- data/vendor/depot_tools/cbuildbot +1 -0
- data/vendor/depot_tools/chrome_set_ver +1 -0
- data/vendor/depot_tools/cipd +247 -0
- data/vendor/depot_tools/cipd.bat +67 -0
- data/vendor/depot_tools/cipd_bin_setup.bat +6 -0
- data/vendor/depot_tools/cipd_bin_setup.sh +22 -0
- data/vendor/depot_tools/cipd_client_version +1 -0
- data/vendor/depot_tools/cipd_client_version.digests +22 -0
- data/vendor/depot_tools/cipd_manifest.txt +63 -0
- data/vendor/depot_tools/cipd_manifest.versions +438 -0
- data/vendor/depot_tools/cit +8 -0
- data/vendor/depot_tools/cit.bat +12 -0
- data/vendor/depot_tools/cit.py +167 -0
- data/vendor/depot_tools/clang-format +8 -0
- data/vendor/depot_tools/clang-format.bat +12 -0
- data/vendor/depot_tools/clang_format.py +79 -0
- data/vendor/depot_tools/clang_format_merge_driver +8 -0
- data/vendor/depot_tools/clang_format_merge_driver.bat +12 -0
- data/vendor/depot_tools/clang_format_merge_driver.py +69 -0
- data/vendor/depot_tools/codereview.settings +6 -0
- data/vendor/depot_tools/compile_single_file +8 -0
- data/vendor/depot_tools/compile_single_file.bat +11 -0
- data/vendor/depot_tools/compile_single_file.py +79 -0
- data/vendor/depot_tools/cpplint.bat +11 -0
- data/vendor/depot_tools/cpplint.py +6097 -0
- data/vendor/depot_tools/cpplint_chromium.py +50 -0
- data/vendor/depot_tools/cros +87 -0
- data/vendor/depot_tools/cros_sdk +1 -0
- data/vendor/depot_tools/crosjobs +13 -0
- data/vendor/depot_tools/detect_host_arch.py +55 -0
- data/vendor/depot_tools/dirmd +12 -0
- data/vendor/depot_tools/dirmd.bat +7 -0
- data/vendor/depot_tools/download_from_google_storage +8 -0
- data/vendor/depot_tools/download_from_google_storage.bat +12 -0
- data/vendor/depot_tools/download_from_google_storage.py +634 -0
- data/vendor/depot_tools/ensure_bootstrap +53 -0
- data/vendor/depot_tools/fetch +21 -0
- data/vendor/depot_tools/fetch.bat +28 -0
- data/vendor/depot_tools/fetch.py +319 -0
- data/vendor/depot_tools/fetch_configs/android.py +34 -0
- data/vendor/depot_tools/fetch_configs/android_internal.py +34 -0
- data/vendor/depot_tools/fetch_configs/breakpad.py +44 -0
- data/vendor/depot_tools/fetch_configs/chromium.py +66 -0
- data/vendor/depot_tools/fetch_configs/config_util.py +52 -0
- data/vendor/depot_tools/fetch_configs/crashpad.py +41 -0
- data/vendor/depot_tools/fetch_configs/dart.py +45 -0
- data/vendor/depot_tools/fetch_configs/depot_tools.py +44 -0
- data/vendor/depot_tools/fetch_configs/devtools-frontend.py +44 -0
- data/vendor/depot_tools/fetch_configs/goma_client.py +41 -0
- data/vendor/depot_tools/fetch_configs/gyp.py +41 -0
- data/vendor/depot_tools/fetch_configs/infra.py +40 -0
- data/vendor/depot_tools/fetch_configs/infra_internal.py +45 -0
- data/vendor/depot_tools/fetch_configs/inspector_protocol.py +40 -0
- data/vendor/depot_tools/fetch_configs/ios.py +34 -0
- data/vendor/depot_tools/fetch_configs/ios_internal.py +39 -0
- data/vendor/depot_tools/fetch_configs/nacl.py +48 -0
- data/vendor/depot_tools/fetch_configs/naclports.py +47 -0
- data/vendor/depot_tools/fetch_configs/node-ci.py +41 -0
- data/vendor/depot_tools/fetch_configs/pdfium.py +40 -0
- data/vendor/depot_tools/fetch_configs/skia.py +41 -0
- data/vendor/depot_tools/fetch_configs/skia_buildbot.py +41 -0
- data/vendor/depot_tools/fetch_configs/syzygy.py +41 -0
- data/vendor/depot_tools/fetch_configs/v8.py +44 -0
- data/vendor/depot_tools/fetch_configs/webrtc.py +52 -0
- data/vendor/depot_tools/fetch_configs/webrtc_android.py +34 -0
- data/vendor/depot_tools/fetch_configs/webrtc_ios.py +34 -0
- data/vendor/depot_tools/fix_encoding.py +385 -0
- data/vendor/depot_tools/gclient +38 -0
- data/vendor/depot_tools/gclient-new-workdir.py +124 -0
- data/vendor/depot_tools/gclient.bat +32 -0
- data/vendor/depot_tools/gclient.py +3198 -0
- data/vendor/depot_tools/gclient_completion.sh +76 -0
- data/vendor/depot_tools/gclient_eval.py +891 -0
- data/vendor/depot_tools/gclient_paths.py +152 -0
- data/vendor/depot_tools/gclient_scm.py +1615 -0
- data/vendor/depot_tools/gclient_utils.py +1280 -0
- data/vendor/depot_tools/gerrit_client.py +151 -0
- data/vendor/depot_tools/gerrit_util.py +996 -0
- data/vendor/depot_tools/git-cache +6 -0
- data/vendor/depot_tools/git-cl +6 -0
- data/vendor/depot_tools/git-crrev-parse +53 -0
- data/vendor/depot_tools/git-drover +6 -0
- data/vendor/depot_tools/git-find-releases +6 -0
- data/vendor/depot_tools/git-footers +6 -0
- data/vendor/depot_tools/git-freeze +8 -0
- data/vendor/depot_tools/git-gs +9 -0
- data/vendor/depot_tools/git-hyper-blame +6 -0
- data/vendor/depot_tools/git-map +6 -0
- data/vendor/depot_tools/git-map-branches +6 -0
- data/vendor/depot_tools/git-mark-merge-base +6 -0
- data/vendor/depot_tools/git-nav-downstream +6 -0
- data/vendor/depot_tools/git-nav-upstream +6 -0
- data/vendor/depot_tools/git-new-branch +6 -0
- data/vendor/depot_tools/git-number +6 -0
- data/vendor/depot_tools/git-rebase-update +6 -0
- data/vendor/depot_tools/git-rename-branch +6 -0
- data/vendor/depot_tools/git-reparent-branch +6 -0
- data/vendor/depot_tools/git-retry +8 -0
- data/vendor/depot_tools/git-runhooks +23 -0
- data/vendor/depot_tools/git-squash-branch +6 -0
- data/vendor/depot_tools/git-templates/description +3 -0
- data/vendor/depot_tools/git-templates/hooks/applypatch-msg +4 -0
- data/vendor/depot_tools/git-templates/hooks/post-applypatch +4 -0
- data/vendor/depot_tools/git-templates/hooks/post-checkout +4 -0
- data/vendor/depot_tools/git-templates/hooks/post-commit +4 -0
- data/vendor/depot_tools/git-templates/hooks/post-merge +4 -0
- data/vendor/depot_tools/git-templates/hooks/post-update +4 -0
- data/vendor/depot_tools/git-templates/hooks/pre-applypatch +4 -0
- data/vendor/depot_tools/git-templates/hooks/pre-auto-gc +4 -0
- data/vendor/depot_tools/git-templates/hooks/pre-commit +4 -0
- data/vendor/depot_tools/git-templates/hooks/pre-rebase +4 -0
- data/vendor/depot_tools/git-templates/hooks/prepare-commit-msg +4 -0
- data/vendor/depot_tools/git-templates/info/exclude +6 -0
- data/vendor/depot_tools/git-thaw +13 -0
- data/vendor/depot_tools/git-upstream-diff +9 -0
- data/vendor/depot_tools/git_cache.py +786 -0
- data/vendor/depot_tools/git_cl.py +5158 -0
- data/vendor/depot_tools/git_cl_completion.sh +48 -0
- data/vendor/depot_tools/git_common.py +1101 -0
- data/vendor/depot_tools/git_dates.py +62 -0
- data/vendor/depot_tools/git_drover.py +469 -0
- data/vendor/depot_tools/git_find_releases.py +67 -0
- data/vendor/depot_tools/git_footers.py +261 -0
- data/vendor/depot_tools/git_freezer.py +40 -0
- data/vendor/depot_tools/git_hyper_blame.py +391 -0
- data/vendor/depot_tools/git_map.py +166 -0
- data/vendor/depot_tools/git_map_branches.py +354 -0
- data/vendor/depot_tools/git_mark_merge_base.py +73 -0
- data/vendor/depot_tools/git_nav_downstream.py +69 -0
- data/vendor/depot_tools/git_new_branch.py +82 -0
- data/vendor/depot_tools/git_number.py +301 -0
- data/vendor/depot_tools/git_rebase_update.py +351 -0
- data/vendor/depot_tools/git_rename_branch.py +55 -0
- data/vendor/depot_tools/git_reparent_branch.py +101 -0
- data/vendor/depot_tools/git_retry.py +181 -0
- data/vendor/depot_tools/git_squash_branch.py +28 -0
- data/vendor/depot_tools/git_upstream_diff.py +64 -0
- data/vendor/depot_tools/gn +8 -0
- data/vendor/depot_tools/gn.bat +12 -0
- data/vendor/depot_tools/gn.py +78 -0
- 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 +190 -0
- data/vendor/depot_tools/gsutil.py.bat +23 -0
- data/vendor/depot_tools/gsutil.vpython +120 -0
- data/vendor/depot_tools/infra/README.md +1 -0
- data/vendor/depot_tools/infra/config/OWNERS +7 -0
- data/vendor/depot_tools/infra/config/README.md +1 -0
- data/vendor/depot_tools/infra/config/recipes.cfg +26 -0
- data/vendor/depot_tools/led +12 -0
- data/vendor/depot_tools/led.bat +7 -0
- data/vendor/depot_tools/lockfile.py +116 -0
- data/vendor/depot_tools/luci-auth +13 -0
- data/vendor/depot_tools/luci-auth.bat +8 -0
- data/vendor/depot_tools/lucicfg +12 -0
- data/vendor/depot_tools/lucicfg.bat +7 -0
- data/vendor/depot_tools/mac_toolchain +12 -0
- data/vendor/depot_tools/man/html/depot_tools.html +934 -0
- data/vendor/depot_tools/man/html/depot_tools_tutorial.html +1593 -0
- data/vendor/depot_tools/man/html/git-cl.html +1033 -0
- data/vendor/depot_tools/man/html/git-drover.html +1048 -0
- data/vendor/depot_tools/man/html/git-footers.html +878 -0
- data/vendor/depot_tools/man/html/git-freeze.html +859 -0
- data/vendor/depot_tools/man/html/git-hyper-blame.html +878 -0
- data/vendor/depot_tools/man/html/git-map-branches.html +904 -0
- data/vendor/depot_tools/man/html/git-map.html +887 -0
- data/vendor/depot_tools/man/html/git-mark-merge-base.html +826 -0
- data/vendor/depot_tools/man/html/git-nav-downstream.html +844 -0
- data/vendor/depot_tools/man/html/git-nav-upstream.html +853 -0
- data/vendor/depot_tools/man/html/git-new-branch.html +932 -0
- data/vendor/depot_tools/man/html/git-rebase-update.html +961 -0
- data/vendor/depot_tools/man/html/git-rename-branch.html +794 -0
- data/vendor/depot_tools/man/html/git-reparent-branch.html +847 -0
- data/vendor/depot_tools/man/html/git-retry.html +858 -0
- data/vendor/depot_tools/man/html/git-squash-branch.html +881 -0
- data/vendor/depot_tools/man/html/git-thaw.html +794 -0
- data/vendor/depot_tools/man/html/git-upstream-diff.html +923 -0
- data/vendor/depot_tools/man/man1/git-cl.1 +198 -0
- data/vendor/depot_tools/man/man1/git-drover.1 +330 -0
- data/vendor/depot_tools/man/man1/git-footers.1 +144 -0
- data/vendor/depot_tools/man/man1/git-freeze.1 +113 -0
- data/vendor/depot_tools/man/man1/git-hyper-blame.1 +128 -0
- data/vendor/depot_tools/man/man1/git-map-branches.1 +210 -0
- data/vendor/depot_tools/man/man1/git-map.1 +179 -0
- data/vendor/depot_tools/man/man1/git-mark-merge-base.1 +69 -0
- data/vendor/depot_tools/man/man1/git-nav-downstream.1 +112 -0
- data/vendor/depot_tools/man/man1/git-nav-upstream.1 +122 -0
- data/vendor/depot_tools/man/man1/git-new-branch.1 +176 -0
- data/vendor/depot_tools/man/man1/git-rebase-update.1 +177 -0
- data/vendor/depot_tools/man/man1/git-rename-branch.1 +53 -0
- data/vendor/depot_tools/man/man1/git-reparent-branch.1 +93 -0
- data/vendor/depot_tools/man/man1/git-retry.1 +108 -0
- data/vendor/depot_tools/man/man1/git-squash-branch.1 +129 -0
- data/vendor/depot_tools/man/man1/git-thaw.1 +54 -0
- data/vendor/depot_tools/man/man1/git-upstream-diff.1 +153 -0
- data/vendor/depot_tools/man/man7/depot_tools.7 +139 -0
- data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +1061 -0
- data/vendor/depot_tools/man/push_to_gs.sh +4 -0
- data/vendor/depot_tools/man/src/.gitignore +5 -0
- data/vendor/depot_tools/man/src/_aliases.txt +5 -0
- data/vendor/depot_tools/man/src/_footer.txt +8 -0
- data/vendor/depot_tools/man/src/_git-cl_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-drover_desc.helper.txt +2 -0
- data/vendor/depot_tools/man/src/_git-footers_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-freeze_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-hyper-blame_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-map-branches_desc.helper.txt +4 -0
- data/vendor/depot_tools/man/src/_git-map_desc.helper.txt +3 -0
- data/vendor/depot_tools/man/src/_git-mark-merge-base_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-nav-downstream_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-nav-upstream_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-new-branch_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-rebase-update_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-rename-branch_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-reparent-branch_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-retry_desc.helper.txt +2 -0
- data/vendor/depot_tools/man/src/_git-squash-branch_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_git-thaw_desc.helper.txt +2 -0
- data/vendor/depot_tools/man/src/_git-upstream-diff_desc.helper.txt +1 -0
- data/vendor/depot_tools/man/src/_helper_prefix.txt +1 -0
- data/vendor/depot_tools/man/src/asciidoc-override.css +7 -0
- data/vendor/depot_tools/man/src/common_demo_functions.sh +84 -0
- data/vendor/depot_tools/man/src/demo_repo.sh +43 -0
- data/vendor/depot_tools/man/src/depot_tools.txt +28 -0
- data/vendor/depot_tools/man/src/depot_tools_tutorial.demo.walkthrough.sh +155 -0
- data/vendor/depot_tools/man/src/depot_tools_tutorial.txt +432 -0
- data/vendor/depot_tools/man/src/filter_demo_output.py +141 -0
- data/vendor/depot_tools/man/src/git-cl.txt +119 -0
- data/vendor/depot_tools/man/src/git-drover.demo.1.sh +22 -0
- data/vendor/depot_tools/man/src/git-drover.demo.2.sh +23 -0
- data/vendor/depot_tools/man/src/git-drover.demo.3.sh +27 -0
- data/vendor/depot_tools/man/src/git-drover.demo.4.sh +39 -0
- data/vendor/depot_tools/man/src/git-drover.demo.common.sh +19 -0
- data/vendor/depot_tools/man/src/git-drover.txt +102 -0
- data/vendor/depot_tools/man/src/git-footers.demo.1.sh +17 -0
- data/vendor/depot_tools/man/src/git-footers.txt +71 -0
- data/vendor/depot_tools/man/src/git-freeze.demo.1.sh +23 -0
- data/vendor/depot_tools/man/src/git-freeze.txt +54 -0
- data/vendor/depot_tools/man/src/git-hyper-blame.demo.1.sh +3 -0
- data/vendor/depot_tools/man/src/git-hyper-blame.demo.2.sh +4 -0
- data/vendor/depot_tools/man/src/git-hyper-blame.demo.common.sh +57 -0
- data/vendor/depot_tools/man/src/git-hyper-blame.txt +85 -0
- data/vendor/depot_tools/man/src/git-map-branches.demo.1.sh +8 -0
- data/vendor/depot_tools/man/src/git-map-branches.txt +64 -0
- data/vendor/depot_tools/man/src/git-map.demo.1.sh +3 -0
- data/vendor/depot_tools/man/src/git-map.txt +67 -0
- data/vendor/depot_tools/man/src/git-mark-merge-base.txt +46 -0
- data/vendor/depot_tools/man/src/git-nav-downstream.demo.1.sh +12 -0
- data/vendor/depot_tools/man/src/git-nav-downstream.txt +40 -0
- data/vendor/depot_tools/man/src/git-nav-upstream.demo.1.sh +12 -0
- data/vendor/depot_tools/man/src/git-nav-upstream.txt +39 -0
- data/vendor/depot_tools/man/src/git-new-branch.demo.1.sh +17 -0
- data/vendor/depot_tools/man/src/git-new-branch.txt +82 -0
- data/vendor/depot_tools/man/src/git-rebase-update.txt +141 -0
- data/vendor/depot_tools/man/src/git-rename-branch.txt +28 -0
- data/vendor/depot_tools/man/src/git-reparent-branch.txt +61 -0
- data/vendor/depot_tools/man/src/git-retry.txt +67 -0
- data/vendor/depot_tools/man/src/git-squash-branch.demo.1.sh +12 -0
- data/vendor/depot_tools/man/src/git-squash-branch.txt +59 -0
- data/vendor/depot_tools/man/src/git-thaw.txt +29 -0
- data/vendor/depot_tools/man/src/git-upstream-diff.txt +107 -0
- data/vendor/depot_tools/man/src/make_docs.sh +260 -0
- data/vendor/depot_tools/man/src/prep_demo_repo.sh +103 -0
- data/vendor/depot_tools/metrics.README.md +101 -0
- data/vendor/depot_tools/metrics.py +297 -0
- data/vendor/depot_tools/metrics_utils.py +293 -0
- data/vendor/depot_tools/my_activity.py +971 -0
- data/vendor/depot_tools/ninja +44 -0
- data/vendor/depot_tools/ninja-linux32 +0 -0
- data/vendor/depot_tools/ninja-linux64 +0 -0
- data/vendor/depot_tools/ninja-mac +0 -0
- data/vendor/depot_tools/ninja.exe +0 -0
- data/vendor/depot_tools/ninjalog.README.md +64 -0
- data/vendor/depot_tools/ninjalog_uploader.py +233 -0
- data/vendor/depot_tools/ninjalog_uploader_wrapper.py +125 -0
- data/vendor/depot_tools/owners.py +641 -0
- data/vendor/depot_tools/owners_finder.py +385 -0
- data/vendor/depot_tools/post_build_ninja_summary.py +350 -0
- data/vendor/depot_tools/presubmit_canned_checks.py +1655 -0
- data/vendor/depot_tools/presubmit_support.py +1923 -0
- data/vendor/depot_tools/profile.xml +8 -0
- data/vendor/depot_tools/prpc +13 -0
- data/vendor/depot_tools/prpc.bat +8 -0
- data/vendor/depot_tools/pylint +9 -0
- 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/pylint.bat +12 -0
- data/vendor/depot_tools/pylint_main.py +45 -0
- data/vendor/depot_tools/pylintrc +349 -0
- data/vendor/depot_tools/python-bin/python3 +7 -0
- data/vendor/depot_tools/python_runner.sh +60 -0
- data/vendor/depot_tools/rdb +12 -0
- data/vendor/depot_tools/rdb.bat +7 -0
- data/vendor/depot_tools/recipes/OWNERS +4 -0
- data/vendor/depot_tools/recipes/README.recipes.md +1079 -0
- data/vendor/depot_tools/recipes/recipe_modules/OWNERS +1 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/OWNERS +2 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +38 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +516 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic.json +117 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_luci.json +117 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_with_branch_heads.json +118 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/clobber.json +211 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +194 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_rebase_patch_ref.json +211 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_reset.json +211 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/input_commit_with_id_without_repo.json +210 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/multiple_patch_refs.json +214 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_apply_patch_on_gclient.json +265 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_HEAD.json +65 -0
- 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 +212 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/reset_root_solution_revision.json +210 -0
- 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 +95 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +209 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +193 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle.json +265 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_branch_heads.json +261 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_feature_branch.json +261 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8_feature_branch.json +265 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_webrtc.json +265 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +265 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +265 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/unrecognized_commit_repo.json +8 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_tags.json +211 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +308 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/__init__.py +0 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +1258 -0
- data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +93 -0
- 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 +35 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/__init__.py +9 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/api.py +455 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic.json +403 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic_pkg.json +403 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-failed.json +82 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-many-instances.json +411 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/mac64.json +403 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_file.json +315 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_mode.json +313 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_verfile.json +313 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/win64.json +403 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.py +187 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk arch.json +5 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk bits.json +5 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_32.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_64.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_32.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_64.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_mips_64.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/mac_intel_64.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_32.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_64.json +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.py +59 -0
- data/vendor/depot_tools/recipes/recipe_modules/cipd/test_api.py +93 -0
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/__init__.py +9 -0
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/api.py +75 -0
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic_luci.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/win.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.py +55 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/__init__.py +13 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +428 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +462 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +238 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +240 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +238 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +95 -0
- 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 +36 -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 +92 -0
- data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/sync_failure.py +24 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/__init__.py +8 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +178 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +284 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.py +73 -0
- data/vendor/depot_tools/recipes/recipe_modules/gerrit/test_api.py +53 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/__init__.py +11 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/api.py +405 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic.json +217 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_branch.json +217 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_file_name.json +219 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_hash.json +216 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_ref.json +217 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_submodule_update_force.json +218 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_tags.json +218 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/can_fail_build.json +164 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cannot_fail_build.json +220 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cat-file_test.json +239 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_delta.json +290 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_failed.json +220 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output.json +222 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output_fails_build.json +111 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/curl_trace_file.json +218 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/git-cache-checkout.json +265 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/platform_win.json +217 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/rebase_failed.json +221 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/remote_not_origin.json +219 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/set_got_revision.json +218 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.py +170 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/resources/git_setup.py +52 -0
- data/vendor/depot_tools/recipes/recipe_modules/git/test_api.py +18 -0
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/__init__.py +5 -0
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/api.py +50 -0
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/config.py +22 -0
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.expected/basic.json +105 -0
- data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.py +47 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/OWNERS +2 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/__init__.py +12 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/api.py +257 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.expected/basic.json +596 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.py +93 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/resources/gerrit_client.py +251 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/test_api.py +95 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.expected/basic.json +5 -0
- data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.py +49 -0
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/__init__.py +4 -0
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/api.py +222 -0
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.expected/basic.json +247 -0
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.py +92 -0
- data/vendor/depot_tools/recipes/recipe_modules/gsutil/resources/gsutil_smart_retry.py +69 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/__init__.py +36 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/api.py +140 -0
- 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 +21 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/mac.json +83 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/win.json +21 -0
- data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.py +42 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/__init__.py +27 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/api.py +251 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.expected/basic.json +27 -0
- data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.py +19 -0
- 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/__init__.py +18 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +264 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/basic_tags.json +57 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json +190 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch_and_target_ref.json +190 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +21 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch_new.json +22 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +95 -0
- data/vendor/depot_tools/recipes/recipe_modules/tryserver/test_api.py +14 -0
- 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/__init__.py +25 -0
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/api.py +137 -0
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/linux.json +21 -0
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/mac.json +21 -0
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/win.json +108 -0
- data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.py +21 -0
- data/vendor/depot_tools/recipes/recipes.py +249 -0
- data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.expected/basic.json +175 -0
- data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.py +56 -0
- data/vendor/depot_tools/recipes/trigger_recipe_roller.txt +13 -0
- data/vendor/depot_tools/repo +1194 -0
- data/vendor/depot_tools/roll-dep +21 -0
- data/vendor/depot_tools/roll-dep.bat +21 -0
- data/vendor/depot_tools/roll_dep.py +282 -0
- data/vendor/depot_tools/scm.py +415 -0
- data/vendor/depot_tools/setup_color.py +130 -0
- data/vendor/depot_tools/split_cl.py +263 -0
- data/vendor/depot_tools/subcommand.py +261 -0
- data/vendor/depot_tools/subprocess2.py +258 -0
- data/vendor/depot_tools/third_party/__init__.py +5 -0
- data/vendor/depot_tools/third_party/colorama/LICENSE.txt +27 -0
- data/vendor/depot_tools/third_party/colorama/README.chromium +12 -0
- data/vendor/depot_tools/third_party/colorama/README.rst +346 -0
- data/vendor/depot_tools/third_party/colorama/__init__.py +6 -0
- data/vendor/depot_tools/third_party/colorama/ansi.py +102 -0
- data/vendor/depot_tools/third_party/colorama/ansitowin32.py +257 -0
- data/vendor/depot_tools/third_party/colorama/initialise.py +80 -0
- data/vendor/depot_tools/third_party/colorama/win32.py +152 -0
- data/vendor/depot_tools/third_party/colorama/winterm.py +169 -0
- data/vendor/depot_tools/third_party/coverage/AUTHORS.txt +43 -0
- data/vendor/depot_tools/third_party/coverage/PKG-INFO +41 -0
- data/vendor/depot_tools/third_party/coverage/README.chromium +13 -0
- data/vendor/depot_tools/third_party/coverage/__init__.py +120 -0
- data/vendor/depot_tools/third_party/coverage/__main__.py +4 -0
- data/vendor/depot_tools/third_party/coverage/annotate.py +101 -0
- data/vendor/depot_tools/third_party/coverage/backward.py +184 -0
- data/vendor/depot_tools/third_party/coverage/bytecode.py +75 -0
- data/vendor/depot_tools/third_party/coverage/cmdline.py +740 -0
- data/vendor/depot_tools/third_party/coverage/codeunit.py +145 -0
- data/vendor/depot_tools/third_party/coverage/collector.py +353 -0
- data/vendor/depot_tools/third_party/coverage/config.py +213 -0
- data/vendor/depot_tools/third_party/coverage/control.py +776 -0
- data/vendor/depot_tools/third_party/coverage/data.py +278 -0
- data/vendor/depot_tools/third_party/coverage/debug.py +54 -0
- data/vendor/depot_tools/third_party/coverage/execfile.py +171 -0
- data/vendor/depot_tools/third_party/coverage/files.py +309 -0
- data/vendor/depot_tools/third_party/coverage/fullcoverage/encodings.py +57 -0
- data/vendor/depot_tools/third_party/coverage/html.py +387 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/coverage_html.js +376 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/index.html +104 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/jquery-1.4.3.min.js +166 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/jquery.hotkeys.js +99 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/jquery.isonscreen.js +53 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/jquery.min.js +166 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/jquery.tablesorter.min.js +2 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/keybd_closed.png +0 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/keybd_open.png +0 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/pyfile.html +90 -0
- data/vendor/depot_tools/third_party/coverage/htmlfiles/style.css +300 -0
- data/vendor/depot_tools/third_party/coverage/misc.py +163 -0
- data/vendor/depot_tools/third_party/coverage/parser.py +666 -0
- data/vendor/depot_tools/third_party/coverage/phystokens.py +208 -0
- data/vendor/depot_tools/third_party/coverage/report.py +92 -0
- data/vendor/depot_tools/third_party/coverage/results.py +286 -0
- data/vendor/depot_tools/third_party/coverage/summary.py +86 -0
- data/vendor/depot_tools/third_party/coverage/templite.py +166 -0
- data/vendor/depot_tools/third_party/coverage/version.py +9 -0
- data/vendor/depot_tools/third_party/coverage/xmlreport.py +155 -0
- data/vendor/depot_tools/third_party/httplib2/LICENSE +1339 -0
- data/vendor/depot_tools/third_party/httplib2/README.chromium +15 -0
- data/vendor/depot_tools/third_party/httplib2/__init__.py +1780 -0
- data/vendor/depot_tools/third_party/httplib2/cacerts.txt +2196 -0
- data/vendor/depot_tools/third_party/httplib2/iri2uri.py +110 -0
- data/vendor/depot_tools/third_party/httplib2/socks.py +448 -0
- data/vendor/depot_tools/third_party/repo/COPYING +202 -0
- data/vendor/depot_tools/third_party/repo/README.chromium +4 -0
- data/vendor/depot_tools/third_party/repo/__init__.py +0 -0
- data/vendor/depot_tools/third_party/repo/progress.py +117 -0
- data/vendor/depot_tools/third_party/retry_decorator/LICENSE.google +30 -0
- data/vendor/depot_tools/third_party/retry_decorator/__init__.py +0 -0
- data/vendor/depot_tools/third_party/retry_decorator/decorators.py +45 -0
- data/vendor/depot_tools/third_party/schema/.editorconfig +15 -0
- data/vendor/depot_tools/third_party/schema/.gitignore +174 -0
- data/vendor/depot_tools/third_party/schema/.travis.yml +37 -0
- data/vendor/depot_tools/third_party/schema/LICENSE-MIT +19 -0
- data/vendor/depot_tools/third_party/schema/MANIFEST.in +1 -0
- data/vendor/depot_tools/third_party/schema/README.chromium +12 -0
- data/vendor/depot_tools/third_party/schema/README.rst +382 -0
- data/vendor/depot_tools/third_party/schema/__init__.py +1 -0
- data/vendor/depot_tools/third_party/schema/schema.py +338 -0
- data/vendor/depot_tools/third_party/schema/setup.cfg +5 -0
- data/vendor/depot_tools/third_party/schema/setup.py +30 -0
- data/vendor/depot_tools/third_party/schema/test_schema.py +556 -0
- data/vendor/depot_tools/third_party/schema/tox.ini +33 -0
- data/vendor/depot_tools/third_party/six/LICENSE.txt +18 -0
- data/vendor/depot_tools/third_party/six/README.chromium +10 -0
- data/vendor/depot_tools/third_party/six/__init__.py +762 -0
- data/vendor/depot_tools/update_depot_tools +138 -0
- data/vendor/depot_tools/update_depot_tools.bat +65 -0
- data/vendor/depot_tools/update_depot_tools_toggle.py +38 -0
- data/vendor/depot_tools/upload_metrics.py +26 -0
- data/vendor/depot_tools/upload_to_google_storage.py +306 -0
- data/vendor/depot_tools/vpython +42 -0
- data/vendor/depot_tools/vpython.bat +7 -0
- data/vendor/depot_tools/vpython3 +55 -0
- data/vendor/depot_tools/vpython3.bat +12 -0
- data/vendor/depot_tools/watchlists.py +141 -0
- data/vendor/depot_tools/weekly +54 -0
- data/vendor/depot_tools/win32imports.py +61 -0
- data/vendor/depot_tools/win_toolchain/OWNERS +2 -0
- data/vendor/depot_tools/win_toolchain/README.md +74 -0
- data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +599 -0
- data/vendor/depot_tools/win_toolchain/package_from_installed.py +524 -0
- data/vendor/depot_tools/wtf +81 -0
- data/vendor/depot_tools/yapf +21 -0
- data/vendor/depot_tools/yapf.bat +12 -0
- data/vendor/depot_tools/zsh-goodies/README +6 -0
- data/vendor/depot_tools/zsh-goodies/_gclient +14 -0
- metadata +729 -0
@@ -0,0 +1,293 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# Copyright (c) 2018 The Chromium Authors. All rights reserved.
|
3
|
+
# Use of this source code is governed by a BSD-style license that can be
|
4
|
+
# found in the LICENSE file.
|
5
|
+
|
6
|
+
from __future__ import print_function
|
7
|
+
|
8
|
+
import re
|
9
|
+
import scm
|
10
|
+
import subprocess2
|
11
|
+
import sys
|
12
|
+
|
13
|
+
try:
|
14
|
+
import urlparse
|
15
|
+
except ImportError: # For Py3 compatibility
|
16
|
+
import urllib.parse as urlparse
|
17
|
+
|
18
|
+
|
19
|
+
# Current version of metrics recording.
|
20
|
+
# When we add new metrics, the version number will be increased, we display the
|
21
|
+
# user what has changed, and ask the user to agree again.
|
22
|
+
CURRENT_VERSION = 1
|
23
|
+
|
24
|
+
APP_URL = 'https://cit-cli-metrics.appspot.com'
|
25
|
+
|
26
|
+
def get_notice_countdown_header(countdown):
|
27
|
+
if countdown == 0:
|
28
|
+
yield ' METRICS COLLECTION IS TAKING PLACE'
|
29
|
+
else:
|
30
|
+
yield ' METRICS COLLECTION WILL START IN %d EXECUTIONS' % countdown
|
31
|
+
|
32
|
+
def get_notice_version_change_header():
|
33
|
+
yield ' WE ARE COLLECTING ADDITIONAL METRICS'
|
34
|
+
yield ''
|
35
|
+
yield ' Please review the changes and opt-in again.'
|
36
|
+
|
37
|
+
def get_notice_footer():
|
38
|
+
yield 'To suppress this message opt in or out using:'
|
39
|
+
yield '$ gclient metrics [--opt-in] [--opt-out]'
|
40
|
+
yield 'For more information please see metrics.README.md'
|
41
|
+
yield 'in your depot_tools checkout or visit'
|
42
|
+
yield 'https://goo.gl/yNpRDV.'
|
43
|
+
|
44
|
+
def get_change_notice(version):
|
45
|
+
if version == 0:
|
46
|
+
pass # No changes for version 0
|
47
|
+
elif version == 1:
|
48
|
+
yield 'We want to collect the Git version.'
|
49
|
+
yield 'We want to collect information about the HTTP'
|
50
|
+
yield 'requests that depot_tools makes, and the git and'
|
51
|
+
yield 'cipd commands it executes.'
|
52
|
+
yield ''
|
53
|
+
yield 'We only collect known strings to make sure we'
|
54
|
+
yield 'don\'t record PII.'
|
55
|
+
|
56
|
+
|
57
|
+
KNOWN_PROJECT_URLS = {
|
58
|
+
'https://chrome-internal.googlesource.com/chrome/ios_internal',
|
59
|
+
'https://chrome-internal.googlesource.com/infra/infra_internal',
|
60
|
+
'https://chromium.googlesource.com/breakpad/breakpad',
|
61
|
+
'https://chromium.googlesource.com/chromium/src',
|
62
|
+
'https://chromium.googlesource.com/chromium/tools/depot_tools',
|
63
|
+
'https://chromium.googlesource.com/crashpad/crashpad',
|
64
|
+
'https://chromium.googlesource.com/external/gyp',
|
65
|
+
'https://chromium.googlesource.com/external/naclports',
|
66
|
+
'https://chromium.googlesource.com/infra/goma/client',
|
67
|
+
'https://chromium.googlesource.com/infra/infra',
|
68
|
+
'https://chromium.googlesource.com/native_client/',
|
69
|
+
'https://chromium.googlesource.com/syzygy',
|
70
|
+
'https://chromium.googlesource.com/v8/v8',
|
71
|
+
'https://dart.googlesource.com/sdk',
|
72
|
+
'https://pdfium.googlesource.com/pdfium',
|
73
|
+
'https://skia.googlesource.com/buildbot',
|
74
|
+
'https://skia.googlesource.com/skia',
|
75
|
+
'https://webrtc.googlesource.com/src',
|
76
|
+
}
|
77
|
+
|
78
|
+
KNOWN_HTTP_HOSTS = {
|
79
|
+
'chrome-internal-review.googlesource.com',
|
80
|
+
'chromium-review.googlesource.com',
|
81
|
+
'dart-review.googlesource.com',
|
82
|
+
'eu1-mirror-chromium-review.googlesource.com',
|
83
|
+
'pdfium-review.googlesource.com',
|
84
|
+
'skia-review.googlesource.com',
|
85
|
+
'us1-mirror-chromium-review.googlesource.com',
|
86
|
+
'us2-mirror-chromium-review.googlesource.com',
|
87
|
+
'us3-mirror-chromium-review.googlesource.com',
|
88
|
+
'webrtc-review.googlesource.com',
|
89
|
+
}
|
90
|
+
|
91
|
+
KNOWN_HTTP_METHODS = {
|
92
|
+
'DELETE',
|
93
|
+
'GET',
|
94
|
+
'PATCH',
|
95
|
+
'POST',
|
96
|
+
'PUT',
|
97
|
+
}
|
98
|
+
|
99
|
+
KNOWN_HTTP_PATHS = {
|
100
|
+
'accounts':
|
101
|
+
re.compile(r'(/a)?/accounts/.*'),
|
102
|
+
'changes':
|
103
|
+
re.compile(r'(/a)?/changes/([^/]+)?$'),
|
104
|
+
'changes/abandon':
|
105
|
+
re.compile(r'(/a)?/changes/.*/abandon'),
|
106
|
+
'changes/comments':
|
107
|
+
re.compile(r'(/a)?/changes/.*/comments'),
|
108
|
+
'changes/detail':
|
109
|
+
re.compile(r'(/a)?/changes/.*/detail'),
|
110
|
+
'changes/edit':
|
111
|
+
re.compile(r'(/a)?/changes/.*/edit'),
|
112
|
+
'changes/message':
|
113
|
+
re.compile(r'(/a)?/changes/.*/message'),
|
114
|
+
'changes/restore':
|
115
|
+
re.compile(r'(/a)?/changes/.*/restore'),
|
116
|
+
'changes/reviewers':
|
117
|
+
re.compile(r'(/a)?/changes/.*/reviewers/.*'),
|
118
|
+
'changes/revisions/commit':
|
119
|
+
re.compile(r'(/a)?/changes/.*/revisions/.*/commit'),
|
120
|
+
'changes/revisions/review':
|
121
|
+
re.compile(r'(/a)?/changes/.*/revisions/.*/review'),
|
122
|
+
'changes/submit':
|
123
|
+
re.compile(r'(/a)?/changes/.*/submit'),
|
124
|
+
'projects/branches':
|
125
|
+
re.compile(r'(/a)?/projects/.*/branches/.*'),
|
126
|
+
}
|
127
|
+
|
128
|
+
KNOWN_HTTP_ARGS = {
|
129
|
+
'ALL_REVISIONS',
|
130
|
+
'CURRENT_COMMIT',
|
131
|
+
'CURRENT_REVISION',
|
132
|
+
'DETAILED_ACCOUNTS',
|
133
|
+
'LABELS',
|
134
|
+
}
|
135
|
+
|
136
|
+
GIT_VERSION_RE = re.compile(
|
137
|
+
r'git version (\d)\.(\d{0,2})\.(\d{0,2})'
|
138
|
+
)
|
139
|
+
|
140
|
+
KNOWN_SUBCOMMAND_ARGS = {
|
141
|
+
'cc',
|
142
|
+
'hashtag',
|
143
|
+
'l=Auto-Submit+1',
|
144
|
+
'l=Code-Review+1',
|
145
|
+
'l=Code-Review+2',
|
146
|
+
'l=Commit-Queue+1',
|
147
|
+
'l=Commit-Queue+2',
|
148
|
+
'label',
|
149
|
+
'm',
|
150
|
+
'notify=ALL',
|
151
|
+
'notify=NONE',
|
152
|
+
'private',
|
153
|
+
'r',
|
154
|
+
'ready',
|
155
|
+
'topic',
|
156
|
+
'wip'
|
157
|
+
}
|
158
|
+
|
159
|
+
|
160
|
+
def get_python_version():
|
161
|
+
"""Return the python version in the major.minor.micro format."""
|
162
|
+
return '{v.major}.{v.minor}.{v.micro}'.format(v=sys.version_info)
|
163
|
+
|
164
|
+
|
165
|
+
def get_git_version():
|
166
|
+
"""Return the Git version in the major.minor.micro format."""
|
167
|
+
p = subprocess2.Popen(
|
168
|
+
['git', '--version'],
|
169
|
+
stdout=subprocess2.PIPE, stderr=subprocess2.PIPE)
|
170
|
+
stdout, _ = p.communicate()
|
171
|
+
match = GIT_VERSION_RE.match(stdout.decode('utf-8'))
|
172
|
+
if not match:
|
173
|
+
return None
|
174
|
+
return '%s.%s.%s' % match.groups()
|
175
|
+
|
176
|
+
|
177
|
+
def return_code_from_exception(exception):
|
178
|
+
"""Returns the exit code that would result of raising the exception."""
|
179
|
+
if exception is None:
|
180
|
+
return 0
|
181
|
+
if isinstance(exception[1], SystemExit):
|
182
|
+
return exception[1].code
|
183
|
+
return 1
|
184
|
+
|
185
|
+
|
186
|
+
def extract_known_subcommand_args(args):
|
187
|
+
"""Extract the known arguments from the passed list of args."""
|
188
|
+
known_args = []
|
189
|
+
for arg in args:
|
190
|
+
if arg in KNOWN_SUBCOMMAND_ARGS:
|
191
|
+
known_args.append(arg)
|
192
|
+
else:
|
193
|
+
arg = arg.split('=')[0]
|
194
|
+
if arg in KNOWN_SUBCOMMAND_ARGS:
|
195
|
+
known_args.append(arg)
|
196
|
+
return sorted(known_args)
|
197
|
+
|
198
|
+
|
199
|
+
def extract_http_metrics(request_uri, method, status, response_time):
|
200
|
+
"""Extract metrics from the request URI.
|
201
|
+
|
202
|
+
Extracts the host, path, and arguments from the request URI, and returns them
|
203
|
+
along with the method, status and response time.
|
204
|
+
|
205
|
+
The host, method, path and arguments must be in the KNOWN_HTTP_* constants
|
206
|
+
defined above.
|
207
|
+
|
208
|
+
Arguments are the values of the o= url parameter. In Gerrit, additional fields
|
209
|
+
can be obtained by adding o parameters, each option requires more database
|
210
|
+
lookups and slows down the query response time to the client, so we make an
|
211
|
+
effort to collect them.
|
212
|
+
|
213
|
+
The regex defined in KNOWN_HTTP_PATH_RES are checked against the path, and
|
214
|
+
those that match will be returned.
|
215
|
+
"""
|
216
|
+
http_metrics = {
|
217
|
+
'status': status,
|
218
|
+
'response_time': response_time,
|
219
|
+
}
|
220
|
+
|
221
|
+
if method in KNOWN_HTTP_METHODS:
|
222
|
+
http_metrics['method'] = method
|
223
|
+
|
224
|
+
parsed_url = urlparse.urlparse(request_uri)
|
225
|
+
|
226
|
+
if parsed_url.netloc in KNOWN_HTTP_HOSTS:
|
227
|
+
http_metrics['host'] = parsed_url.netloc
|
228
|
+
|
229
|
+
for name, path_re in KNOWN_HTTP_PATHS.items():
|
230
|
+
if path_re.match(parsed_url.path):
|
231
|
+
http_metrics['path'] = name
|
232
|
+
break
|
233
|
+
|
234
|
+
parsed_query = urlparse.parse_qs(parsed_url.query)
|
235
|
+
|
236
|
+
# Collect o-parameters from the request.
|
237
|
+
args = [
|
238
|
+
arg for arg in parsed_query.get('o', [])
|
239
|
+
if arg in KNOWN_HTTP_ARGS
|
240
|
+
]
|
241
|
+
if args:
|
242
|
+
http_metrics['arguments'] = args
|
243
|
+
|
244
|
+
return http_metrics
|
245
|
+
|
246
|
+
|
247
|
+
def get_repo_timestamp(path_to_repo):
|
248
|
+
"""Get an approximate timestamp for the upstream of |path_to_repo|.
|
249
|
+
|
250
|
+
Returns the top two bits of the timestamp of the HEAD for the upstream of the
|
251
|
+
branch path_to_repo is checked out at.
|
252
|
+
"""
|
253
|
+
# Get the upstream for the current branch. If we're not in a branch, fallback
|
254
|
+
# to HEAD.
|
255
|
+
try:
|
256
|
+
upstream = scm.GIT.GetUpstreamBranch(path_to_repo) or 'HEAD'
|
257
|
+
except subprocess2.CalledProcessError:
|
258
|
+
upstream = 'HEAD'
|
259
|
+
|
260
|
+
# Get the timestamp of the HEAD for the upstream of the current branch.
|
261
|
+
p = subprocess2.Popen(
|
262
|
+
['git', '-C', path_to_repo, 'log', '-n1', upstream, '--format=%at'],
|
263
|
+
stdout=subprocess2.PIPE, stderr=subprocess2.PIPE)
|
264
|
+
stdout, _ = p.communicate()
|
265
|
+
|
266
|
+
# If there was an error, give up.
|
267
|
+
if p.returncode != 0:
|
268
|
+
return None
|
269
|
+
|
270
|
+
return stdout.strip()
|
271
|
+
|
272
|
+
def print_boxed_text(out, min_width, lines):
|
273
|
+
[EW, NS, SE, SW, NE, NW] = list('=|++++')
|
274
|
+
width = max(min_width, max(len(line) for line in lines))
|
275
|
+
out(SE + EW * (width + 2) + SW + '\n')
|
276
|
+
for line in lines:
|
277
|
+
out('%s %-*s %s\n' % (NS, width, line, NS))
|
278
|
+
out(NE + EW * (width + 2) + NW + '\n')
|
279
|
+
|
280
|
+
def print_notice(countdown):
|
281
|
+
"""Print a notice to let the user know the status of metrics collection."""
|
282
|
+
lines = list(get_notice_countdown_header(countdown))
|
283
|
+
lines.append('')
|
284
|
+
lines += list(get_notice_footer())
|
285
|
+
print_boxed_text(sys.stderr.write, 49, lines)
|
286
|
+
|
287
|
+
def print_version_change(config_version):
|
288
|
+
"""Print a notice to let the user know we are collecting more metrics."""
|
289
|
+
lines = list(get_notice_version_change_header())
|
290
|
+
for version in range(config_version + 1, CURRENT_VERSION + 1):
|
291
|
+
lines.append('')
|
292
|
+
lines += list(get_change_notice(version))
|
293
|
+
print_boxed_text(sys.stderr.write, 49, lines)
|
@@ -0,0 +1,971 @@
|
|
1
|
+
#!/usr/bin/env vpython3
|
2
|
+
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
3
|
+
# Use of this source code is governed by a BSD-style license that can be
|
4
|
+
# found in the LICENSE file.
|
5
|
+
|
6
|
+
"""Get stats about your activity.
|
7
|
+
|
8
|
+
Example:
|
9
|
+
- my_activity.py for stats for the current week (last week on mondays).
|
10
|
+
- my_activity.py -Q for stats for last quarter.
|
11
|
+
- my_activity.py -Y for stats for this year.
|
12
|
+
- my_activity.py -b 4/24/19 for stats since April 24th 2019.
|
13
|
+
- my_activity.py -b 4/24/19 -e 6/16/19 stats between April 24th and June 16th.
|
14
|
+
- my_activity.py -jd to output stats for the week to json with deltas data.
|
15
|
+
"""
|
16
|
+
|
17
|
+
# These services typically only provide a created time and a last modified time
|
18
|
+
# for each item for general queries. This is not enough to determine if there
|
19
|
+
# was activity in a given time period. So, we first query for all things created
|
20
|
+
# before end and modified after begin. Then, we get the details of each item and
|
21
|
+
# check those details to determine if there was activity in the given period.
|
22
|
+
# This means that query time scales mostly with (today() - begin).
|
23
|
+
|
24
|
+
from __future__ import print_function
|
25
|
+
|
26
|
+
import collections
|
27
|
+
import contextlib
|
28
|
+
from datetime import datetime
|
29
|
+
from datetime import timedelta
|
30
|
+
import httplib2
|
31
|
+
import itertools
|
32
|
+
import json
|
33
|
+
import logging
|
34
|
+
from multiprocessing.pool import ThreadPool
|
35
|
+
import optparse
|
36
|
+
import os
|
37
|
+
import subprocess
|
38
|
+
from string import Formatter
|
39
|
+
import sys
|
40
|
+
import urllib
|
41
|
+
import re
|
42
|
+
|
43
|
+
import auth
|
44
|
+
import fix_encoding
|
45
|
+
import gclient_utils
|
46
|
+
import gerrit_util
|
47
|
+
|
48
|
+
|
49
|
+
if sys.version_info.major == 2:
|
50
|
+
logging.warning(
|
51
|
+
'Python 2 is deprecated. Run my_activity.py using vpython3.')
|
52
|
+
import urllib as urllib_parse
|
53
|
+
else:
|
54
|
+
import urllib.parse as urllib_parse
|
55
|
+
|
56
|
+
try:
|
57
|
+
import dateutil # pylint: disable=import-error
|
58
|
+
import dateutil.parser
|
59
|
+
from dateutil.relativedelta import relativedelta
|
60
|
+
except ImportError:
|
61
|
+
logging.error('python-dateutil package required')
|
62
|
+
exit(1)
|
63
|
+
|
64
|
+
|
65
|
+
class DefaultFormatter(Formatter):
|
66
|
+
def __init__(self, default = ''):
|
67
|
+
super(DefaultFormatter, self).__init__()
|
68
|
+
self.default = default
|
69
|
+
|
70
|
+
def get_value(self, key, args, kwds):
|
71
|
+
if isinstance(key, str) and key not in kwds:
|
72
|
+
return self.default
|
73
|
+
return Formatter.get_value(self, key, args, kwds)
|
74
|
+
|
75
|
+
gerrit_instances = [
|
76
|
+
{
|
77
|
+
'url': 'android-review.googlesource.com',
|
78
|
+
'shorturl': 'r.android.com',
|
79
|
+
'short_url_protocol': 'https',
|
80
|
+
},
|
81
|
+
{
|
82
|
+
'url': 'gerrit-review.googlesource.com',
|
83
|
+
},
|
84
|
+
{
|
85
|
+
'url': 'chrome-internal-review.googlesource.com',
|
86
|
+
'shorturl': 'crrev.com/i',
|
87
|
+
'short_url_protocol': 'https',
|
88
|
+
},
|
89
|
+
{
|
90
|
+
'url': 'chromium-review.googlesource.com',
|
91
|
+
'shorturl': 'crrev.com/c',
|
92
|
+
'short_url_protocol': 'https',
|
93
|
+
},
|
94
|
+
{
|
95
|
+
'url': 'dawn-review.googlesource.com',
|
96
|
+
},
|
97
|
+
{
|
98
|
+
'url': 'pdfium-review.googlesource.com',
|
99
|
+
},
|
100
|
+
{
|
101
|
+
'url': 'skia-review.googlesource.com',
|
102
|
+
},
|
103
|
+
]
|
104
|
+
|
105
|
+
monorail_projects = {
|
106
|
+
'angleproject': {
|
107
|
+
'shorturl': 'anglebug.com',
|
108
|
+
'short_url_protocol': 'http',
|
109
|
+
},
|
110
|
+
'chromium': {
|
111
|
+
'shorturl': 'crbug.com',
|
112
|
+
'short_url_protocol': 'https',
|
113
|
+
},
|
114
|
+
'dawn': {},
|
115
|
+
'google-breakpad': {},
|
116
|
+
'gyp': {},
|
117
|
+
'pdfium': {
|
118
|
+
'shorturl': 'crbug.com/pdfium',
|
119
|
+
'short_url_protocol': 'https',
|
120
|
+
},
|
121
|
+
'skia': {},
|
122
|
+
'v8': {
|
123
|
+
'shorturl': 'crbug.com/v8',
|
124
|
+
'short_url_protocol': 'https',
|
125
|
+
},
|
126
|
+
}
|
127
|
+
|
128
|
+
def username(email):
|
129
|
+
"""Keeps the username of an email address."""
|
130
|
+
return email and email.split('@', 1)[0]
|
131
|
+
|
132
|
+
|
133
|
+
def datetime_to_midnight(date):
|
134
|
+
return date - timedelta(hours=date.hour, minutes=date.minute,
|
135
|
+
seconds=date.second, microseconds=date.microsecond)
|
136
|
+
|
137
|
+
|
138
|
+
def get_quarter_of(date):
|
139
|
+
begin = (datetime_to_midnight(date) -
|
140
|
+
relativedelta(months=(date.month - 1) % 3, days=(date.day - 1)))
|
141
|
+
return begin, begin + relativedelta(months=3)
|
142
|
+
|
143
|
+
|
144
|
+
def get_year_of(date):
|
145
|
+
begin = (datetime_to_midnight(date) -
|
146
|
+
relativedelta(months=(date.month - 1), days=(date.day - 1)))
|
147
|
+
return begin, begin + relativedelta(years=1)
|
148
|
+
|
149
|
+
|
150
|
+
def get_week_of(date):
|
151
|
+
begin = (datetime_to_midnight(date) - timedelta(days=date.weekday()))
|
152
|
+
return begin, begin + timedelta(days=7)
|
153
|
+
|
154
|
+
|
155
|
+
def get_yes_or_no(msg):
|
156
|
+
while True:
|
157
|
+
response = gclient_utils.AskForData(msg + ' yes/no [no] ')
|
158
|
+
if response == 'y' or response == 'yes':
|
159
|
+
return True
|
160
|
+
elif not response or response == 'n' or response == 'no':
|
161
|
+
return False
|
162
|
+
|
163
|
+
|
164
|
+
def datetime_from_gerrit(date_string):
|
165
|
+
return datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S.%f000')
|
166
|
+
|
167
|
+
|
168
|
+
def datetime_from_monorail(date_string):
|
169
|
+
return datetime.strptime(date_string, '%Y-%m-%dT%H:%M:%S')
|
170
|
+
|
171
|
+
def extract_bug_numbers_from_description(issue):
|
172
|
+
# Getting the description for REST Gerrit
|
173
|
+
revision = issue['revisions'][issue['current_revision']]
|
174
|
+
description = revision['commit']['message']
|
175
|
+
|
176
|
+
bugs = []
|
177
|
+
# Handle both "Bug: 99999" and "BUG=99999" bug notations
|
178
|
+
# Multiple bugs can be noted on a single line or in multiple ones.
|
179
|
+
matches = re.findall(
|
180
|
+
r'^(BUG=|(Bug|Fixed):\s*)((((?:[a-zA-Z0-9-]+:)?\d+)(,\s?)?)+)',
|
181
|
+
description, flags=re.IGNORECASE | re.MULTILINE)
|
182
|
+
if matches:
|
183
|
+
for match in matches:
|
184
|
+
bugs.extend(match[2].replace(' ', '').split(','))
|
185
|
+
# Add default chromium: prefix if none specified.
|
186
|
+
bugs = [bug if ':' in bug else 'chromium:%s' % bug for bug in bugs]
|
187
|
+
|
188
|
+
return sorted(set(bugs))
|
189
|
+
|
190
|
+
class MyActivity(object):
|
191
|
+
def __init__(self, options):
|
192
|
+
self.options = options
|
193
|
+
self.modified_after = options.begin
|
194
|
+
self.modified_before = options.end
|
195
|
+
self.user = options.user
|
196
|
+
self.changes = []
|
197
|
+
self.reviews = []
|
198
|
+
self.issues = []
|
199
|
+
self.referenced_issues = []
|
200
|
+
self.google_code_auth_token = None
|
201
|
+
self.access_errors = set()
|
202
|
+
self.skip_servers = (options.skip_servers.split(','))
|
203
|
+
|
204
|
+
def show_progress(self, how='.'):
|
205
|
+
if sys.stdout.isatty():
|
206
|
+
sys.stdout.write(how)
|
207
|
+
sys.stdout.flush()
|
208
|
+
|
209
|
+
def gerrit_changes_over_rest(self, instance, filters):
|
210
|
+
# Convert the "key:value" filter to a list of (key, value) pairs.
|
211
|
+
req = list(f.split(':', 1) for f in filters)
|
212
|
+
try:
|
213
|
+
# Instantiate the generator to force all the requests now and catch the
|
214
|
+
# errors here.
|
215
|
+
return list(gerrit_util.GenerateAllChanges(instance['url'], req,
|
216
|
+
o_params=['MESSAGES', 'LABELS', 'DETAILED_ACCOUNTS',
|
217
|
+
'CURRENT_REVISION', 'CURRENT_COMMIT']))
|
218
|
+
except gerrit_util.GerritError as e:
|
219
|
+
error_message = 'Looking up %r: %s' % (instance['url'], e)
|
220
|
+
if error_message not in self.access_errors:
|
221
|
+
self.access_errors.add(error_message)
|
222
|
+
return []
|
223
|
+
|
224
|
+
def gerrit_search(self, instance, owner=None, reviewer=None):
|
225
|
+
if instance['url'] in self.skip_servers:
|
226
|
+
return []
|
227
|
+
max_age = datetime.today() - self.modified_after
|
228
|
+
filters = ['-age:%ss' % (max_age.days * 24 * 3600 + max_age.seconds)]
|
229
|
+
if owner:
|
230
|
+
assert not reviewer
|
231
|
+
filters.append('owner:%s' % owner)
|
232
|
+
else:
|
233
|
+
filters.extend(('-owner:%s' % reviewer, 'reviewer:%s' % reviewer))
|
234
|
+
# TODO(cjhopman): Should abandoned changes be filtered out when
|
235
|
+
# merged_only is not enabled?
|
236
|
+
if self.options.merged_only:
|
237
|
+
filters.append('status:merged')
|
238
|
+
|
239
|
+
issues = self.gerrit_changes_over_rest(instance, filters)
|
240
|
+
self.show_progress()
|
241
|
+
issues = [self.process_gerrit_issue(instance, issue)
|
242
|
+
for issue in issues]
|
243
|
+
|
244
|
+
issues = filter(self.filter_issue, issues)
|
245
|
+
issues = sorted(issues, key=lambda i: i['modified'], reverse=True)
|
246
|
+
|
247
|
+
return issues
|
248
|
+
|
249
|
+
def process_gerrit_issue(self, instance, issue):
|
250
|
+
ret = {}
|
251
|
+
if self.options.deltas:
|
252
|
+
ret['delta'] = DefaultFormatter().format(
|
253
|
+
'+{insertions},-{deletions}',
|
254
|
+
**issue)
|
255
|
+
ret['status'] = issue['status']
|
256
|
+
if 'shorturl' in instance:
|
257
|
+
protocol = instance.get('short_url_protocol', 'http')
|
258
|
+
url = instance['shorturl']
|
259
|
+
else:
|
260
|
+
protocol = 'https'
|
261
|
+
url = instance['url']
|
262
|
+
ret['review_url'] = '%s://%s/%s' % (protocol, url, issue['_number'])
|
263
|
+
|
264
|
+
ret['header'] = issue['subject']
|
265
|
+
ret['owner'] = issue['owner'].get('email', '')
|
266
|
+
ret['author'] = ret['owner']
|
267
|
+
ret['created'] = datetime_from_gerrit(issue['created'])
|
268
|
+
ret['modified'] = datetime_from_gerrit(issue['updated'])
|
269
|
+
if 'messages' in issue:
|
270
|
+
ret['replies'] = self.process_gerrit_issue_replies(issue['messages'])
|
271
|
+
else:
|
272
|
+
ret['replies'] = []
|
273
|
+
ret['reviewers'] = set(r['author'] for r in ret['replies'])
|
274
|
+
ret['reviewers'].discard(ret['author'])
|
275
|
+
ret['bugs'] = extract_bug_numbers_from_description(issue)
|
276
|
+
return ret
|
277
|
+
|
278
|
+
@staticmethod
|
279
|
+
def process_gerrit_issue_replies(replies):
|
280
|
+
ret = []
|
281
|
+
replies = filter(lambda r: 'author' in r and 'email' in r['author'],
|
282
|
+
replies)
|
283
|
+
for reply in replies:
|
284
|
+
ret.append({
|
285
|
+
'author': reply['author']['email'],
|
286
|
+
'created': datetime_from_gerrit(reply['date']),
|
287
|
+
'content': reply['message'],
|
288
|
+
})
|
289
|
+
return ret
|
290
|
+
|
291
|
+
def monorail_get_auth_http(self):
|
292
|
+
# Manually use a long timeout (10m); for some users who have a
|
293
|
+
# long history on the issue tracker, whatever the default timeout
|
294
|
+
# is is reached.
|
295
|
+
return auth.Authenticator().authorize(httplib2.Http(timeout=600))
|
296
|
+
|
297
|
+
def filter_modified_monorail_issue(self, issue):
|
298
|
+
"""Precisely checks if an issue has been modified in the time range.
|
299
|
+
|
300
|
+
This fetches all issue comments to check if the issue has been modified in
|
301
|
+
the time range specified by user. This is needed because monorail only
|
302
|
+
allows filtering by last updated and published dates, which is not
|
303
|
+
sufficient to tell whether a given issue has been modified at some specific
|
304
|
+
time range. Any update to the issue is a reported as comment on Monorail.
|
305
|
+
|
306
|
+
Args:
|
307
|
+
issue: Issue dict as returned by monorail_query_issues method. In
|
308
|
+
particular, must have a key 'uid' formatted as 'project:issue_id'.
|
309
|
+
|
310
|
+
Returns:
|
311
|
+
Passed issue if modified, None otherwise.
|
312
|
+
"""
|
313
|
+
http = self.monorail_get_auth_http()
|
314
|
+
project, issue_id = issue['uid'].split(':')
|
315
|
+
url = ('https://monorail-prod.appspot.com/_ah/api/monorail/v1/projects'
|
316
|
+
'/%s/issues/%s/comments?maxResults=10000') % (project, issue_id)
|
317
|
+
_, body = http.request(url)
|
318
|
+
self.show_progress()
|
319
|
+
content = json.loads(body)
|
320
|
+
if not content:
|
321
|
+
logging.error('Unable to parse %s response from monorail.', project)
|
322
|
+
return issue
|
323
|
+
|
324
|
+
for item in content.get('items', []):
|
325
|
+
comment_published = datetime_from_monorail(item['published'])
|
326
|
+
if self.filter_modified(comment_published):
|
327
|
+
return issue
|
328
|
+
|
329
|
+
return None
|
330
|
+
|
331
|
+
def monorail_query_issues(self, project, query):
|
332
|
+
http = self.monorail_get_auth_http()
|
333
|
+
url = ('https://monorail-prod.appspot.com/_ah/api/monorail/v1/projects'
|
334
|
+
'/%s/issues') % project
|
335
|
+
query_data = urllib_parse.urlencode(query)
|
336
|
+
url = url + '?' + query_data
|
337
|
+
_, body = http.request(url)
|
338
|
+
self.show_progress()
|
339
|
+
content = json.loads(body)
|
340
|
+
if not content:
|
341
|
+
logging.error('Unable to parse %s response from monorail.', project)
|
342
|
+
return []
|
343
|
+
|
344
|
+
issues = []
|
345
|
+
project_config = monorail_projects.get(project, {})
|
346
|
+
for item in content.get('items', []):
|
347
|
+
if project_config.get('shorturl'):
|
348
|
+
protocol = project_config.get('short_url_protocol', 'http')
|
349
|
+
item_url = '%s://%s/%d' % (
|
350
|
+
protocol, project_config['shorturl'], item['id'])
|
351
|
+
else:
|
352
|
+
item_url = 'https://bugs.chromium.org/p/%s/issues/detail?id=%d' % (
|
353
|
+
project, item['id'])
|
354
|
+
issue = {
|
355
|
+
'uid': '%s:%s' % (project, item['id']),
|
356
|
+
'header': item['title'],
|
357
|
+
'created': datetime_from_monorail(item['published']),
|
358
|
+
'modified': datetime_from_monorail(item['updated']),
|
359
|
+
'author': item['author']['name'],
|
360
|
+
'url': item_url,
|
361
|
+
'comments': [],
|
362
|
+
'status': item['status'],
|
363
|
+
'labels': [],
|
364
|
+
'components': []
|
365
|
+
}
|
366
|
+
if 'owner' in item:
|
367
|
+
issue['owner'] = item['owner']['name']
|
368
|
+
else:
|
369
|
+
issue['owner'] = 'None'
|
370
|
+
if 'labels' in item:
|
371
|
+
issue['labels'] = item['labels']
|
372
|
+
if 'components' in item:
|
373
|
+
issue['components'] = item['components']
|
374
|
+
issues.append(issue)
|
375
|
+
|
376
|
+
return issues
|
377
|
+
|
378
|
+
def monorail_issue_search(self, project):
|
379
|
+
epoch = datetime.utcfromtimestamp(0)
|
380
|
+
# Defaults to @chromium.org email if one wasn't provided on -u option.
|
381
|
+
user_str = (self.options.email if self.options.email.find('@') >= 0
|
382
|
+
else '%s@chromium.org' % self.user)
|
383
|
+
|
384
|
+
issues = self.monorail_query_issues(project, {
|
385
|
+
'maxResults': 10000,
|
386
|
+
'q': user_str,
|
387
|
+
'publishedMax': '%d' % (self.modified_before - epoch).total_seconds(),
|
388
|
+
'updatedMin': '%d' % (self.modified_after - epoch).total_seconds(),
|
389
|
+
})
|
390
|
+
|
391
|
+
if self.options.completed_issues:
|
392
|
+
return [
|
393
|
+
issue for issue in issues
|
394
|
+
if (self.match(issue['owner']) and
|
395
|
+
issue['status'].lower() in ('verified', 'fixed'))
|
396
|
+
]
|
397
|
+
|
398
|
+
return [
|
399
|
+
issue for issue in issues
|
400
|
+
if issue['author'] == user_str or issue['owner'] == user_str]
|
401
|
+
|
402
|
+
def monorail_get_issues(self, project, issue_ids):
|
403
|
+
return self.monorail_query_issues(project, {
|
404
|
+
'maxResults': 10000,
|
405
|
+
'q': 'id:%s' % ','.join(issue_ids)
|
406
|
+
})
|
407
|
+
|
408
|
+
def print_heading(self, heading):
|
409
|
+
print()
|
410
|
+
print(self.options.output_format_heading.format(heading=heading))
|
411
|
+
|
412
|
+
def match(self, author):
|
413
|
+
if '@' in self.user:
|
414
|
+
return author == self.user
|
415
|
+
return author.startswith(self.user + '@')
|
416
|
+
|
417
|
+
def print_change(self, change):
|
418
|
+
activity = len([
|
419
|
+
reply
|
420
|
+
for reply in change['replies']
|
421
|
+
if self.match(reply['author'])
|
422
|
+
])
|
423
|
+
optional_values = {
|
424
|
+
'created': change['created'].date().isoformat(),
|
425
|
+
'modified': change['modified'].date().isoformat(),
|
426
|
+
'reviewers': ', '.join(change['reviewers']),
|
427
|
+
'status': change['status'],
|
428
|
+
'activity': activity,
|
429
|
+
}
|
430
|
+
if self.options.deltas:
|
431
|
+
optional_values['delta'] = change['delta']
|
432
|
+
|
433
|
+
self.print_generic(self.options.output_format,
|
434
|
+
self.options.output_format_changes,
|
435
|
+
change['header'],
|
436
|
+
change['review_url'],
|
437
|
+
change['author'],
|
438
|
+
change['created'],
|
439
|
+
change['modified'],
|
440
|
+
optional_values)
|
441
|
+
|
442
|
+
def print_issue(self, issue):
|
443
|
+
optional_values = {
|
444
|
+
'created': issue['created'].date().isoformat(),
|
445
|
+
'modified': issue['modified'].date().isoformat(),
|
446
|
+
'owner': issue['owner'],
|
447
|
+
'status': issue['status'],
|
448
|
+
}
|
449
|
+
self.print_generic(self.options.output_format,
|
450
|
+
self.options.output_format_issues,
|
451
|
+
issue['header'],
|
452
|
+
issue['url'],
|
453
|
+
issue['author'],
|
454
|
+
issue['created'],
|
455
|
+
issue['modified'],
|
456
|
+
optional_values)
|
457
|
+
|
458
|
+
def print_review(self, review):
|
459
|
+
activity = len([
|
460
|
+
reply
|
461
|
+
for reply in review['replies']
|
462
|
+
if self.match(reply['author'])
|
463
|
+
])
|
464
|
+
optional_values = {
|
465
|
+
'created': review['created'].date().isoformat(),
|
466
|
+
'modified': review['modified'].date().isoformat(),
|
467
|
+
'status': review['status'],
|
468
|
+
'activity': activity,
|
469
|
+
}
|
470
|
+
if self.options.deltas:
|
471
|
+
optional_values['delta'] = review['delta']
|
472
|
+
|
473
|
+
self.print_generic(self.options.output_format,
|
474
|
+
self.options.output_format_reviews,
|
475
|
+
review['header'],
|
476
|
+
review['review_url'],
|
477
|
+
review['author'],
|
478
|
+
review['created'],
|
479
|
+
review['modified'],
|
480
|
+
optional_values)
|
481
|
+
|
482
|
+
@staticmethod
|
483
|
+
def print_generic(default_fmt, specific_fmt,
|
484
|
+
title, url, author, created, modified,
|
485
|
+
optional_values=None):
|
486
|
+
output_format = specific_fmt if specific_fmt is not None else default_fmt
|
487
|
+
values = {
|
488
|
+
'title': title,
|
489
|
+
'url': url,
|
490
|
+
'author': author,
|
491
|
+
'created': created,
|
492
|
+
'modified': modified,
|
493
|
+
}
|
494
|
+
if optional_values is not None:
|
495
|
+
values.update(optional_values)
|
496
|
+
print(DefaultFormatter().format(output_format, **values))
|
497
|
+
|
498
|
+
|
499
|
+
def filter_issue(self, issue, should_filter_by_user=True):
|
500
|
+
def maybe_filter_username(email):
|
501
|
+
return not should_filter_by_user or username(email) == self.user
|
502
|
+
if (maybe_filter_username(issue['author']) and
|
503
|
+
self.filter_modified(issue['created'])):
|
504
|
+
return True
|
505
|
+
if (maybe_filter_username(issue['owner']) and
|
506
|
+
(self.filter_modified(issue['created']) or
|
507
|
+
self.filter_modified(issue['modified']))):
|
508
|
+
return True
|
509
|
+
for reply in issue['replies']:
|
510
|
+
if self.filter_modified(reply['created']):
|
511
|
+
if not should_filter_by_user:
|
512
|
+
break
|
513
|
+
if (username(reply['author']) == self.user
|
514
|
+
or (self.user + '@') in reply['content']):
|
515
|
+
break
|
516
|
+
else:
|
517
|
+
return False
|
518
|
+
return True
|
519
|
+
|
520
|
+
def filter_modified(self, modified):
|
521
|
+
return self.modified_after < modified and modified < self.modified_before
|
522
|
+
|
523
|
+
def auth_for_changes(self):
|
524
|
+
#TODO(cjhopman): Move authentication check for getting changes here.
|
525
|
+
pass
|
526
|
+
|
527
|
+
def auth_for_reviews(self):
|
528
|
+
# Reviews use all the same instances as changes so no authentication is
|
529
|
+
# required.
|
530
|
+
pass
|
531
|
+
|
532
|
+
def get_changes(self):
|
533
|
+
num_instances = len(gerrit_instances)
|
534
|
+
with contextlib.closing(ThreadPool(num_instances)) as pool:
|
535
|
+
gerrit_changes = pool.map_async(
|
536
|
+
lambda instance: self.gerrit_search(instance, owner=self.user),
|
537
|
+
gerrit_instances)
|
538
|
+
gerrit_changes = itertools.chain.from_iterable(gerrit_changes.get())
|
539
|
+
self.changes = list(gerrit_changes)
|
540
|
+
|
541
|
+
def print_changes(self):
|
542
|
+
if self.changes:
|
543
|
+
self.print_heading('Changes')
|
544
|
+
for change in self.changes:
|
545
|
+
self.print_change(change)
|
546
|
+
|
547
|
+
def print_access_errors(self):
|
548
|
+
if self.access_errors:
|
549
|
+
logging.error('Access Errors:')
|
550
|
+
for error in self.access_errors:
|
551
|
+
logging.error(error.rstrip())
|
552
|
+
|
553
|
+
def get_reviews(self):
|
554
|
+
num_instances = len(gerrit_instances)
|
555
|
+
with contextlib.closing(ThreadPool(num_instances)) as pool:
|
556
|
+
gerrit_reviews = pool.map_async(
|
557
|
+
lambda instance: self.gerrit_search(instance, reviewer=self.user),
|
558
|
+
gerrit_instances)
|
559
|
+
gerrit_reviews = itertools.chain.from_iterable(gerrit_reviews.get())
|
560
|
+
self.reviews = list(gerrit_reviews)
|
561
|
+
|
562
|
+
def print_reviews(self):
|
563
|
+
if self.reviews:
|
564
|
+
self.print_heading('Reviews')
|
565
|
+
for review in self.reviews:
|
566
|
+
self.print_review(review)
|
567
|
+
|
568
|
+
def get_issues(self):
|
569
|
+
with contextlib.closing(ThreadPool(len(monorail_projects))) as pool:
|
570
|
+
monorail_issues = pool.map(
|
571
|
+
self.monorail_issue_search, monorail_projects.keys())
|
572
|
+
monorail_issues = list(itertools.chain.from_iterable(monorail_issues))
|
573
|
+
|
574
|
+
if not monorail_issues:
|
575
|
+
return
|
576
|
+
|
577
|
+
with contextlib.closing(ThreadPool(len(monorail_issues))) as pool:
|
578
|
+
filtered_issues = pool.map(
|
579
|
+
self.filter_modified_monorail_issue, monorail_issues)
|
580
|
+
self.issues = [issue for issue in filtered_issues if issue]
|
581
|
+
|
582
|
+
def get_referenced_issues(self):
|
583
|
+
if not self.issues:
|
584
|
+
self.get_issues()
|
585
|
+
|
586
|
+
if not self.changes:
|
587
|
+
self.get_changes()
|
588
|
+
|
589
|
+
referenced_issue_uids = set(itertools.chain.from_iterable(
|
590
|
+
change['bugs'] for change in self.changes))
|
591
|
+
fetched_issue_uids = set(issue['uid'] for issue in self.issues)
|
592
|
+
missing_issue_uids = referenced_issue_uids - fetched_issue_uids
|
593
|
+
|
594
|
+
missing_issues_by_project = collections.defaultdict(list)
|
595
|
+
for issue_uid in missing_issue_uids:
|
596
|
+
project, issue_id = issue_uid.split(':')
|
597
|
+
missing_issues_by_project[project].append(issue_id)
|
598
|
+
|
599
|
+
for project, issue_ids in missing_issues_by_project.items():
|
600
|
+
self.referenced_issues += self.monorail_get_issues(project, issue_ids)
|
601
|
+
|
602
|
+
def print_issues(self):
|
603
|
+
if self.issues:
|
604
|
+
self.print_heading('Issues')
|
605
|
+
for issue in self.issues:
|
606
|
+
self.print_issue(issue)
|
607
|
+
|
608
|
+
def print_changes_by_issue(self, skip_empty_own):
|
609
|
+
if not self.issues or not self.changes:
|
610
|
+
return
|
611
|
+
|
612
|
+
self.print_heading('Changes by referenced issue(s)')
|
613
|
+
issues = {issue['uid']: issue for issue in self.issues}
|
614
|
+
ref_issues = {issue['uid']: issue for issue in self.referenced_issues}
|
615
|
+
changes_by_issue_uid = collections.defaultdict(list)
|
616
|
+
changes_by_ref_issue_uid = collections.defaultdict(list)
|
617
|
+
changes_without_issue = []
|
618
|
+
for change in self.changes:
|
619
|
+
added = False
|
620
|
+
for issue_uid in change['bugs']:
|
621
|
+
if issue_uid in issues:
|
622
|
+
changes_by_issue_uid[issue_uid].append(change)
|
623
|
+
added = True
|
624
|
+
if issue_uid in ref_issues:
|
625
|
+
changes_by_ref_issue_uid[issue_uid].append(change)
|
626
|
+
added = True
|
627
|
+
if not added:
|
628
|
+
changes_without_issue.append(change)
|
629
|
+
|
630
|
+
# Changes referencing own issues.
|
631
|
+
for issue_uid in issues:
|
632
|
+
if changes_by_issue_uid[issue_uid] or not skip_empty_own:
|
633
|
+
self.print_issue(issues[issue_uid])
|
634
|
+
if changes_by_issue_uid[issue_uid]:
|
635
|
+
print()
|
636
|
+
for change in changes_by_issue_uid[issue_uid]:
|
637
|
+
print(' ', end='') # this prints no newline
|
638
|
+
self.print_change(change)
|
639
|
+
print()
|
640
|
+
|
641
|
+
# Changes referencing others' issues.
|
642
|
+
for issue_uid in ref_issues:
|
643
|
+
assert changes_by_ref_issue_uid[issue_uid]
|
644
|
+
self.print_issue(ref_issues[issue_uid])
|
645
|
+
for change in changes_by_ref_issue_uid[issue_uid]:
|
646
|
+
print('', end=' ') # this prints one space due to comma, but no newline
|
647
|
+
self.print_change(change)
|
648
|
+
|
649
|
+
# Changes referencing no issues.
|
650
|
+
if changes_without_issue:
|
651
|
+
print(self.options.output_format_no_url.format(title='Other changes'))
|
652
|
+
for change in changes_without_issue:
|
653
|
+
print('', end=' ') # this prints one space due to comma, but no newline
|
654
|
+
self.print_change(change)
|
655
|
+
|
656
|
+
def print_activity(self):
|
657
|
+
self.print_changes()
|
658
|
+
self.print_reviews()
|
659
|
+
self.print_issues()
|
660
|
+
|
661
|
+
def dump_json(self, ignore_keys=None):
|
662
|
+
if ignore_keys is None:
|
663
|
+
ignore_keys = ['replies']
|
664
|
+
|
665
|
+
def format_for_json_dump(in_array):
|
666
|
+
output = {}
|
667
|
+
for item in in_array:
|
668
|
+
url = item.get('url') or item.get('review_url')
|
669
|
+
if not url:
|
670
|
+
raise Exception('Dumped item %s does not specify url' % item)
|
671
|
+
output[url] = dict(
|
672
|
+
(k, v) for k,v in item.items() if k not in ignore_keys)
|
673
|
+
return output
|
674
|
+
|
675
|
+
class PythonObjectEncoder(json.JSONEncoder):
|
676
|
+
def default(self, obj): # pylint: disable=method-hidden
|
677
|
+
if isinstance(obj, datetime):
|
678
|
+
return obj.isoformat()
|
679
|
+
if isinstance(obj, set):
|
680
|
+
return list(obj)
|
681
|
+
return json.JSONEncoder.default(self, obj)
|
682
|
+
|
683
|
+
output = {
|
684
|
+
'reviews': format_for_json_dump(self.reviews),
|
685
|
+
'changes': format_for_json_dump(self.changes),
|
686
|
+
'issues': format_for_json_dump(self.issues)
|
687
|
+
}
|
688
|
+
print(json.dumps(output, indent=2, cls=PythonObjectEncoder))
|
689
|
+
|
690
|
+
|
691
|
+
def main():
|
692
|
+
parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
|
693
|
+
parser.add_option(
|
694
|
+
'-u', '--user', metavar='<email>',
|
695
|
+
# Look for USER and USERNAME (Windows) environment variables.
|
696
|
+
default=os.environ.get('USER', os.environ.get('USERNAME')),
|
697
|
+
help='Filter on user, default=%default')
|
698
|
+
parser.add_option(
|
699
|
+
'-b', '--begin', metavar='<date>',
|
700
|
+
help='Filter issues created after the date (mm/dd/yy)')
|
701
|
+
parser.add_option(
|
702
|
+
'-e', '--end', metavar='<date>',
|
703
|
+
help='Filter issues created before the date (mm/dd/yy)')
|
704
|
+
quarter_begin, quarter_end = get_quarter_of(datetime.today() -
|
705
|
+
relativedelta(months=2))
|
706
|
+
parser.add_option(
|
707
|
+
'-Q', '--last_quarter', action='store_true',
|
708
|
+
help='Use last quarter\'s dates, i.e. %s to %s' % (
|
709
|
+
quarter_begin.strftime('%Y-%m-%d'), quarter_end.strftime('%Y-%m-%d')))
|
710
|
+
parser.add_option(
|
711
|
+
'-Y', '--this_year', action='store_true',
|
712
|
+
help='Use this year\'s dates')
|
713
|
+
parser.add_option(
|
714
|
+
'-w', '--week_of', metavar='<date>',
|
715
|
+
help='Show issues for week of the date (mm/dd/yy)')
|
716
|
+
parser.add_option(
|
717
|
+
'-W', '--last_week', action='count',
|
718
|
+
help='Show last week\'s issues. Use more times for more weeks.')
|
719
|
+
parser.add_option(
|
720
|
+
'-a', '--auth',
|
721
|
+
action='store_true',
|
722
|
+
help='Ask to authenticate for instances with no auth cookie')
|
723
|
+
parser.add_option(
|
724
|
+
'-d', '--deltas',
|
725
|
+
action='store_true',
|
726
|
+
help='Fetch deltas for changes.')
|
727
|
+
parser.add_option(
|
728
|
+
'--no-referenced-issues',
|
729
|
+
action='store_true',
|
730
|
+
help='Do not fetch issues referenced by owned changes. Useful in '
|
731
|
+
'combination with --changes-by-issue when you only want to list '
|
732
|
+
'issues that have also been modified in the same time period.')
|
733
|
+
parser.add_option(
|
734
|
+
'--skip_servers',
|
735
|
+
action='store',
|
736
|
+
default='',
|
737
|
+
help='A comma separated list of gerrit and rietveld servers to ignore')
|
738
|
+
parser.add_option(
|
739
|
+
'--skip-own-issues-without-changes',
|
740
|
+
action='store_true',
|
741
|
+
help='Skips listing own issues without changes when showing changes '
|
742
|
+
'grouped by referenced issue(s). See --changes-by-issue for more '
|
743
|
+
'details.')
|
744
|
+
|
745
|
+
activity_types_group = optparse.OptionGroup(parser, 'Activity Types',
|
746
|
+
'By default, all activity will be looked up and '
|
747
|
+
'printed. If any of these are specified, only '
|
748
|
+
'those specified will be searched.')
|
749
|
+
activity_types_group.add_option(
|
750
|
+
'-c', '--changes',
|
751
|
+
action='store_true',
|
752
|
+
help='Show changes.')
|
753
|
+
activity_types_group.add_option(
|
754
|
+
'-i', '--issues',
|
755
|
+
action='store_true',
|
756
|
+
help='Show issues.')
|
757
|
+
activity_types_group.add_option(
|
758
|
+
'-r', '--reviews',
|
759
|
+
action='store_true',
|
760
|
+
help='Show reviews.')
|
761
|
+
activity_types_group.add_option(
|
762
|
+
'--changes-by-issue', action='store_true',
|
763
|
+
help='Show changes grouped by referenced issue(s).')
|
764
|
+
parser.add_option_group(activity_types_group)
|
765
|
+
|
766
|
+
output_format_group = optparse.OptionGroup(parser, 'Output Format',
|
767
|
+
'By default, all activity will be printed in the '
|
768
|
+
'following format: {url} {title}. This can be '
|
769
|
+
'changed for either all activity types or '
|
770
|
+
'individually for each activity type. The format '
|
771
|
+
'is defined as documented for '
|
772
|
+
'string.format(...). The variables available for '
|
773
|
+
'all activity types are url, title, author, '
|
774
|
+
'created and modified. Format options for '
|
775
|
+
'specific activity types will override the '
|
776
|
+
'generic format.')
|
777
|
+
output_format_group.add_option(
|
778
|
+
'-f', '--output-format', metavar='<format>',
|
779
|
+
default=u'{url} {title}',
|
780
|
+
help='Specifies the format to use when printing all your activity.')
|
781
|
+
output_format_group.add_option(
|
782
|
+
'--output-format-changes', metavar='<format>',
|
783
|
+
default=None,
|
784
|
+
help='Specifies the format to use when printing changes. Supports the '
|
785
|
+
'additional variable {reviewers}')
|
786
|
+
output_format_group.add_option(
|
787
|
+
'--output-format-issues', metavar='<format>',
|
788
|
+
default=None,
|
789
|
+
help='Specifies the format to use when printing issues. Supports the '
|
790
|
+
'additional variable {owner}.')
|
791
|
+
output_format_group.add_option(
|
792
|
+
'--output-format-reviews', metavar='<format>',
|
793
|
+
default=None,
|
794
|
+
help='Specifies the format to use when printing reviews.')
|
795
|
+
output_format_group.add_option(
|
796
|
+
'--output-format-heading', metavar='<format>',
|
797
|
+
default=u'{heading}:',
|
798
|
+
help='Specifies the format to use when printing headings. '
|
799
|
+
'Supports the variable {heading}.')
|
800
|
+
output_format_group.add_option(
|
801
|
+
'--output-format-no-url', default='{title}',
|
802
|
+
help='Specifies the format to use when printing activity without url.')
|
803
|
+
output_format_group.add_option(
|
804
|
+
'-m', '--markdown', action='store_true',
|
805
|
+
help='Use markdown-friendly output (overrides --output-format '
|
806
|
+
'and --output-format-heading)')
|
807
|
+
output_format_group.add_option(
|
808
|
+
'-j', '--json', action='store_true',
|
809
|
+
help='Output json data (overrides other format options)')
|
810
|
+
parser.add_option_group(output_format_group)
|
811
|
+
|
812
|
+
parser.add_option(
|
813
|
+
'-v', '--verbose',
|
814
|
+
action='store_const',
|
815
|
+
dest='verbosity',
|
816
|
+
default=logging.WARN,
|
817
|
+
const=logging.INFO,
|
818
|
+
help='Output extra informational messages.'
|
819
|
+
)
|
820
|
+
parser.add_option(
|
821
|
+
'-q', '--quiet',
|
822
|
+
action='store_const',
|
823
|
+
dest='verbosity',
|
824
|
+
const=logging.ERROR,
|
825
|
+
help='Suppress non-error messages.'
|
826
|
+
)
|
827
|
+
parser.add_option(
|
828
|
+
'-M', '--merged-only',
|
829
|
+
action='store_true',
|
830
|
+
dest='merged_only',
|
831
|
+
default=False,
|
832
|
+
help='Shows only changes that have been merged.')
|
833
|
+
parser.add_option(
|
834
|
+
'-C', '--completed-issues',
|
835
|
+
action='store_true',
|
836
|
+
dest='completed_issues',
|
837
|
+
default=False,
|
838
|
+
help='Shows only monorail issues that have completed (Fixed|Verified) '
|
839
|
+
'by the user.')
|
840
|
+
parser.add_option(
|
841
|
+
'-o', '--output', metavar='<file>',
|
842
|
+
help='Where to output the results. By default prints to stdout.')
|
843
|
+
|
844
|
+
# Remove description formatting
|
845
|
+
parser.format_description = (
|
846
|
+
lambda _: parser.description) # pylint: disable=no-member
|
847
|
+
|
848
|
+
options, args = parser.parse_args()
|
849
|
+
options.local_user = os.environ.get('USER')
|
850
|
+
if args:
|
851
|
+
parser.error('Args unsupported')
|
852
|
+
if not options.user:
|
853
|
+
parser.error('USER/USERNAME is not set, please use -u')
|
854
|
+
# Retains the original -u option as the email address.
|
855
|
+
options.email = options.user
|
856
|
+
options.user = username(options.email)
|
857
|
+
|
858
|
+
logging.basicConfig(level=options.verbosity)
|
859
|
+
|
860
|
+
# python-keyring provides easy access to the system keyring.
|
861
|
+
try:
|
862
|
+
import keyring # pylint: disable=unused-import,unused-variable,F0401
|
863
|
+
except ImportError:
|
864
|
+
logging.warning('Consider installing python-keyring')
|
865
|
+
|
866
|
+
if not options.begin:
|
867
|
+
if options.last_quarter:
|
868
|
+
begin, end = quarter_begin, quarter_end
|
869
|
+
elif options.this_year:
|
870
|
+
begin, end = get_year_of(datetime.today())
|
871
|
+
elif options.week_of:
|
872
|
+
begin, end = (get_week_of(datetime.strptime(options.week_of, '%m/%d/%y')))
|
873
|
+
elif options.last_week:
|
874
|
+
begin, end = (get_week_of(datetime.today() -
|
875
|
+
timedelta(days=1 + 7 * options.last_week)))
|
876
|
+
else:
|
877
|
+
begin, end = (get_week_of(datetime.today() - timedelta(days=1)))
|
878
|
+
else:
|
879
|
+
begin = dateutil.parser.parse(options.begin)
|
880
|
+
if options.end:
|
881
|
+
end = dateutil.parser.parse(options.end)
|
882
|
+
else:
|
883
|
+
end = datetime.today()
|
884
|
+
options.begin, options.end = begin, end
|
885
|
+
if begin >= end:
|
886
|
+
# The queries fail in peculiar ways when the begin date is in the future.
|
887
|
+
# Give a descriptive error message instead.
|
888
|
+
logging.error('Start date (%s) is the same or later than end date (%s)' %
|
889
|
+
(begin, end))
|
890
|
+
return 1
|
891
|
+
|
892
|
+
if options.markdown:
|
893
|
+
options.output_format_heading = '### {heading}\n'
|
894
|
+
options.output_format = ' * [{title}]({url})'
|
895
|
+
options.output_format_no_url = ' * {title}'
|
896
|
+
logging.info('Searching for activity by %s', options.user)
|
897
|
+
logging.info('Using range %s to %s', options.begin, options.end)
|
898
|
+
|
899
|
+
my_activity = MyActivity(options)
|
900
|
+
my_activity.show_progress('Loading data')
|
901
|
+
|
902
|
+
if not (options.changes or options.reviews or options.issues or
|
903
|
+
options.changes_by_issue):
|
904
|
+
options.changes = True
|
905
|
+
options.issues = True
|
906
|
+
options.reviews = True
|
907
|
+
|
908
|
+
# First do any required authentication so none of the user interaction has to
|
909
|
+
# wait for actual work.
|
910
|
+
if options.changes or options.changes_by_issue:
|
911
|
+
my_activity.auth_for_changes()
|
912
|
+
if options.reviews:
|
913
|
+
my_activity.auth_for_reviews()
|
914
|
+
|
915
|
+
logging.info('Looking up activity.....')
|
916
|
+
|
917
|
+
try:
|
918
|
+
if options.changes or options.changes_by_issue:
|
919
|
+
my_activity.get_changes()
|
920
|
+
if options.reviews:
|
921
|
+
my_activity.get_reviews()
|
922
|
+
if options.issues or options.changes_by_issue:
|
923
|
+
my_activity.get_issues()
|
924
|
+
if not options.no_referenced_issues:
|
925
|
+
my_activity.get_referenced_issues()
|
926
|
+
except auth.LoginRequiredError as e:
|
927
|
+
logging.error('auth.LoginRequiredError: %s', e)
|
928
|
+
|
929
|
+
my_activity.show_progress('\n')
|
930
|
+
|
931
|
+
my_activity.print_access_errors()
|
932
|
+
|
933
|
+
output_file = None
|
934
|
+
try:
|
935
|
+
if options.output:
|
936
|
+
output_file = open(options.output, 'w')
|
937
|
+
logging.info('Printing output to "%s"', options.output)
|
938
|
+
sys.stdout = output_file
|
939
|
+
except (IOError, OSError) as e:
|
940
|
+
logging.error('Unable to write output: %s', e)
|
941
|
+
else:
|
942
|
+
if options.json:
|
943
|
+
my_activity.dump_json()
|
944
|
+
else:
|
945
|
+
if options.changes:
|
946
|
+
my_activity.print_changes()
|
947
|
+
if options.reviews:
|
948
|
+
my_activity.print_reviews()
|
949
|
+
if options.issues:
|
950
|
+
my_activity.print_issues()
|
951
|
+
if options.changes_by_issue:
|
952
|
+
my_activity.print_changes_by_issue(
|
953
|
+
options.skip_own_issues_without_changes)
|
954
|
+
finally:
|
955
|
+
if output_file:
|
956
|
+
logging.info('Done printing to file.')
|
957
|
+
sys.stdout = sys.__stdout__
|
958
|
+
output_file.close()
|
959
|
+
|
960
|
+
return 0
|
961
|
+
|
962
|
+
|
963
|
+
if __name__ == '__main__':
|
964
|
+
# Fix encoding to support non-ascii issue titles.
|
965
|
+
fix_encoding.fix_encoding()
|
966
|
+
|
967
|
+
try:
|
968
|
+
sys.exit(main())
|
969
|
+
except KeyboardInterrupt:
|
970
|
+
sys.stderr.write('interrupted\n')
|
971
|
+
sys.exit(1)
|