forked from mirrors/gecko-dev
Bug 1784232 - Bump taskgraph to v3.2.0 r=ahal
Differential Revision: https://phabricator.services.mozilla.com/D155978
This commit is contained in:
parent
35f28283e0
commit
0e57af4969
63 changed files with 2402 additions and 550 deletions
|
|
@ -37,7 +37,7 @@
|
||||||
#
|
#
|
||||||
# {
|
# {
|
||||||
# tasks_for: 'action',
|
# tasks_for: 'action',
|
||||||
# push: {owner, pushlog_id, revision},
|
# push: {owner, pushlog_id, revision, base_revision},
|
||||||
# repository: {url, project, level},
|
# repository: {url, project, level},
|
||||||
# input,
|
# input,
|
||||||
# taskId, // targetted taskId
|
# taskId, // targetted taskId
|
||||||
|
|
@ -196,6 +196,7 @@ tasks:
|
||||||
# to `mach taskgraph decision` are all on the command line.
|
# to `mach taskgraph decision` are all on the command line.
|
||||||
$merge:
|
$merge:
|
||||||
- GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
|
- GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
|
||||||
|
GECKO_BASE_REV: '${push.base_revision}'
|
||||||
GECKO_HEAD_REPOSITORY: '${repoUrl}'
|
GECKO_HEAD_REPOSITORY: '${repoUrl}'
|
||||||
GECKO_HEAD_REF: '${push.revision}'
|
GECKO_HEAD_REF: '${push.revision}'
|
||||||
GECKO_HEAD_REV: '${push.revision}'
|
GECKO_HEAD_REV: '${push.revision}'
|
||||||
|
|
@ -253,6 +254,7 @@ tasks:
|
||||||
--tasks-for='${tasks_for}'
|
--tasks-for='${tasks_for}'
|
||||||
--repository-type=hg
|
--repository-type=hg
|
||||||
--base-repository="$GECKO_BASE_REPOSITORY"
|
--base-repository="$GECKO_BASE_REPOSITORY"
|
||||||
|
--base-rev="$GECKO_BASE_REV"
|
||||||
--head-repository="$GECKO_HEAD_REPOSITORY"
|
--head-repository="$GECKO_HEAD_REPOSITORY"
|
||||||
--head-ref="$GECKO_HEAD_REF"
|
--head-ref="$GECKO_HEAD_REF"
|
||||||
--head-rev="$GECKO_HEAD_REV"
|
--head-rev="$GECKO_HEAD_REV"
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ vendored:third_party/python/ecdsa
|
||||||
vendored:third_party/python/esprima
|
vendored:third_party/python/esprima
|
||||||
vendored:third_party/python/fluent.migrate
|
vendored:third_party/python/fluent.migrate
|
||||||
vendored:third_party/python/fluent.syntax
|
vendored:third_party/python/fluent.syntax
|
||||||
|
vendored:third_party/python/giturlparse
|
||||||
vendored:third_party/python/gyp/pylib
|
vendored:third_party/python/gyp/pylib
|
||||||
vendored:third_party/python/idna
|
vendored:third_party/python/idna
|
||||||
vendored:third_party/python/idna-ssl
|
vendored:third_party/python/idna-ssl
|
||||||
|
|
@ -87,6 +88,7 @@ vendored:third_party/python/jsonschema
|
||||||
vendored:third_party/python/looseversion
|
vendored:third_party/python/looseversion
|
||||||
vendored:third_party/python/MarkupSafe/src
|
vendored:third_party/python/MarkupSafe/src
|
||||||
vendored:third_party/python/mohawk
|
vendored:third_party/python/mohawk
|
||||||
|
vendored:third_party/python/mozilla_repo_urls
|
||||||
vendored:third_party/python/mozilla_version
|
vendored:third_party/python/mozilla_version
|
||||||
vendored:third_party/python/multidict
|
vendored:third_party/python/multidict
|
||||||
vendored:third_party/python/packaging
|
vendored:third_party/python/packaging
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,15 @@ Push Information
|
||||||
``base_repository`` in cases where ``base_repository`` is likely to be cached
|
``base_repository`` in cases where ``base_repository`` is likely to be cached
|
||||||
and only a few additional commits are needed from ``head_repository``.
|
and only a few additional commits are needed from ``head_repository``.
|
||||||
|
|
||||||
|
``base_rev``
|
||||||
|
The previous revision before ``head_rev`` got merged into. This can be a short revision string.
|
||||||
|
|
||||||
``head_rev``
|
``head_rev``
|
||||||
The revision to check out; this can be a short revision string
|
The revision to check out; this can be a short revision string
|
||||||
|
|
||||||
|
``base_ref``
|
||||||
|
Reference where ``head_rev`` got merged into. It is usually a branch or a tag.
|
||||||
|
|
||||||
``head_ref``
|
``head_ref``
|
||||||
For Mercurial repositories, this is the same as ``head_rev``. For
|
For Mercurial repositories, this is the same as ``head_rev``. For
|
||||||
git repositories, which do not allow pulling explicit revisions, this gives
|
git repositories, which do not allow pulling explicit revisions, this gives
|
||||||
|
|
|
||||||
|
|
@ -183,10 +183,14 @@ def register_callback_action(
|
||||||
revision = parameters[
|
revision = parameters[
|
||||||
"{}head_rev".format(graph_config["project-repo-param-prefix"])
|
"{}head_rev".format(graph_config["project-repo-param-prefix"])
|
||||||
]
|
]
|
||||||
|
base_revision = parameters[
|
||||||
|
"{}base_rev".format(graph_config["project-repo-param-prefix"])
|
||||||
|
]
|
||||||
push = {
|
push = {
|
||||||
"owner": "mozilla-taskcluster-maintenance@mozilla.com",
|
"owner": "mozilla-taskcluster-maintenance@mozilla.com",
|
||||||
"pushlog_id": parameters["pushlog_id"],
|
"pushlog_id": parameters["pushlog_id"],
|
||||||
"revision": revision,
|
"revision": revision,
|
||||||
|
"base_revision": base_revision,
|
||||||
}
|
}
|
||||||
|
|
||||||
match = re.match(
|
match = re.match(
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,19 @@ import yaml
|
||||||
from redo import retry
|
from redo import retry
|
||||||
from taskgraph import create
|
from taskgraph import create
|
||||||
from taskgraph.create import create_tasks
|
from taskgraph.create import create_tasks
|
||||||
|
from taskgraph.decision import (
|
||||||
|
# TODO: Let standalone taskgraph generate parameters instead
|
||||||
|
# of calling internals
|
||||||
|
_determine_more_accurate_base_ref,
|
||||||
|
_determine_more_accurate_base_rev,
|
||||||
|
_get_env_prefix,
|
||||||
|
)
|
||||||
from taskgraph.parameters import Parameters
|
from taskgraph.parameters import Parameters
|
||||||
from taskgraph.taskgraph import TaskGraph
|
from taskgraph.taskgraph import TaskGraph
|
||||||
from taskgraph.util.python_path import find_object
|
from taskgraph.util.python_path import find_object
|
||||||
from taskgraph.util.schema import Schema, validate_schema
|
from taskgraph.util.schema import Schema, validate_schema
|
||||||
from taskgraph.util.taskcluster import get_artifact
|
from taskgraph.util.taskcluster import get_artifact
|
||||||
|
from taskgraph.util.vcs import get_repository
|
||||||
from taskgraph.util.yaml import load_yaml
|
from taskgraph.util.yaml import load_yaml
|
||||||
from voluptuous import Any, Optional, Required
|
from voluptuous import Any, Optional, Required
|
||||||
|
|
||||||
|
|
@ -283,6 +291,8 @@ def get_decision_parameters(graph_config, options):
|
||||||
n: options[n]
|
n: options[n]
|
||||||
for n in [
|
for n in [
|
||||||
"base_repository",
|
"base_repository",
|
||||||
|
"base_ref",
|
||||||
|
"base_rev",
|
||||||
"head_repository",
|
"head_repository",
|
||||||
"head_rev",
|
"head_rev",
|
||||||
"head_ref",
|
"head_ref",
|
||||||
|
|
@ -310,6 +320,23 @@ def get_decision_parameters(graph_config, options):
|
||||||
|
|
||||||
commit_message = get_hg_commit_message(os.path.join(GECKO, product_dir))
|
commit_message = get_hg_commit_message(os.path.join(GECKO, product_dir))
|
||||||
|
|
||||||
|
repo_path = os.getcwd()
|
||||||
|
repo = get_repository(repo_path)
|
||||||
|
parameters["base_ref"] = _determine_more_accurate_base_ref(
|
||||||
|
repo,
|
||||||
|
candidate_base_ref=options.get("base_ref"),
|
||||||
|
head_ref=options.get("head_ref"),
|
||||||
|
base_rev=options.get("base_rev"),
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters["base_rev"] = _determine_more_accurate_base_rev(
|
||||||
|
repo,
|
||||||
|
base_ref=parameters["base_ref"],
|
||||||
|
candidate_base_rev=options.get("base_rev"),
|
||||||
|
head_rev=options.get("head_rev"),
|
||||||
|
env_prefix=_get_env_prefix(graph_config),
|
||||||
|
)
|
||||||
|
|
||||||
# Define default filter list, as most configurations shouldn't need
|
# Define default filter list, as most configurations shouldn't need
|
||||||
# custom filters.
|
# custom filters.
|
||||||
parameters["filters"] = [
|
parameters["filters"] = [
|
||||||
|
|
|
||||||
|
|
@ -595,6 +595,15 @@ def image_digest(args):
|
||||||
help='Type of repository, either "hg" or "git"',
|
help='Type of repository, either "hg" or "git"',
|
||||||
)
|
)
|
||||||
@argument("--base-repository", required=True, help='URL for "base" repository to clone')
|
@argument("--base-repository", required=True, help='URL for "base" repository to clone')
|
||||||
|
@argument(
|
||||||
|
"--base-ref", default="", help='Reference of the revision in the "base" repository'
|
||||||
|
)
|
||||||
|
@argument(
|
||||||
|
"--base-rev",
|
||||||
|
default="",
|
||||||
|
help="Taskgraph decides what to do based on the revision range between "
|
||||||
|
"`--base-rev` and `--head-rev`. Value is determined automatically if not provided",
|
||||||
|
)
|
||||||
@argument(
|
@argument(
|
||||||
"--head-repository",
|
"--head-repository",
|
||||||
required=True,
|
required=True,
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,12 @@ class TestGetDecisionParameters(unittest.TestCase):
|
||||||
}
|
}
|
||||||
|
|
||||||
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
||||||
def test_simple_options(self, mock_get_hg_revision_branch):
|
@patch("gecko_taskgraph.decision._determine_more_accurate_base_rev")
|
||||||
|
def test_simple_options(
|
||||||
|
self, mock_determine_more_accurate_base_rev, mock_get_hg_revision_branch
|
||||||
|
):
|
||||||
mock_get_hg_revision_branch.return_value = "default"
|
mock_get_hg_revision_branch.return_value = "default"
|
||||||
|
mock_determine_more_accurate_base_rev.return_value = "baserev"
|
||||||
with MockedOpen({self.ttc_file: None}):
|
with MockedOpen({self.ttc_file: None}):
|
||||||
params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
|
params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
|
||||||
self.assertEqual(params["pushlog_id"], "143")
|
self.assertEqual(params["pushlog_id"], "143")
|
||||||
|
|
@ -88,8 +92,12 @@ class TestGetDecisionParameters(unittest.TestCase):
|
||||||
self.assertEqual(params["try_task_config"], {})
|
self.assertEqual(params["try_task_config"], {})
|
||||||
|
|
||||||
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
||||||
def test_no_email_owner(self, mock_get_hg_revision_branch):
|
@patch("gecko_taskgraph.decision._determine_more_accurate_base_rev")
|
||||||
|
def test_no_email_owner(
|
||||||
|
self, mock_determine_more_accurate_base_rev, mock_get_hg_revision_branch
|
||||||
|
):
|
||||||
mock_get_hg_revision_branch.return_value = "default"
|
mock_get_hg_revision_branch.return_value = "default"
|
||||||
|
mock_determine_more_accurate_base_rev.return_value = "baserev"
|
||||||
self.options["owner"] = "ffxbld"
|
self.options["owner"] = "ffxbld"
|
||||||
with MockedOpen({self.ttc_file: None}):
|
with MockedOpen({self.ttc_file: None}):
|
||||||
params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
|
params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
|
||||||
|
|
@ -97,9 +105,16 @@ class TestGetDecisionParameters(unittest.TestCase):
|
||||||
|
|
||||||
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
||||||
@patch("gecko_taskgraph.decision.get_hg_commit_message")
|
@patch("gecko_taskgraph.decision.get_hg_commit_message")
|
||||||
def test_try_options(self, mock_get_hg_commit_message, mock_get_hg_revision_branch):
|
@patch("gecko_taskgraph.decision._determine_more_accurate_base_rev")
|
||||||
|
def test_try_options(
|
||||||
|
self,
|
||||||
|
mock_determine_more_accurate_base_rev,
|
||||||
|
mock_get_hg_commit_message,
|
||||||
|
mock_get_hg_revision_branch,
|
||||||
|
):
|
||||||
mock_get_hg_commit_message.return_value = "try: -b do -t all --artifact"
|
mock_get_hg_commit_message.return_value = "try: -b do -t all --artifact"
|
||||||
mock_get_hg_revision_branch.return_value = "default"
|
mock_get_hg_revision_branch.return_value = "default"
|
||||||
|
mock_determine_more_accurate_base_rev.return_value = "baserev"
|
||||||
self.options["project"] = "try"
|
self.options["project"] = "try"
|
||||||
with MockedOpen({self.ttc_file: None}):
|
with MockedOpen({self.ttc_file: None}):
|
||||||
params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
|
params = decision.get_decision_parameters(FAKE_GRAPH_CONFIG, self.options)
|
||||||
|
|
@ -117,11 +132,16 @@ class TestGetDecisionParameters(unittest.TestCase):
|
||||||
|
|
||||||
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
@patch("gecko_taskgraph.decision.get_hg_revision_branch")
|
||||||
@patch("gecko_taskgraph.decision.get_hg_commit_message")
|
@patch("gecko_taskgraph.decision.get_hg_commit_message")
|
||||||
|
@patch("gecko_taskgraph.decision._determine_more_accurate_base_rev")
|
||||||
def test_try_task_config(
|
def test_try_task_config(
|
||||||
self, mock_get_hg_commit_message, mock_get_hg_revision_branch
|
self,
|
||||||
|
mock_get_hg_commit_message,
|
||||||
|
mock_get_hg_revision_branch,
|
||||||
|
mock_determine_more_accurate_base_rev,
|
||||||
):
|
):
|
||||||
mock_get_hg_commit_message.return_value = "Fuzzy query=foo"
|
mock_get_hg_commit_message.return_value = "Fuzzy query=foo"
|
||||||
mock_get_hg_revision_branch.return_value = "default"
|
mock_get_hg_revision_branch.return_value = "default"
|
||||||
|
mock_determine_more_accurate_base_rev.return_value = "baserev"
|
||||||
ttc = {"tasks": ["a", "b"]}
|
ttc = {"tasks": ["a", "b"]}
|
||||||
self.options["project"] = "try"
|
self.options["project"] = "try"
|
||||||
with MockedOpen({self.ttc_file: json.dumps(ttc)}):
|
with MockedOpen({self.ttc_file: json.dumps(ttc)}):
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ class TestTaskclusterYml(unittest.TestCase):
|
||||||
"tasks_for": "hg-push",
|
"tasks_for": "hg-push",
|
||||||
"push": {
|
"push": {
|
||||||
"revision": "e8d2d9aff5026ef1f1777b781b47fdcbdb9d8f20",
|
"revision": "e8d2d9aff5026ef1f1777b781b47fdcbdb9d8f20",
|
||||||
|
"base_revision": "e8aebe488b2f2e567940577de25013d00e818f7c",
|
||||||
"owner": "dustin@mozilla.com",
|
"owner": "dustin@mozilla.com",
|
||||||
"pushlog_id": 1556565286,
|
"pushlog_id": 1556565286,
|
||||||
"pushdate": 112957,
|
"pushdate": 112957,
|
||||||
|
|
@ -51,6 +52,7 @@ class TestTaskclusterYml(unittest.TestCase):
|
||||||
},
|
},
|
||||||
"push": {
|
"push": {
|
||||||
"revision": "e8aebe488b2f2e567940577de25013d00e818f7c",
|
"revision": "e8aebe488b2f2e567940577de25013d00e818f7c",
|
||||||
|
"base_revision": "54cbb3745cdb9a8aa0a4428d405b3b2e1c7d13c2",
|
||||||
"pushlog_id": -1,
|
"pushlog_id": -1,
|
||||||
"pushdate": 0,
|
"pushdate": 0,
|
||||||
"owner": "cron",
|
"owner": "cron",
|
||||||
|
|
@ -80,6 +82,7 @@ class TestTaskclusterYml(unittest.TestCase):
|
||||||
},
|
},
|
||||||
"push": {
|
"push": {
|
||||||
"revision": "e8d2d9aff5026ef1f1777b781b47fdcbdb9d8f20",
|
"revision": "e8d2d9aff5026ef1f1777b781b47fdcbdb9d8f20",
|
||||||
|
"base_revision": "e8aebe488b2f2e567940577de25013d00e818f7c",
|
||||||
"owner": "dustin@mozilla.com",
|
"owner": "dustin@mozilla.com",
|
||||||
"pushlog_id": 1556565286,
|
"pushlog_id": 1556565286,
|
||||||
"pushdate": 112957,
|
"pushdate": 112957,
|
||||||
|
|
|
||||||
191
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/LICENSE
vendored
Normal file
191
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,191 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, and
|
||||||
|
distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||||
|
owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||||
|
that control, are controlled by, or are under common control with that entity.
|
||||||
|
For the purposes of this definition, "control" means (i) the power, direct or
|
||||||
|
indirect, to cause the direction or management of such entity, whether by
|
||||||
|
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||||
|
permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, including
|
||||||
|
but not limited to software source code, documentation source, and configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation or
|
||||||
|
translation of a Source form, including but not limited to compiled object code,
|
||||||
|
generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||||
|
available under the License, as indicated by a copyright notice that is included
|
||||||
|
in or attached to the work (an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||||
|
is based on (or derived from) the Work and for which the editorial revisions,
|
||||||
|
annotations, elaborations, or other modifications represent, as a whole, an
|
||||||
|
original work of authorship. For the purposes of this License, Derivative Works
|
||||||
|
shall not include works that remain separable from, or merely link (or bind by
|
||||||
|
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the original version
|
||||||
|
of the Work and any modifications or additions to that Work or Derivative Works
|
||||||
|
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||||
|
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||||
|
on behalf of the copyright owner. For the purposes of this definition,
|
||||||
|
"submitted" means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems, and
|
||||||
|
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||||
|
the purpose of discussing and improving the Work, but excluding communication
|
||||||
|
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||||
|
of whom a Contribution has been received by Licensor and subsequently
|
||||||
|
incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License.
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby
|
||||||
|
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||||
|
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||||
|
Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License.
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby
|
||||||
|
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||||
|
irrevocable (except as stated in this section) patent license to make, have
|
||||||
|
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||||
|
such license applies only to those patent claims licensable by such Contributor
|
||||||
|
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||||
|
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||||
|
submitted. If You institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||||
|
Contribution incorporated within the Work constitutes direct or contributory
|
||||||
|
patent infringement, then any patent licenses granted to You under this License
|
||||||
|
for that Work shall terminate as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution.
|
||||||
|
|
||||||
|
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||||
|
in any medium, with or without modifications, and in Source or Object form,
|
||||||
|
provided that You meet the following conditions:
|
||||||
|
|
||||||
|
You must give any other recipients of the Work or Derivative Works a copy of
|
||||||
|
this License; and
|
||||||
|
You must cause any modified files to carry prominent notices stating that You
|
||||||
|
changed the files; and
|
||||||
|
You must retain, in the Source form of any Derivative Works that You distribute,
|
||||||
|
all copyright, patent, trademark, and attribution notices from the Source form
|
||||||
|
of the Work, excluding those notices that do not pertain to any part of the
|
||||||
|
Derivative Works; and
|
||||||
|
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||||
|
Derivative Works that You distribute must include a readable copy of the
|
||||||
|
attribution notices contained within such NOTICE file, excluding those notices
|
||||||
|
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||||
|
following places: within a NOTICE text file distributed as part of the
|
||||||
|
Derivative Works; within the Source form or documentation, if provided along
|
||||||
|
with the Derivative Works; or, within a display generated by the Derivative
|
||||||
|
Works, if and wherever such third-party notices normally appear. The contents of
|
||||||
|
the NOTICE file are for informational purposes only and do not modify the
|
||||||
|
License. You may add Your own attribution notices within Derivative Works that
|
||||||
|
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||||
|
provided that such additional attribution notices cannot be construed as
|
||||||
|
modifying the License.
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide
|
||||||
|
additional or different license terms and conditions for use, reproduction, or
|
||||||
|
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||||
|
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||||
|
with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions.
|
||||||
|
|
||||||
|
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||||
|
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||||
|
conditions of this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||||
|
any separate license agreement you may have executed with Licensor regarding
|
||||||
|
such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks.
|
||||||
|
|
||||||
|
This License does not grant permission to use the trade names, trademarks,
|
||||||
|
service marks, or product names of the Licensor, except as required for
|
||||||
|
reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||||
|
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||||
|
including, without limitation, any warranties or conditions of TITLE,
|
||||||
|
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||||
|
solely responsible for determining the appropriateness of using or
|
||||||
|
redistributing the Work and assume any risks associated with Your exercise of
|
||||||
|
permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability.
|
||||||
|
|
||||||
|
In no event and under no legal theory, whether in tort (including negligence),
|
||||||
|
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||||
|
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special, incidental,
|
||||||
|
or consequential damages of any character arising as a result of this License or
|
||||||
|
out of the use or inability to use the Work (including but not limited to
|
||||||
|
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||||
|
any and all other commercial damages or losses), even if such Contributor has
|
||||||
|
been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability.
|
||||||
|
|
||||||
|
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||||
|
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||||
|
other liability obligations and/or rights consistent with this License. However,
|
||||||
|
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||||
|
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||||
|
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason of your
|
||||||
|
accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following boilerplate
|
||||||
|
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||||
|
identifying information. (Don't include the brackets!) The text should be
|
||||||
|
enclosed in the appropriate comment syntax for the file format. We also
|
||||||
|
recommend that a file or class name and description of purpose be included on
|
||||||
|
the same "printed page" as the copyright notice for easier identification within
|
||||||
|
third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
165
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/METADATA
vendored
Normal file
165
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/METADATA
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
Metadata-Version: 2.1
|
||||||
|
Name: giturlparse
|
||||||
|
Version: 0.10.0
|
||||||
|
Summary: A Git URL parsing module (supports parsing and rewriting)
|
||||||
|
Home-page: https://github.com/nephila/giturlparse
|
||||||
|
Author: Aaron O Mullan
|
||||||
|
Author-email: aaron@friendco.de
|
||||||
|
Maintainer: Iacopo Spalletti
|
||||||
|
Maintainer-email: i.spalletti@nephila.it
|
||||||
|
License: Apache v2
|
||||||
|
Keywords: giturlparse
|
||||||
|
Platform: UNKNOWN
|
||||||
|
Classifier: Development Status :: 5 - Production/Stable
|
||||||
|
Classifier: Framework :: Django
|
||||||
|
Classifier: Intended Audience :: Developers
|
||||||
|
Classifier: License :: OSI Approved :: Apache Software License
|
||||||
|
Classifier: Natural Language :: English
|
||||||
|
Classifier: Programming Language :: Python :: 3.6
|
||||||
|
Classifier: Programming Language :: Python :: 3.7
|
||||||
|
Requires-Python: >=3.6
|
||||||
|
Description-Content-Type: text/x-rst
|
||||||
|
|
||||||
|
===========
|
||||||
|
giturlparse
|
||||||
|
===========
|
||||||
|
|
||||||
|
Parse & rewrite git urls (supports GitHub, Bitbucket, FriendCode, Assembla, Gitlab ...)
|
||||||
|
|
||||||
|
This is a fork of giturlparse.py with updated parsers.
|
||||||
|
|
||||||
|
Original project can be found at https://github.com/FriendCode/giturlparse.py
|
||||||
|
|
||||||
|
************
|
||||||
|
Installing
|
||||||
|
************
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pip install giturlparse
|
||||||
|
|
||||||
|
******************
|
||||||
|
Examples
|
||||||
|
******************
|
||||||
|
|
||||||
|
Exposed attributes
|
||||||
|
==================
|
||||||
|
|
||||||
|
* ``platform``: platform codename
|
||||||
|
* ``host``: server hostname
|
||||||
|
* ``resource``: same as ``host``
|
||||||
|
* ``port``: URL port (only if explicitly defined in URL)
|
||||||
|
* ``protocol``: URL protocol (git, ssh, http/https)
|
||||||
|
* ``protocols``: list of protocols explicitly defined in URL
|
||||||
|
* ``user``: repository user
|
||||||
|
* ``owner``: repository owner (user or organization)
|
||||||
|
* ``repo``: repository name
|
||||||
|
* ``name``: same as ``repo``
|
||||||
|
* ``groups``: list of groups - gitlab only
|
||||||
|
* ``path``: path to file or directory (includes the branch name) - gitlab / github only
|
||||||
|
* ``path_raw``: raw path starting from the repo name (might include platform keyword) - gitlab / github only
|
||||||
|
* ``branch``: branch name (when parseable) - gitlab / github only
|
||||||
|
|
||||||
|
Parse
|
||||||
|
==================
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from giturlparse import parse
|
||||||
|
|
||||||
|
p = parse('git@bitbucket.org:AaronO/some-repo.git')
|
||||||
|
|
||||||
|
p.host, p.owner, p.repo
|
||||||
|
|
||||||
|
# => ('bitbucket.org', 'AaronO', 'some-repo')
|
||||||
|
|
||||||
|
|
||||||
|
Rewrite
|
||||||
|
==================
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from giturlparse import parse
|
||||||
|
|
||||||
|
url = 'git@github.com:Org/Private-repo.git'
|
||||||
|
|
||||||
|
p = parse(url)
|
||||||
|
|
||||||
|
p.url2ssh, p.url2https, p.url2git, p.url2http
|
||||||
|
# => ('git@github.com:Org/Private-repo.git', 'https://github.com/Org/Private-repo.git', 'git://github.com/Org/Private-repo.git', None)
|
||||||
|
|
||||||
|
URLS
|
||||||
|
==================
|
||||||
|
|
||||||
|
Alternative URLs for same repo::
|
||||||
|
|
||||||
|
from giturlparse import parse
|
||||||
|
|
||||||
|
url = 'git@github.com:Org/Private-repo.git'
|
||||||
|
|
||||||
|
parse(url).urls
|
||||||
|
# => {
|
||||||
|
# 'ssh': 'git@github.com:Org/Private-repo.git',
|
||||||
|
# 'https': 'https://github.com/Org/Private-repo.git',
|
||||||
|
# 'git': 'git://github.com/Org/Private-repo.git'
|
||||||
|
# }
|
||||||
|
|
||||||
|
Validate
|
||||||
|
==================
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from giturlparse import parse, validate
|
||||||
|
|
||||||
|
url = 'git@github.com:Org/Private-repo.git'
|
||||||
|
|
||||||
|
parse(url).valid
|
||||||
|
# => True
|
||||||
|
|
||||||
|
# Or
|
||||||
|
|
||||||
|
validate(url)
|
||||||
|
# => True
|
||||||
|
|
||||||
|
Tests
|
||||||
|
==================
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
python setup.py test
|
||||||
|
|
||||||
|
License
|
||||||
|
==================
|
||||||
|
|
||||||
|
Apache v2 (Check out LICENSE file)
|
||||||
|
|
||||||
|
.. :changelog:
|
||||||
|
|
||||||
|
*******
|
||||||
|
History
|
||||||
|
*******
|
||||||
|
|
||||||
|
.. towncrier release notes start
|
||||||
|
|
||||||
|
0.10.0 (2020-12-05)
|
||||||
|
===================
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- General matching improvements (#18)
|
||||||
|
- Update tooling, drop python2 (#10213)
|
||||||
|
|
||||||
|
0.9.2 (2018-10-27)
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Removed "s" from the base platform regex
|
||||||
|
* Fix license classifier in setup.py
|
||||||
|
* Update meta files
|
||||||
|
|
||||||
|
0.9.1 (2018-01-20)
|
||||||
|
==================
|
||||||
|
|
||||||
|
* First fork release
|
||||||
|
|
||||||
|
|
||||||
18
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/RECORD
vendored
Normal file
18
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/RECORD
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
giturlparse/__init__.py,sha256=c5WMm7u1auWiuJrsY0bo1IsT6iRi8b6pGebNQC03_PI,332
|
||||||
|
giturlparse/parser.py,sha256=BTaOH--z1-odYdOwEb5iNadYpCvUM4-bKHYXGKxGIZM,1924
|
||||||
|
giturlparse/result.py,sha256=wKg1h9vYXkPseRgEAIk8TDPS1UMIU_z3t4IKbT7uD18,2765
|
||||||
|
giturlparse/platforms/__init__.py,sha256=y8xzQWxqGHwlvx0pY99Hqott-xK2Q0iBzpQ9dTehTrY,527
|
||||||
|
giturlparse/platforms/assembla.py,sha256=iPYpPOu8cNapbniD7sj63aTwPGT4DUH1U8RkvbUkiqE,498
|
||||||
|
giturlparse/platforms/base.py,sha256=cZPxEa1u1WNq6IvhUVp3XWJtks9Dy2sifDaJAdeHclI,1566
|
||||||
|
giturlparse/platforms/bitbucket.py,sha256=R6dsFBhuMlLe9-gIAP7X8hzJn-FHAjI-bBgnfNom4tc,680
|
||||||
|
giturlparse/platforms/friendcode.py,sha256=w__PNSQAkNO2Y45doOw7YMDqwuSyu_FocQTRa305VM0,389
|
||||||
|
giturlparse/platforms/github.py,sha256=G_7VRQpm5ZtvOcc1xbVF3CnC4AcCRnyK7EgkoaoqOEo,1446
|
||||||
|
giturlparse/platforms/gitlab.py,sha256=2K65zlI8CA5OdXV9eXW3SBFH7oW78lFlkhLviW3Mwyo,1794
|
||||||
|
giturlparse/tests/__init__.py,sha256=yBGT6Ycwx1AsTFYemzHoqrJ82seE0gfGti99VyrV3x0,37
|
||||||
|
giturlparse/tests/parse.py,sha256=dpFzvo40qdH7Zg6CmgMqBMeZz473GhbZotmVK_nq_pk,14594
|
||||||
|
giturlparse/tests/rewrite.py,sha256=scB7YGBUeFo3bEyI0Mvc0hK_ajlBY2RkrEGRtnrtukc,3386
|
||||||
|
giturlparse-0.10.0.dist-info/LICENSE,sha256=c7p036pSC0mkAbXSFFmoUjoUbzt1GKgz7qXvqFEwv2g,10273
|
||||||
|
giturlparse-0.10.0.dist-info/METADATA,sha256=NDWxArULRXhAAu2KttDMuZu1k35HvJ1eJHEcWfeB8lI,3511
|
||||||
|
giturlparse-0.10.0.dist-info/WHEEL,sha256=oh0NKYrTcu1i1-wgrI1cnhkjYIi8WJ-8qd9Jrr5_y4E,110
|
||||||
|
giturlparse-0.10.0.dist-info/top_level.txt,sha256=NHfX7iaRAYz-bnROU6Q0tgNInQU-YgIeeii0uznxCLA,12
|
||||||
|
giturlparse-0.10.0.dist-info/RECORD,,
|
||||||
6
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/WHEEL
vendored
Normal file
6
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/WHEEL
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
Wheel-Version: 1.0
|
||||||
|
Generator: bdist_wheel (0.36.1)
|
||||||
|
Root-Is-Purelib: true
|
||||||
|
Tag: py2-none-any
|
||||||
|
Tag: py3-none-any
|
||||||
|
|
||||||
1
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/top_level.txt
vendored
Normal file
1
third_party/python/giturlparse/giturlparse-0.10.0.dist-info/top_level.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
giturlparse
|
||||||
14
third_party/python/giturlparse/giturlparse/__init__.py
vendored
Normal file
14
third_party/python/giturlparse/giturlparse/__init__.py
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
from .parser import parse as _parse
|
||||||
|
from .result import GitUrlParsed
|
||||||
|
|
||||||
|
__author__ = "Iacopo Spalletti"
|
||||||
|
__email__ = "i.spalletti@nephila.it"
|
||||||
|
__version__ = "0.10.0"
|
||||||
|
|
||||||
|
|
||||||
|
def parse(url, check_domain=True):
|
||||||
|
return GitUrlParsed(_parse(url, check_domain))
|
||||||
|
|
||||||
|
|
||||||
|
def validate(url, check_domain=True):
|
||||||
|
return parse(url, check_domain).valid
|
||||||
69
third_party/python/giturlparse/giturlparse/parser.py
vendored
Normal file
69
third_party/python/giturlparse/giturlparse/parser.py
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
from .platforms import PLATFORMS
|
||||||
|
|
||||||
|
SUPPORTED_ATTRIBUTES = (
|
||||||
|
"domain",
|
||||||
|
"repo",
|
||||||
|
"owner",
|
||||||
|
"path_raw",
|
||||||
|
"groups_path",
|
||||||
|
"_user",
|
||||||
|
"port",
|
||||||
|
"url",
|
||||||
|
"platform",
|
||||||
|
"protocol",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(url, check_domain=True):
|
||||||
|
# Values are None by default
|
||||||
|
parsed_info = defaultdict(lambda: None)
|
||||||
|
parsed_info["port"] = ""
|
||||||
|
parsed_info["path_raw"] = ""
|
||||||
|
parsed_info["groups_path"] = ""
|
||||||
|
|
||||||
|
# Defaults to all attributes
|
||||||
|
map(parsed_info.setdefault, SUPPORTED_ATTRIBUTES)
|
||||||
|
|
||||||
|
for name, platform in PLATFORMS:
|
||||||
|
for protocol, regex in platform.COMPILED_PATTERNS.items():
|
||||||
|
# print(name, protocol, regex)
|
||||||
|
# Match current regex against URL
|
||||||
|
match = regex.match(url)
|
||||||
|
|
||||||
|
# Skip if not matched
|
||||||
|
if not match:
|
||||||
|
# print("[%s] URL: %s dit not match %s" % (name, url, regex.pattern))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Skip if domain is bad
|
||||||
|
domain = match.group("domain")
|
||||||
|
# print('[%s] DOMAIN = %s' % (url, domain,))
|
||||||
|
if check_domain:
|
||||||
|
if platform.DOMAINS and not (domain in platform.DOMAINS):
|
||||||
|
continue
|
||||||
|
if platform.SKIP_DOMAINS and domain in platform.SKIP_DOMAINS:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# add in platform defaults
|
||||||
|
parsed_info.update(platform.DEFAULTS)
|
||||||
|
|
||||||
|
# Get matches as dictionary
|
||||||
|
matches = platform.clean_data(match.groupdict(default=""))
|
||||||
|
|
||||||
|
# Update info with matches
|
||||||
|
parsed_info.update(matches)
|
||||||
|
|
||||||
|
# Update info with platform info
|
||||||
|
parsed_info.update(
|
||||||
|
{
|
||||||
|
"url": url,
|
||||||
|
"platform": name,
|
||||||
|
"protocol": protocol,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return parsed_info
|
||||||
|
|
||||||
|
# Empty if none matched
|
||||||
|
return parsed_info
|
||||||
18
third_party/python/giturlparse/giturlparse/platforms/__init__.py
vendored
Normal file
18
third_party/python/giturlparse/giturlparse/platforms/__init__.py
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
from .assembla import AssemblaPlatform
|
||||||
|
from .base import BasePlatform
|
||||||
|
from .bitbucket import BitbucketPlatform
|
||||||
|
from .friendcode import FriendCodePlatform
|
||||||
|
from .github import GitHubPlatform
|
||||||
|
from .gitlab import GitLabPlatform
|
||||||
|
|
||||||
|
# Supported platforms
|
||||||
|
PLATFORMS = [
|
||||||
|
# name -> Platform object
|
||||||
|
("github", GitHubPlatform()),
|
||||||
|
("bitbucket", BitbucketPlatform()),
|
||||||
|
("friendcode", FriendCodePlatform()),
|
||||||
|
("assembla", AssemblaPlatform()),
|
||||||
|
("gitlab", GitLabPlatform()),
|
||||||
|
# Match url
|
||||||
|
("base", BasePlatform()),
|
||||||
|
]
|
||||||
14
third_party/python/giturlparse/giturlparse/platforms/assembla.py
vendored
Normal file
14
third_party/python/giturlparse/giturlparse/platforms/assembla.py
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
from .base import BasePlatform
|
||||||
|
|
||||||
|
|
||||||
|
class AssemblaPlatform(BasePlatform):
|
||||||
|
DOMAINS = ("git.assembla.com",)
|
||||||
|
PATTERNS = {
|
||||||
|
"ssh": r"(?P<protocols>(git\+)?(?P<protocol>ssh))?(://)?git@(?P<domain>.+?):(?P<pathname>(?P<repo>.+)).git",
|
||||||
|
"git": r"(?P<protocols>(?P<protocol>git))://(?P<domain>.+?)/(?P<pathname>(?P<repo>.+)).git",
|
||||||
|
}
|
||||||
|
FORMATS = {
|
||||||
|
"ssh": r"git@%(domain)s:%(repo)s.git",
|
||||||
|
"git": r"git://%(domain)s/%(repo)s.git",
|
||||||
|
}
|
||||||
|
DEFAULTS = {"_user": "git"}
|
||||||
43
third_party/python/giturlparse/giturlparse/platforms/base.py
vendored
Normal file
43
third_party/python/giturlparse/giturlparse/platforms/base.py
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import itertools
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class BasePlatform:
|
||||||
|
FORMATS = {
|
||||||
|
"ssh": r"(?P<protocols>(git\+)?(?P<protocol>ssh))?(://)?%(_user)s@%(host)s:%(repo)s.git",
|
||||||
|
"http": r"(?P<protocols>(git\+)?(?P<protocol>http))://%(host)s/%(repo)s.git",
|
||||||
|
"https": r"(?P<protocols>(git\+)?(?P<protocol>https))://%(host)s/%(repo)s.git",
|
||||||
|
"git": r"(?P<protocols>(?P<protocol>git))://%(host)s/%(repo)s.git",
|
||||||
|
}
|
||||||
|
|
||||||
|
PATTERNS = {
|
||||||
|
"ssh": r"(?P<_user>.+)@(?P<domain>[^/]+?):(?P<repo>.+).git",
|
||||||
|
"http": r"http://(?P<domain>[^/]+?)/(?P<repo>.+).git",
|
||||||
|
"https": r"https://(?P<domain>[^/]+?)/(?P<repo>.+).git",
|
||||||
|
"git": r"git://(?P<domain>[^/]+?)/(?P<repo>.+).git",
|
||||||
|
}
|
||||||
|
|
||||||
|
# None means it matches all domains
|
||||||
|
DOMAINS = None
|
||||||
|
SKIP_DOMAINS = None
|
||||||
|
DEFAULTS = {}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
# Precompile PATTERNS
|
||||||
|
self.COMPILED_PATTERNS = {proto: re.compile(regex, re.IGNORECASE) for proto, regex in self.PATTERNS.items()}
|
||||||
|
|
||||||
|
# Supported protocols
|
||||||
|
self.PROTOCOLS = self.PATTERNS.keys()
|
||||||
|
|
||||||
|
if self.__class__ == BasePlatform:
|
||||||
|
sub = [subclass.SKIP_DOMAINS for subclass in self.__class__.__subclasses__() if subclass.SKIP_DOMAINS]
|
||||||
|
if sub:
|
||||||
|
self.SKIP_DOMAINS = list(itertools.chain.from_iterable(sub))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clean_data(data):
|
||||||
|
data["path"] = ""
|
||||||
|
data["branch"] = ""
|
||||||
|
data["protocols"] = list(filter(lambda x: x, data["protocols"].split("+")))
|
||||||
|
data["pathname"] = data["pathname"].strip(":")
|
||||||
|
return data
|
||||||
20
third_party/python/giturlparse/giturlparse/platforms/bitbucket.py
vendored
Normal file
20
third_party/python/giturlparse/giturlparse/platforms/bitbucket.py
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
from .base import BasePlatform
|
||||||
|
|
||||||
|
|
||||||
|
class BitbucketPlatform(BasePlatform):
|
||||||
|
PATTERNS = {
|
||||||
|
"https": (
|
||||||
|
r"(?P<protocols>(git\+)?(?P<protocol>https))://(?P<_user>.+)@(?P<domain>.+?)"
|
||||||
|
r"(?P<pathname>/(?P<owner>.+)/(?P<repo>.+?)(?:\.git)?)$"
|
||||||
|
),
|
||||||
|
"ssh": (
|
||||||
|
r"(?P<protocols>(git\+)?(?P<protocol>ssh))?(://)?git@(?P<domain>.+?):"
|
||||||
|
r"(?P<pathname>(?P<owner>.+)/(?P<repo>.+?)(?:\.git)?)$"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
FORMATS = {
|
||||||
|
"https": r"https://%(owner)s@%(domain)s/%(owner)s/%(repo)s.git",
|
||||||
|
"ssh": r"git@%(domain)s:%(owner)s/%(repo)s.git",
|
||||||
|
}
|
||||||
|
DOMAINS = ("bitbucket.org",)
|
||||||
|
DEFAULTS = {"_user": "git"}
|
||||||
14
third_party/python/giturlparse/giturlparse/platforms/friendcode.py
vendored
Normal file
14
third_party/python/giturlparse/giturlparse/platforms/friendcode.py
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
from .base import BasePlatform
|
||||||
|
|
||||||
|
|
||||||
|
class FriendCodePlatform(BasePlatform):
|
||||||
|
DOMAINS = ("friendco.de",)
|
||||||
|
PATTERNS = {
|
||||||
|
"https": (
|
||||||
|
r"(?P<protocols>(git\+)?(?P<protocol>https))://(?P<domain>.+?)/"
|
||||||
|
r"(?P<pathname>(?P<owner>.+)@user/(?P<repo>.+)).git"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
FORMATS = {
|
||||||
|
"https": r"https://%(domain)s/%(owner)s@user/%(repo)s.git",
|
||||||
|
}
|
||||||
39
third_party/python/giturlparse/giturlparse/platforms/github.py
vendored
Normal file
39
third_party/python/giturlparse/giturlparse/platforms/github.py
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
from .base import BasePlatform
|
||||||
|
|
||||||
|
|
||||||
|
class GitHubPlatform(BasePlatform):
|
||||||
|
PATTERNS = {
|
||||||
|
"https": (
|
||||||
|
r"(?P<protocols>(git\+)?(?P<protocol>https))://(?P<domain>[^/]+?)"
|
||||||
|
r"(?P<pathname>/(?P<owner>[^/]+?)/(?P<repo>[^/]+?)(?:\.git)?(?P<path_raw>(/blob/|/tree/).+)?)$"
|
||||||
|
),
|
||||||
|
"ssh": (
|
||||||
|
r"(?P<protocols>(git\+)?(?P<protocol>ssh))?(://)?git@(?P<domain>.+?)(?P<pathname>(:|/)"
|
||||||
|
r"(?P<owner>[^/]+)/(?P<repo>[^/]+?)(?:\.git)"
|
||||||
|
r"(?P<path_raw>(/blob/|/tree/).+)?)$"
|
||||||
|
),
|
||||||
|
"git": (
|
||||||
|
r"(?P<protocols>(?P<protocol>git))://(?P<domain>.+?)"
|
||||||
|
r"(?P<pathname>/(?P<owner>[^/]+)/(?P<repo>[^/]+?)(?:\.git)?"
|
||||||
|
r"(?P<path_raw>(/blob/|/tree/).+)?)$"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
FORMATS = {
|
||||||
|
"https": r"https://%(domain)s/%(owner)s/%(repo)s.git%(path_raw)s",
|
||||||
|
"ssh": r"git@%(domain)s:%(owner)s/%(repo)s.git%(path_raw)s",
|
||||||
|
"git": r"git://%(domain)s/%(owner)s/%(repo)s.git%(path_raw)s",
|
||||||
|
}
|
||||||
|
DOMAINS = (
|
||||||
|
"github.com",
|
||||||
|
"gist.github.com",
|
||||||
|
)
|
||||||
|
DEFAULTS = {"_user": "git"}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clean_data(data):
|
||||||
|
data = BasePlatform.clean_data(data)
|
||||||
|
if data["path_raw"].startswith("/blob/"):
|
||||||
|
data["path"] = data["path_raw"].replace("/blob/", "")
|
||||||
|
if data["path_raw"].startswith("/tree/"):
|
||||||
|
data["branch"] = data["path_raw"].replace("/tree/", "")
|
||||||
|
return data
|
||||||
43
third_party/python/giturlparse/giturlparse/platforms/gitlab.py
vendored
Normal file
43
third_party/python/giturlparse/giturlparse/platforms/gitlab.py
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
from .base import BasePlatform
|
||||||
|
|
||||||
|
|
||||||
|
class GitLabPlatform(BasePlatform):
|
||||||
|
PATTERNS = {
|
||||||
|
"https": (
|
||||||
|
r"(?P<protocols>(git\+)?(?P<protocol>https))://(?P<domain>.+?)(?P<port>:[0-9]+)?"
|
||||||
|
r"(?P<pathname>/(?P<owner>[^/]+?)/"
|
||||||
|
r"(?P<groups_path>.*?)?(?(groups_path)/)?(?P<repo>[^/]+?)(?:\.git)?"
|
||||||
|
r"(?P<path_raw>(/blob/|/-/tree/).+)?)$"
|
||||||
|
),
|
||||||
|
"ssh": (
|
||||||
|
r"(?P<protocols>(git\+)?(?P<protocol>ssh))?(://)?git@(?P<domain>.+?):(?P<port>[0-9]+)?(?(port))?"
|
||||||
|
r"(?P<pathname>/?(?P<owner>[^/]+)/"
|
||||||
|
r"(?P<groups_path>.*?)?(?(groups_path)/)?(?P<repo>[^/]+?)(?:\.git)?"
|
||||||
|
r"(?P<path_raw>(/blob/|/-/tree/).+)?)$"
|
||||||
|
),
|
||||||
|
"git": (
|
||||||
|
r"(?P<protocols>(?P<protocol>git))://(?P<domain>.+?):(?P<port>[0-9]+)?(?(port))?"
|
||||||
|
r"(?P<pathname>/?(?P<owner>[^/]+)/"
|
||||||
|
r"(?P<groups_path>.*?)?(?(groups_path)/)?(?P<repo>[^/]+?)(?:\.git)?"
|
||||||
|
r"(?P<path_raw>(/blob/|/-/tree/).+)?)$"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
FORMATS = {
|
||||||
|
"https": r"https://%(domain)s/%(owner)s/%(groups_slash)s%(repo)s.git%(path_raw)s",
|
||||||
|
"ssh": r"git@%(domain)s:%(port_slash)s%(owner)s/%(groups_slash)s%(repo)s.git%(path_raw)s",
|
||||||
|
"git": r"git://%(domain)s%(port)s/%(owner)s/%(groups_slash)s%(repo)s.git%(path_raw)s",
|
||||||
|
}
|
||||||
|
SKIP_DOMAINS = (
|
||||||
|
"github.com",
|
||||||
|
"gist.github.com",
|
||||||
|
)
|
||||||
|
DEFAULTS = {"_user": "git", "port": ""}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clean_data(data):
|
||||||
|
data = BasePlatform.clean_data(data)
|
||||||
|
if data["path_raw"].startswith("/blob/"):
|
||||||
|
data["path"] = data["path_raw"].replace("/blob/", "")
|
||||||
|
if data["path_raw"].startswith("/-/tree/"):
|
||||||
|
data["branch"] = data["path_raw"].replace("/-/tree/", "")
|
||||||
|
return data
|
||||||
131
third_party/python/giturlparse/giturlparse/result.py
vendored
Normal file
131
third_party/python/giturlparse/giturlparse/result.py
vendored
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
|
from .platforms import PLATFORMS
|
||||||
|
|
||||||
|
# Possible values to extract from a Git Url
|
||||||
|
REQUIRED_ATTRIBUTES = (
|
||||||
|
"domain",
|
||||||
|
"repo",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class GitUrlParsed:
|
||||||
|
platform = None
|
||||||
|
|
||||||
|
def __init__(self, parsed_info):
|
||||||
|
self._parsed = parsed_info
|
||||||
|
|
||||||
|
# Set parsed objects as attributes
|
||||||
|
for k, v in parsed_info.items():
|
||||||
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
for name, platform in PLATFORMS:
|
||||||
|
if name == self.platform:
|
||||||
|
self._platform_obj = platform
|
||||||
|
break
|
||||||
|
|
||||||
|
def _valid_attrs(self):
|
||||||
|
return all([getattr(self, attr, None) for attr in REQUIRED_ATTRIBUTES]) # NOQA
|
||||||
|
|
||||||
|
@property
|
||||||
|
def valid(self):
|
||||||
|
return all(
|
||||||
|
[
|
||||||
|
self._valid_attrs(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
##
|
||||||
|
# Alias properties
|
||||||
|
##
|
||||||
|
@property
|
||||||
|
def host(self):
|
||||||
|
return self.domain
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource(self):
|
||||||
|
return self.domain
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self.repo
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user(self):
|
||||||
|
if hasattr(self, "_user"):
|
||||||
|
return self._user
|
||||||
|
|
||||||
|
return self.owner
|
||||||
|
|
||||||
|
@property
|
||||||
|
def groups(self):
|
||||||
|
if self.groups_path:
|
||||||
|
return self.groups_path.split("/")
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def format(self, protocol): # noqa : A0003
|
||||||
|
"""Reformat URL to protocol."""
|
||||||
|
items = copy(self._parsed)
|
||||||
|
items["port_slash"] = "%s/" % self.port if self.port else ""
|
||||||
|
items["groups_slash"] = "%s/" % self.groups_path if self.groups_path else ""
|
||||||
|
return self._platform_obj.FORMATS[protocol] % items
|
||||||
|
|
||||||
|
@property
|
||||||
|
def normalized(self):
|
||||||
|
"""Normalize URL."""
|
||||||
|
return self.format(self.protocol)
|
||||||
|
|
||||||
|
##
|
||||||
|
# Rewriting
|
||||||
|
##
|
||||||
|
@property
|
||||||
|
def url2ssh(self):
|
||||||
|
return self.format("ssh")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url2http(self):
|
||||||
|
return self.format("http")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url2https(self):
|
||||||
|
return self.format("https")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url2git(self):
|
||||||
|
return self.format("git")
|
||||||
|
|
||||||
|
# All supported Urls for a repo
|
||||||
|
@property
|
||||||
|
def urls(self):
|
||||||
|
return {protocol: self.format(protocol) for protocol in self._platform_obj.PROTOCOLS}
|
||||||
|
|
||||||
|
##
|
||||||
|
# Platforms
|
||||||
|
##
|
||||||
|
@property
|
||||||
|
def github(self):
|
||||||
|
return self.platform == "github"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bitbucket(self):
|
||||||
|
return self.platform == "bitbucket"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def friendcode(self):
|
||||||
|
return self.platform == "friendcode"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def assembla(self):
|
||||||
|
return self.platform == "assembla"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gitlab(self):
|
||||||
|
return self.platform == "gitlab"
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get data as dict
|
||||||
|
##
|
||||||
|
@property
|
||||||
|
def data(self):
|
||||||
|
return dict(self._parsed)
|
||||||
16
third_party/python/mozilla_repo_urls/mozilla_repo_urls-0.0.3.dist-info/METADATA
vendored
Normal file
16
third_party/python/mozilla_repo_urls/mozilla_repo_urls-0.0.3.dist-info/METADATA
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
Metadata-Version: 2.1
|
||||||
|
Name: mozilla-repo-urls
|
||||||
|
Version: 0.0.3
|
||||||
|
Summary: Process Mozilla's repository URLs. The intent is to centralize URLs parsing.
|
||||||
|
Home-page: https://github.com/mozilla-releng/mozilla-repo-urls
|
||||||
|
Author: Mozilla Release Engineering
|
||||||
|
Author-email: release+python@mozilla.com
|
||||||
|
License: MPL2
|
||||||
|
Classifier: Programming Language :: Python :: 3
|
||||||
|
Classifier: Programming Language :: Python :: 3.6
|
||||||
|
Classifier: Programming Language :: Python :: 3.7
|
||||||
|
Classifier: Programming Language :: Python :: 3.8
|
||||||
|
Classifier: Programming Language :: Python :: 3.9
|
||||||
|
Classifier: Programming Language :: Python :: 3.10
|
||||||
|
Requires-Dist: giturlparse
|
||||||
|
|
||||||
12
third_party/python/mozilla_repo_urls/mozilla_repo_urls-0.0.3.dist-info/RECORD
vendored
Normal file
12
third_party/python/mozilla_repo_urls/mozilla_repo_urls-0.0.3.dist-info/RECORD
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
mozilla_repo_urls/__init__.py,sha256=seFB5ueyozmIXZxBWVATYPbQCzNln2SWSTirc0yk_A0,108
|
||||||
|
mozilla_repo_urls/errors.py,sha256=koXTtW_axWwCtWVHkvxXjYqAq1AXYbN54Q-C8veqDNw,485
|
||||||
|
mozilla_repo_urls/parser.py,sha256=a6Q1x8o_yu4Qof86aq2M8dwPhiMeAzCV7LxAw7CzwRg,805
|
||||||
|
mozilla_repo_urls/result.py,sha256=SN8hhIc6R1xLGOYZ0h1CpQbFiRP6LIqzNoup3MjOqnc,744
|
||||||
|
mozilla_repo_urls/platforms/__init__.py,sha256=5gwGbeTZUI-0VR0HmC3913e6AUTylDkjmcXYkg8QwYc,89
|
||||||
|
mozilla_repo_urls/platforms/hgmo.py,sha256=bKpBHAqxlMOmGbfn6aSU_q5N-7LbwNDSrt0TZ0UzTvk,1043
|
||||||
|
test/__init__.py,sha256=ui4glNH_cCoz4Ex7hcZhHTcstOPJb2wcojFiNvvIALI,88
|
||||||
|
test/test_integration.py,sha256=Eq0XjKA0w0Ao50UJMcF5tuPiFqfa1stgl9T2lg1vHJE,10919
|
||||||
|
mozilla_repo_urls-0.0.3.dist-info/METADATA,sha256=4bWx4lq-nBnCq0cnpmwfmfVpmFwX0dbvBi3jg05B1s4,628
|
||||||
|
mozilla_repo_urls-0.0.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
||||||
|
mozilla_repo_urls-0.0.3.dist-info/top_level.txt,sha256=0LuRstNeetmfWdKTPvknIx8aDVzsf1KSmASCgOvKvDM,23
|
||||||
|
mozilla_repo_urls-0.0.3.dist-info/RECORD,,
|
||||||
2
third_party/python/mozilla_repo_urls/mozilla_repo_urls-0.0.3.dist-info/top_level.txt
vendored
Normal file
2
third_party/python/mozilla_repo_urls/mozilla_repo_urls-0.0.3.dist-info/top_level.txt
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
mozilla_repo_urls
|
||||||
|
test
|
||||||
2
third_party/python/mozilla_repo_urls/mozilla_repo_urls/__init__.py
vendored
Normal file
2
third_party/python/mozilla_repo_urls/mozilla_repo_urls/__init__.py
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
from mozilla_repo_urls.errors import * # noqa F401
|
||||||
|
from mozilla_repo_urls.parser import parse # noqa F401
|
||||||
15
third_party/python/mozilla_repo_urls/mozilla_repo_urls/errors.py
vendored
Normal file
15
third_party/python/mozilla_repo_urls/mozilla_repo_urls/errors.py
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
class RepoUrlsBaseError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidRepoUrlError(RepoUrlsBaseError):
|
||||||
|
def __init__(self, url_string) -> None:
|
||||||
|
super().__init__(f"Could not parse URL: {url_string}")
|
||||||
|
|
||||||
|
|
||||||
|
class UnsupportedPlatformError(RepoUrlsBaseError):
|
||||||
|
def __init__(self, url_string, platform, supported_platforms) -> None:
|
||||||
|
super().__init__(
|
||||||
|
f"Unsupported platform. Got: {platform}. "
|
||||||
|
f"Expected: {supported_platforms}. URL: {url_string}"
|
||||||
|
)
|
||||||
27
third_party/python/mozilla_repo_urls/mozilla_repo_urls/parser.py
vendored
Normal file
27
third_party/python/mozilla_repo_urls/mozilla_repo_urls/parser.py
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import giturlparse
|
||||||
|
|
||||||
|
from mozilla_repo_urls.platforms import ADDITIONAL_PLATFORMS
|
||||||
|
|
||||||
|
from .errors import InvalidRepoUrlError, UnsupportedPlatformError
|
||||||
|
from .result import RepoUrlParsed
|
||||||
|
|
||||||
|
for i, platform in enumerate(ADDITIONAL_PLATFORMS):
|
||||||
|
giturlparse.platforms.PLATFORMS.insert(i, platform)
|
||||||
|
|
||||||
|
|
||||||
|
_SUPPORTED_PLAFORMS = ("hgmo", "github")
|
||||||
|
|
||||||
|
|
||||||
|
def parse(url_string):
|
||||||
|
# Workaround for https://github.com/nephila/giturlparse/issues/43
|
||||||
|
url_string = url_string.rstrip("/")
|
||||||
|
parsed_info = giturlparse.parser.parse(url_string)
|
||||||
|
parsed_url = RepoUrlParsed(parsed_info)
|
||||||
|
|
||||||
|
if not parsed_url.valid:
|
||||||
|
raise InvalidRepoUrlError(url_string)
|
||||||
|
|
||||||
|
if parsed_url.platform not in _SUPPORTED_PLAFORMS:
|
||||||
|
raise UnsupportedPlatformError(url_string, platform, _SUPPORTED_PLAFORMS)
|
||||||
|
|
||||||
|
return parsed_url
|
||||||
5
third_party/python/mozilla_repo_urls/mozilla_repo_urls/platforms/__init__.py
vendored
Normal file
5
third_party/python/mozilla_repo_urls/mozilla_repo_urls/platforms/__init__.py
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
from .hgmo import HgmoPlatform
|
||||||
|
|
||||||
|
ADDITIONAL_PLATFORMS = [
|
||||||
|
("hgmo", HgmoPlatform()),
|
||||||
|
]
|
||||||
34
third_party/python/mozilla_repo_urls/mozilla_repo_urls/platforms/hgmo.py
vendored
Normal file
34
third_party/python/mozilla_repo_urls/mozilla_repo_urls/platforms/hgmo.py
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
from giturlparse.platforms.base import BasePlatform
|
||||||
|
|
||||||
|
|
||||||
|
class HgmoPlatform(BasePlatform):
|
||||||
|
PATTERNS = {
|
||||||
|
"https": (
|
||||||
|
r"(?P<protocols>(?P<protocol>https))://"
|
||||||
|
r"(?P<domain>[^/]+?)"
|
||||||
|
r"(?P<pathname>/"
|
||||||
|
r"(?P<repo>(([^/]+?)(/)?){1,2}))"
|
||||||
|
r"(?P<path_raw>(/raw-file/|/file/).+)?$"
|
||||||
|
),
|
||||||
|
"ssh": (
|
||||||
|
r"(?P<protocols>(?P<protocol>ssh))(://)?"
|
||||||
|
r"(?P<domain>.+?)"
|
||||||
|
r"(?P<pathname>(:|/))"
|
||||||
|
r"(?P<repo>(([^/]+?)(/)?){1,2})/?$"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
FORMATS = {
|
||||||
|
"https": r"https://%(domain)s/%(repo)s%(path_raw)s",
|
||||||
|
"ssh": r"ssh://%(domain)s/%(repo)s",
|
||||||
|
}
|
||||||
|
DOMAINS = ("hg.mozilla.org",)
|
||||||
|
DEFAULTS = {"_user": ""}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clean_data(data):
|
||||||
|
data = BasePlatform.clean_data(data)
|
||||||
|
if data["path_raw"].startswith(("/raw-file/", "/file")):
|
||||||
|
data["path"] = (
|
||||||
|
data["path_raw"].replace("/raw-file/", "").replace("/file/", "")
|
||||||
|
)
|
||||||
|
return data
|
||||||
30
third_party/python/mozilla_repo_urls/mozilla_repo_urls/result.py
vendored
Normal file
30
third_party/python/mozilla_repo_urls/mozilla_repo_urls/result.py
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import giturlparse
|
||||||
|
|
||||||
|
_DOT_GIT_SUFFIX = ".git"
|
||||||
|
|
||||||
|
|
||||||
|
class RepoUrlParsed(giturlparse.result.GitUrlParsed):
|
||||||
|
@property
|
||||||
|
def hgmo(self) -> bool:
|
||||||
|
return self.platform == "hgmo"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def repo_name(self) -> str:
|
||||||
|
return self.repo_path.split("/")[-1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def repo_path(self) -> str:
|
||||||
|
repo_path = (
|
||||||
|
self.pathname[: -len(_DOT_GIT_SUFFIX)]
|
||||||
|
if self.pathname.endswith(_DOT_GIT_SUFFIX)
|
||||||
|
else self.pathname
|
||||||
|
)
|
||||||
|
return repo_path.strip("/")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def repo_type(self) -> str:
|
||||||
|
return "hg" if self.platform == "hgmo" else "git"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def taskcluster_role_prefix(self) -> str:
|
||||||
|
return f"repo:{self.host}/{self.repo_path}"
|
||||||
6
third_party/python/mozilla_repo_urls/test/__init__.py
vendored
Normal file
6
third_party/python/mozilla_repo_urls/test/__init__.py
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def does_not_raise():
|
||||||
|
yield
|
||||||
280
third_party/python/mozilla_repo_urls/test/test_integration.py
vendored
Normal file
280
third_party/python/mozilla_repo_urls/test/test_integration.py
vendored
Normal file
|
|
@ -0,0 +1,280 @@
|
||||||
|
from test import does_not_raise
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import mozilla_repo_urls
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"url_string, expectation, expected",
|
||||||
|
(
|
||||||
|
(
|
||||||
|
"https://hg.mozilla.org/mozilla-central",
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"github": False,
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": True,
|
||||||
|
"host": "hg.mozilla.org",
|
||||||
|
"name": "mozilla-central",
|
||||||
|
"normalized": "https://hg.mozilla.org/mozilla-central",
|
||||||
|
"path_raw": "",
|
||||||
|
"path": "",
|
||||||
|
"pathname": "/mozilla-central",
|
||||||
|
"platform": "hgmo",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "https",
|
||||||
|
"protocols": ["https"],
|
||||||
|
"repo": "mozilla-central",
|
||||||
|
"repo_name": "mozilla-central",
|
||||||
|
"repo_path": "mozilla-central",
|
||||||
|
"repo_type": "hg",
|
||||||
|
"resource": "hg.mozilla.org",
|
||||||
|
"taskcluster_role_prefix": "repo:hg.mozilla.org/mozilla-central",
|
||||||
|
"urls": {
|
||||||
|
"https": "https://hg.mozilla.org/mozilla-central",
|
||||||
|
"ssh": "ssh://hg.mozilla.org/mozilla-central",
|
||||||
|
},
|
||||||
|
"user": "",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://hg.mozilla.org/releases/mozilla-beta",
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"github": False,
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": True,
|
||||||
|
"host": "hg.mozilla.org",
|
||||||
|
"name": "releases/mozilla-beta",
|
||||||
|
"normalized": "https://hg.mozilla.org/releases/mozilla-beta",
|
||||||
|
"path_raw": "",
|
||||||
|
"path": "",
|
||||||
|
"pathname": "/releases/mozilla-beta",
|
||||||
|
"platform": "hgmo",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "https",
|
||||||
|
"protocols": ["https"],
|
||||||
|
"repo": "releases/mozilla-beta",
|
||||||
|
"repo_name": "mozilla-beta",
|
||||||
|
"repo_path": "releases/mozilla-beta",
|
||||||
|
"repo_type": "hg",
|
||||||
|
"resource": "hg.mozilla.org",
|
||||||
|
"taskcluster_role_prefix": "repo:hg.mozilla.org/releases/mozilla-beta",
|
||||||
|
"urls": {
|
||||||
|
"https": "https://hg.mozilla.org/releases/mozilla-beta",
|
||||||
|
"ssh": "ssh://hg.mozilla.org/releases/mozilla-beta",
|
||||||
|
},
|
||||||
|
"user": "",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://hg.mozilla.org/releases/mozilla-release",
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"github": False,
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": True,
|
||||||
|
"host": "hg.mozilla.org",
|
||||||
|
"name": "releases/mozilla-release",
|
||||||
|
"normalized": "https://hg.mozilla.org/releases/mozilla-release",
|
||||||
|
"path_raw": "",
|
||||||
|
"path": "",
|
||||||
|
"pathname": "/releases/mozilla-release",
|
||||||
|
"platform": "hgmo",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "https",
|
||||||
|
"protocols": ["https"],
|
||||||
|
"repo": "releases/mozilla-release",
|
||||||
|
"repo_name": "mozilla-release",
|
||||||
|
"repo_path": "releases/mozilla-release",
|
||||||
|
"repo_type": "hg",
|
||||||
|
"resource": "hg.mozilla.org",
|
||||||
|
"taskcluster_role_prefix": "repo:hg.mozilla.org/releases/mozilla-release", # noqa: E501
|
||||||
|
"urls": {
|
||||||
|
"https": "https://hg.mozilla.org/releases/mozilla-release",
|
||||||
|
"ssh": "ssh://hg.mozilla.org/releases/mozilla-release",
|
||||||
|
},
|
||||||
|
"user": "",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://hg.mozilla.org/try",
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": True,
|
||||||
|
"host": "hg.mozilla.org",
|
||||||
|
"name": "try",
|
||||||
|
"normalized": "https://hg.mozilla.org/try",
|
||||||
|
"path_raw": "",
|
||||||
|
"path": "",
|
||||||
|
"pathname": "/try",
|
||||||
|
"platform": "hgmo",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "https",
|
||||||
|
"protocols": ["https"],
|
||||||
|
"repo": "try",
|
||||||
|
"repo_name": "try",
|
||||||
|
"repo_path": "try",
|
||||||
|
"repo_type": "hg",
|
||||||
|
"resource": "hg.mozilla.org",
|
||||||
|
"taskcluster_role_prefix": "repo:hg.mozilla.org/try",
|
||||||
|
"urls": {
|
||||||
|
"https": "https://hg.mozilla.org/try",
|
||||||
|
"ssh": "ssh://hg.mozilla.org/try",
|
||||||
|
},
|
||||||
|
"user": "",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/ci/config.yml", # noqa: E501
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": True,
|
||||||
|
"host": "hg.mozilla.org",
|
||||||
|
"name": "mozilla-central",
|
||||||
|
"normalized": "https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/ci/config.yml", # noqa: E501
|
||||||
|
"path_raw": "/raw-file/tip/taskcluster/ci/config.yml",
|
||||||
|
"path": "tip/taskcluster/ci/config.yml",
|
||||||
|
"pathname": "/mozilla-central",
|
||||||
|
"platform": "hgmo",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "https",
|
||||||
|
"protocols": ["https"],
|
||||||
|
"repo": "mozilla-central",
|
||||||
|
"repo_name": "mozilla-central",
|
||||||
|
"repo_path": "mozilla-central",
|
||||||
|
"repo_type": "hg",
|
||||||
|
"resource": "hg.mozilla.org",
|
||||||
|
"taskcluster_role_prefix": "repo:hg.mozilla.org/mozilla-central",
|
||||||
|
"urls": {
|
||||||
|
"https": "https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/ci/config.yml", # noqa: E501
|
||||||
|
"ssh": "ssh://hg.mozilla.org/mozilla-central",
|
||||||
|
},
|
||||||
|
"user": "",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/ci/config.yml", # noqa: E501
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"github": False,
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": True,
|
||||||
|
"host": "hg.mozilla.org",
|
||||||
|
"name": "mozilla-central",
|
||||||
|
"normalized": "https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/ci/config.yml", # noqa: E501
|
||||||
|
"path_raw": "/file/tip/taskcluster/ci/config.yml",
|
||||||
|
"path": "tip/taskcluster/ci/config.yml",
|
||||||
|
"pathname": "/mozilla-central",
|
||||||
|
"platform": "hgmo",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "https",
|
||||||
|
"protocols": ["https"],
|
||||||
|
"repo": "mozilla-central",
|
||||||
|
"repo_name": "mozilla-central",
|
||||||
|
"repo_path": "mozilla-central",
|
||||||
|
"repo_type": "hg",
|
||||||
|
"resource": "hg.mozilla.org",
|
||||||
|
"taskcluster_role_prefix": "repo:hg.mozilla.org/mozilla-central",
|
||||||
|
"urls": {
|
||||||
|
"https": "https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/ci/config.yml", # noqa: E501
|
||||||
|
"ssh": "ssh://hg.mozilla.org/mozilla-central",
|
||||||
|
},
|
||||||
|
"user": "",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://github.com/mozilla-mobile/fenix",
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"github": True,
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": False,
|
||||||
|
"host": "github.com",
|
||||||
|
"name": "fenix",
|
||||||
|
"normalized": "https://github.com/mozilla-mobile/fenix.git",
|
||||||
|
"owner": "mozilla-mobile",
|
||||||
|
"path_raw": "",
|
||||||
|
"path": "",
|
||||||
|
"pathname": "/mozilla-mobile/fenix",
|
||||||
|
"platform": "github",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "https",
|
||||||
|
"protocols": ["https"],
|
||||||
|
"repo": "fenix",
|
||||||
|
"repo_name": "fenix",
|
||||||
|
"repo_path": "mozilla-mobile/fenix",
|
||||||
|
"repo_type": "git",
|
||||||
|
"resource": "github.com",
|
||||||
|
"taskcluster_role_prefix": "repo:github.com/mozilla-mobile/fenix",
|
||||||
|
"urls": {
|
||||||
|
"git": "git://github.com/mozilla-mobile/fenix.git",
|
||||||
|
"https": "https://github.com/mozilla-mobile/fenix.git",
|
||||||
|
"ssh": "git@github.com:mozilla-mobile/fenix.git",
|
||||||
|
},
|
||||||
|
"user": "git",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"git@github.com:mozilla-mobile/firefox-android.git",
|
||||||
|
does_not_raise(),
|
||||||
|
{
|
||||||
|
"github": True,
|
||||||
|
"groups": [],
|
||||||
|
"hgmo": False,
|
||||||
|
"host": "github.com",
|
||||||
|
"name": "firefox-android",
|
||||||
|
"normalized": "git@github.com:mozilla-mobile/firefox-android.git",
|
||||||
|
"owner": "mozilla-mobile",
|
||||||
|
"path_raw": "",
|
||||||
|
"path": "",
|
||||||
|
"pathname": "mozilla-mobile/firefox-android.git",
|
||||||
|
"platform": "github",
|
||||||
|
"port": "",
|
||||||
|
"protocol": "ssh",
|
||||||
|
"protocols": [],
|
||||||
|
"repo": "firefox-android",
|
||||||
|
"repo_name": "firefox-android",
|
||||||
|
"repo_path": "mozilla-mobile/firefox-android",
|
||||||
|
"repo_type": "git",
|
||||||
|
"resource": "github.com",
|
||||||
|
"taskcluster_role_prefix": "repo:github.com/mozilla-mobile/firefox-android", # noqa: E501
|
||||||
|
"urls": {
|
||||||
|
"git": "git://github.com/mozilla-mobile/firefox-android.git",
|
||||||
|
"https": "https://github.com/mozilla-mobile/firefox-android.git",
|
||||||
|
"ssh": "git@github.com:mozilla-mobile/firefox-android.git",
|
||||||
|
},
|
||||||
|
"user": "git",
|
||||||
|
"valid": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://some.unknown/repo",
|
||||||
|
pytest.raises(mozilla_repo_urls.InvalidRepoUrlError),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://gitlab.com/some-owner/some-repo",
|
||||||
|
pytest.raises(mozilla_repo_urls.UnsupportedPlatformError),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_parse(url_string, expectation, expected):
|
||||||
|
with expectation:
|
||||||
|
url_object = mozilla_repo_urls.parse(url_string)
|
||||||
|
actual = {
|
||||||
|
attribute_name: getattr(url_object, attribute_name)
|
||||||
|
for attribute_name in expected.keys()
|
||||||
|
}
|
||||||
|
assert actual == expected
|
||||||
36
third_party/python/poetry.lock
generated
vendored
36
third_party/python/poetry.lock
generated
vendored
|
|
@ -194,6 +194,14 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "giturlparse"
|
||||||
|
version = "0.10.0"
|
||||||
|
description = "A Git URL parsing module (supports parsing and rewriting)"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glean-parser"
|
name = "glean-parser"
|
||||||
version = "6.1.2"
|
version = "6.1.2"
|
||||||
|
|
@ -334,6 +342,17 @@ python-versions = "*"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
six = "*"
|
six = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mozilla-repo-urls"
|
||||||
|
version = "0.0.3"
|
||||||
|
description = "Process Mozilla's repository URLs. The intent is to centralize URLs parsing."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
giturlparse = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mozilla-version"
|
name = "mozilla-version"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
|
|
@ -615,7 +634,7 @@ test = ["pytest", "pytest-cov", "pytest-mock", "httmock", "mock", "setuptools-li
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "taskcluster-taskgraph"
|
name = "taskcluster-taskgraph"
|
||||||
version = "2.0.0"
|
version = "3.2.0"
|
||||||
description = "Build taskcluster taskgraphs"
|
description = "Build taskcluster taskgraphs"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
|
@ -625,6 +644,7 @@ python-versions = "*"
|
||||||
appdirs = ">=1.4"
|
appdirs = ">=1.4"
|
||||||
attrs = ">=19.1.0"
|
attrs = ">=19.1.0"
|
||||||
json-e = ">=2.7"
|
json-e = ">=2.7"
|
||||||
|
mozilla-repo-urls = "*"
|
||||||
PyYAML = ">=5.4"
|
PyYAML = ">=5.4"
|
||||||
redo = ">=2.0"
|
redo = ">=2.0"
|
||||||
requests = ">=2.25"
|
requests = ">=2.25"
|
||||||
|
|
@ -737,7 +757,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.6"
|
python-versions = "^3.6"
|
||||||
content-hash = "9d5442add586f045a8bac2403afaade45b7836ae851e906fd598d48c23075eb1"
|
content-hash = "e350bab49e867e6242ad7be2ca071a731ffe5162e79553e38f82eba26c421da3"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiohttp = [
|
aiohttp = [
|
||||||
|
|
@ -850,6 +870,10 @@ esprima = [
|
||||||
{file = "fluent.syntax-0.18.1-py2.py3-none-any.whl", hash = "sha256:0e63679fa4f1b3042565220a5127b4bab842424f07d6a13c12299e3b3835486a"},
|
{file = "fluent.syntax-0.18.1-py2.py3-none-any.whl", hash = "sha256:0e63679fa4f1b3042565220a5127b4bab842424f07d6a13c12299e3b3835486a"},
|
||||||
{file = "fluent.syntax-0.18.1.tar.gz", hash = "sha256:3a55f5e605d1b029a65cc8b6492c86ec4608e15447e73db1495de11fd46c104f"},
|
{file = "fluent.syntax-0.18.1.tar.gz", hash = "sha256:3a55f5e605d1b029a65cc8b6492c86ec4608e15447e73db1495de11fd46c104f"},
|
||||||
]
|
]
|
||||||
|
giturlparse = [
|
||||||
|
{file = "giturlparse-0.10.0-py2.py3-none-any.whl", hash = "sha256:04ba1a3a099c3093fa8d24a422913c6a9b2c2cd22bcffc939cf72e3e98f672d7"},
|
||||||
|
{file = "giturlparse-0.10.0.tar.gz", hash = "sha256:2595ab291d30717cda8474b874c9fd509f1b9802ad7f6968c36a45e4b13eb337"},
|
||||||
|
]
|
||||||
glean-parser = [
|
glean-parser = [
|
||||||
{file = "glean_parser-6.1.2-py3-none-any.whl", hash = "sha256:e801af6463b7e0ba79d97ddfc0a58d9d71121c93cea601417571e33fa8142270"},
|
{file = "glean_parser-6.1.2-py3-none-any.whl", hash = "sha256:e801af6463b7e0ba79d97ddfc0a58d9d71121c93cea601417571e33fa8142270"},
|
||||||
{file = "glean_parser-6.1.2.tar.gz", hash = "sha256:12a0fecedc1144d77fa571e0422ff3fea4dbadc381d631bea800a6b2f58f4f7f"},
|
{file = "glean_parser-6.1.2.tar.gz", hash = "sha256:12a0fecedc1144d77fa571e0422ff3fea4dbadc381d631bea800a6b2f58f4f7f"},
|
||||||
|
|
@ -945,6 +969,10 @@ mohawk = [
|
||||||
{file = "mohawk-0.3.4-py2-none-any.whl", hash = "sha256:b3f85ffa93a5c7d2f9cc591246ef9f8ac4a9fa716bfd5bae0377699a2d89d78c"},
|
{file = "mohawk-0.3.4-py2-none-any.whl", hash = "sha256:b3f85ffa93a5c7d2f9cc591246ef9f8ac4a9fa716bfd5bae0377699a2d89d78c"},
|
||||||
{file = "mohawk-0.3.4.tar.gz", hash = "sha256:e98b331d9fa9ece7b8be26094cbe2d57613ae882133cc755167268a984bc0ab3"},
|
{file = "mohawk-0.3.4.tar.gz", hash = "sha256:e98b331d9fa9ece7b8be26094cbe2d57613ae882133cc755167268a984bc0ab3"},
|
||||||
]
|
]
|
||||||
|
mozilla-repo-urls = [
|
||||||
|
{file = "mozilla-repo-urls-0.0.3.tar.gz", hash = "sha256:3b2f9b42111ce3d50ecdcd081a62229e1fdc8f5472adbf405abe12d3ba8e8af5"},
|
||||||
|
{file = "mozilla_repo_urls-0.0.3-py3-none-any.whl", hash = "sha256:673c80a4d0ed449093203b88e119e0bf1074026f891c1dd50aa04d534fd0658c"},
|
||||||
|
]
|
||||||
mozilla-version = [
|
mozilla-version = [
|
||||||
{file = "mozilla-version-0.3.4.tar.gz", hash = "sha256:3ed4deb7a6fb25c83a5346ef4de08ddff9b2ddc4d16dd8fafb4a84978cc71255"},
|
{file = "mozilla-version-0.3.4.tar.gz", hash = "sha256:3ed4deb7a6fb25c83a5346ef4de08ddff9b2ddc4d16dd8fafb4a84978cc71255"},
|
||||||
{file = "mozilla_version-0.3.4-py2.py3-none-any.whl", hash = "sha256:ce5741c2e7d12c30b53de9f79e30d6ac2a8bd4c93be711d30c7a7a08e32a094f"},
|
{file = "mozilla_version-0.3.4-py2.py3-none-any.whl", hash = "sha256:ce5741c2e7d12c30b53de9f79e30d6ac2a8bd4c93be711d30c7a7a08e32a094f"},
|
||||||
|
|
@ -1125,8 +1153,8 @@ taskcluster = [
|
||||||
{file = "taskcluster-44.2.2.tar.gz", hash = "sha256:0266a6a901e1a2ec838984a7f24e7adb6d58f9f2e221a7f613388f8f23f786fc"},
|
{file = "taskcluster-44.2.2.tar.gz", hash = "sha256:0266a6a901e1a2ec838984a7f24e7adb6d58f9f2e221a7f613388f8f23f786fc"},
|
||||||
]
|
]
|
||||||
taskcluster-taskgraph = [
|
taskcluster-taskgraph = [
|
||||||
{file = "taskcluster-taskgraph-2.0.0.tar.gz", hash = "sha256:93eff40ba39a29cd290fc25a2124ed9bf5806d87891edd7e8de35df568708141"},
|
{file = "taskcluster-taskgraph-3.2.0.tar.gz", hash = "sha256:941d96fd36c20b0e84e322d2c25be04fe5f258405793af5e086bbec698cbcb17"},
|
||||||
{file = "taskcluster_taskgraph-2.0.0-py3-none-any.whl", hash = "sha256:3d22ab488071ddc82997b33fc6c1c524a44bdc7e14b30a274d99dbbdd7389502"},
|
{file = "taskcluster_taskgraph-3.2.0-py3-none-any.whl", hash = "sha256:fafcd1bfd8ec8b2f57db4e4d87d5b881da3ad7119d78d407d22b4b71b805d1bf"},
|
||||||
]
|
]
|
||||||
taskcluster-urls = [
|
taskcluster-urls = [
|
||||||
{file = "taskcluster-urls-13.0.1.tar.gz", hash = "sha256:b25e122ecec249c4299ac7b20b08db76e3e2025bdaeb699a9d444556de5fd367"},
|
{file = "taskcluster-urls-13.0.1.tar.gz", hash = "sha256:b25e122ecec249c4299ac7b20b08db76e3e2025bdaeb699a9d444556de5fd367"},
|
||||||
|
|
|
||||||
96
third_party/python/requirements.in
vendored
96
third_party/python/requirements.in
vendored
|
|
@ -1,48 +1,48 @@
|
||||||
appdirs==1.4.4
|
appdirs==1.4.4
|
||||||
attrs==19.2.0
|
attrs==19.2.0
|
||||||
blessings==1.7
|
blessings==1.7
|
||||||
cbor2==4.0.1
|
cbor2==4.0.1
|
||||||
colorama==0.4.5
|
colorama==0.4.5
|
||||||
compare-locales==8.2.1
|
compare-locales==8.2.1
|
||||||
cookies==2.2.1
|
cookies==2.2.1
|
||||||
cram==0.7
|
cram==0.7
|
||||||
distro==1.4.0
|
distro==1.4.0
|
||||||
ecdsa==0.15
|
ecdsa==0.15
|
||||||
esprima==4.0.1
|
esprima==4.0.1
|
||||||
fluent.migrate==0.11
|
fluent.migrate==0.11
|
||||||
fluent.syntax==0.18.1
|
fluent.syntax==0.18.1
|
||||||
glean_parser==6.1.2
|
glean_parser==6.1.2
|
||||||
# Pin importlib-metadata to a version compatible with poetry
|
# Pin importlib-metadata to a version compatible with poetry
|
||||||
importlib-metadata==1.7.0
|
importlib-metadata==1.7.0
|
||||||
jsmin==2.1.0
|
jsmin==2.1.0
|
||||||
json-e==2.7.0
|
json-e==2.7.0
|
||||||
looseversion==1.0.1
|
looseversion==1.0.1
|
||||||
mozilla-version==0.3.4
|
mozilla-version==0.3.4
|
||||||
packaging==20.9
|
packaging==20.9
|
||||||
pathspec==0.9.0
|
pathspec==0.9.0
|
||||||
pip==21.2.4
|
pip==21.2.4
|
||||||
pip-tools==5.5.0
|
pip-tools==5.5.0
|
||||||
ply==3.10
|
ply==3.10
|
||||||
pyasn1==0.4.8
|
pyasn1==0.4.8
|
||||||
pyasn1-modules==0.2.8
|
pyasn1-modules==0.2.8
|
||||||
pylru==1.0.9
|
pylru==1.0.9
|
||||||
python-hglib==2.4
|
python-hglib==2.4
|
||||||
pytoml==0.1.10
|
pytoml==0.1.10
|
||||||
pyyaml==5.4.1
|
pyyaml==5.4.1
|
||||||
redo==2.0.3
|
redo==2.0.3
|
||||||
requests==2.25.1
|
requests==2.25.1
|
||||||
requests-unixsocket==0.2.0
|
requests-unixsocket==0.2.0
|
||||||
responses==0.10.6
|
responses==0.10.6
|
||||||
rsa==3.1.4
|
rsa==3.1.4
|
||||||
sentry-sdk==0.14.3
|
sentry-sdk==0.14.3
|
||||||
setuptools==51.2.0
|
setuptools==51.2.0
|
||||||
six==1.13.0
|
six==1.13.0
|
||||||
slugid==2.0.0
|
slugid==2.0.0
|
||||||
taskcluster==44.2.2
|
taskcluster==44.2.2
|
||||||
taskcluster-taskgraph==2.0.0
|
taskcluster-taskgraph==3.2.0
|
||||||
taskcluster-urls==13.0.1
|
taskcluster-urls==13.0.1
|
||||||
tqdm==4.62.3
|
tqdm==4.62.3
|
||||||
urllib3==1.26
|
urllib3==1.26
|
||||||
voluptuous==0.12.1
|
voluptuous==0.12.1
|
||||||
wheel==0.37.0
|
wheel==0.37.0
|
||||||
yamllint==1.23
|
yamllint==1.23
|
||||||
|
|
|
||||||
796
third_party/python/requirements.txt
vendored
796
third_party/python/requirements.txt
vendored
|
|
@ -1,395 +1,401 @@
|
||||||
aiohttp==3.7.4.post0; python_version >= "3.6" \
|
aiohttp==3.7.4.post0; python_version >= "3.6" \
|
||||||
--hash=sha256:3cf75f7cdc2397ed4442594b935a11ed5569961333d49b7539ea741be2cc79d5 \
|
--hash=sha256:3cf75f7cdc2397ed4442594b935a11ed5569961333d49b7539ea741be2cc79d5 \
|
||||||
--hash=sha256:4b302b45040890cea949ad092479e01ba25911a15e648429c7c5aae9650c67a8 \
|
--hash=sha256:4b302b45040890cea949ad092479e01ba25911a15e648429c7c5aae9650c67a8 \
|
||||||
--hash=sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95 \
|
--hash=sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95 \
|
||||||
--hash=sha256:393f389841e8f2dfc86f774ad22f00923fdee66d238af89b70ea314c4aefd290 \
|
--hash=sha256:393f389841e8f2dfc86f774ad22f00923fdee66d238af89b70ea314c4aefd290 \
|
||||||
--hash=sha256:c6e9dcb4cb338d91a73f178d866d051efe7c62a7166653a91e7d9fb18274058f \
|
--hash=sha256:c6e9dcb4cb338d91a73f178d866d051efe7c62a7166653a91e7d9fb18274058f \
|
||||||
--hash=sha256:5df68496d19f849921f05f14f31bd6ef53ad4b00245da3195048c69934521809 \
|
--hash=sha256:5df68496d19f849921f05f14f31bd6ef53ad4b00245da3195048c69934521809 \
|
||||||
--hash=sha256:0563c1b3826945eecd62186f3f5c7d31abb7391fedc893b7e2b26303b5a9f3fe \
|
--hash=sha256:0563c1b3826945eecd62186f3f5c7d31abb7391fedc893b7e2b26303b5a9f3fe \
|
||||||
--hash=sha256:3d78619672183be860b96ed96f533046ec97ca067fd46ac1f6a09cd9b7484287 \
|
--hash=sha256:3d78619672183be860b96ed96f533046ec97ca067fd46ac1f6a09cd9b7484287 \
|
||||||
--hash=sha256:f705e12750171c0ab4ef2a3c76b9a4024a62c4103e3a55dd6f99265b9bc6fcfc \
|
--hash=sha256:f705e12750171c0ab4ef2a3c76b9a4024a62c4103e3a55dd6f99265b9bc6fcfc \
|
||||||
--hash=sha256:230a8f7e24298dea47659251abc0fd8b3c4e38a664c59d4b89cca7f6c09c9e87 \
|
--hash=sha256:230a8f7e24298dea47659251abc0fd8b3c4e38a664c59d4b89cca7f6c09c9e87 \
|
||||||
--hash=sha256:2e19413bf84934d651344783c9f5e22dee452e251cfd220ebadbed2d9931dbf0 \
|
--hash=sha256:2e19413bf84934d651344783c9f5e22dee452e251cfd220ebadbed2d9931dbf0 \
|
||||||
--hash=sha256:e4b2b334e68b18ac9817d828ba44d8fcb391f6acb398bcc5062b14b2cbeac970 \
|
--hash=sha256:e4b2b334e68b18ac9817d828ba44d8fcb391f6acb398bcc5062b14b2cbeac970 \
|
||||||
--hash=sha256:d012ad7911653a906425d8473a1465caa9f8dea7fcf07b6d870397b774ea7c0f \
|
--hash=sha256:d012ad7911653a906425d8473a1465caa9f8dea7fcf07b6d870397b774ea7c0f \
|
||||||
--hash=sha256:40eced07f07a9e60e825554a31f923e8d3997cfc7fb31dbc1328c70826e04cde \
|
--hash=sha256:40eced07f07a9e60e825554a31f923e8d3997cfc7fb31dbc1328c70826e04cde \
|
||||||
--hash=sha256:209b4a8ee987eccc91e2bd3ac36adee0e53a5970b8ac52c273f7f8fd4872c94c \
|
--hash=sha256:209b4a8ee987eccc91e2bd3ac36adee0e53a5970b8ac52c273f7f8fd4872c94c \
|
||||||
--hash=sha256:14762875b22d0055f05d12abc7f7d61d5fd4fe4642ce1a249abdf8c700bf1fd8 \
|
--hash=sha256:14762875b22d0055f05d12abc7f7d61d5fd4fe4642ce1a249abdf8c700bf1fd8 \
|
||||||
--hash=sha256:7615dab56bb07bff74bc865307aeb89a8bfd9941d2ef9d817b9436da3a0ea54f \
|
--hash=sha256:7615dab56bb07bff74bc865307aeb89a8bfd9941d2ef9d817b9436da3a0ea54f \
|
||||||
--hash=sha256:d9e13b33afd39ddeb377eff2c1c4f00544e191e1d1dee5b6c51ddee8ea6f0cf5 \
|
--hash=sha256:d9e13b33afd39ddeb377eff2c1c4f00544e191e1d1dee5b6c51ddee8ea6f0cf5 \
|
||||||
--hash=sha256:547da6cacac20666422d4882cfcd51298d45f7ccb60a04ec27424d2f36ba3eaf \
|
--hash=sha256:547da6cacac20666422d4882cfcd51298d45f7ccb60a04ec27424d2f36ba3eaf \
|
||||||
--hash=sha256:af9aa9ef5ba1fd5b8c948bb11f44891968ab30356d65fd0cc6707d989cd521df \
|
--hash=sha256:af9aa9ef5ba1fd5b8c948bb11f44891968ab30356d65fd0cc6707d989cd521df \
|
||||||
--hash=sha256:64322071e046020e8797117b3658b9c2f80e3267daec409b350b6a7a05041213 \
|
--hash=sha256:64322071e046020e8797117b3658b9c2f80e3267daec409b350b6a7a05041213 \
|
||||||
--hash=sha256:bb437315738aa441251214dad17428cafda9cdc9729499f1d6001748e1d432f4 \
|
--hash=sha256:bb437315738aa441251214dad17428cafda9cdc9729499f1d6001748e1d432f4 \
|
||||||
--hash=sha256:e54962802d4b8b18b6207d4a927032826af39395a3bd9196a5af43fc4e60b009 \
|
--hash=sha256:e54962802d4b8b18b6207d4a927032826af39395a3bd9196a5af43fc4e60b009 \
|
||||||
--hash=sha256:a00bb73540af068ca7390e636c01cbc4f644961896fa9363154ff43fd37af2f5 \
|
--hash=sha256:a00bb73540af068ca7390e636c01cbc4f644961896fa9363154ff43fd37af2f5 \
|
||||||
--hash=sha256:79ebfc238612123a713a457d92afb4096e2148be17df6c50fb9bf7a81c2f8013 \
|
--hash=sha256:79ebfc238612123a713a457d92afb4096e2148be17df6c50fb9bf7a81c2f8013 \
|
||||||
--hash=sha256:515dfef7f869a0feb2afee66b957cc7bbe9ad0cdee45aec7fdc623f4ecd4fb16 \
|
--hash=sha256:515dfef7f869a0feb2afee66b957cc7bbe9ad0cdee45aec7fdc623f4ecd4fb16 \
|
||||||
--hash=sha256:114b281e4d68302a324dd33abb04778e8557d88947875cbf4e842c2c01a030c5 \
|
--hash=sha256:114b281e4d68302a324dd33abb04778e8557d88947875cbf4e842c2c01a030c5 \
|
||||||
--hash=sha256:7b18b97cf8ee5452fa5f4e3af95d01d84d86d32c5e2bfa260cf041749d66360b \
|
--hash=sha256:7b18b97cf8ee5452fa5f4e3af95d01d84d86d32c5e2bfa260cf041749d66360b \
|
||||||
--hash=sha256:15492a6368d985b76a2a5fdd2166cddfea5d24e69eefed4630cbaae5c81d89bd \
|
--hash=sha256:15492a6368d985b76a2a5fdd2166cddfea5d24e69eefed4630cbaae5c81d89bd \
|
||||||
--hash=sha256:bdb230b4943891321e06fc7def63c7aace16095be7d9cf3b1e01be2f10fba439 \
|
--hash=sha256:bdb230b4943891321e06fc7def63c7aace16095be7d9cf3b1e01be2f10fba439 \
|
||||||
--hash=sha256:cffe3ab27871bc3ea47df5d8f7013945712c46a3cc5a95b6bee15887f1675c22 \
|
--hash=sha256:cffe3ab27871bc3ea47df5d8f7013945712c46a3cc5a95b6bee15887f1675c22 \
|
||||||
--hash=sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a \
|
--hash=sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a \
|
||||||
--hash=sha256:a5ca29ee66f8343ed336816c553e82d6cade48a3ad702b9ffa6125d187e2dedb \
|
--hash=sha256:a5ca29ee66f8343ed336816c553e82d6cade48a3ad702b9ffa6125d187e2dedb \
|
||||||
--hash=sha256:17c073de315745a1510393a96e680d20af8e67e324f70b42accbd4cb3315c9fb \
|
--hash=sha256:17c073de315745a1510393a96e680d20af8e67e324f70b42accbd4cb3315c9fb \
|
||||||
--hash=sha256:932bb1ea39a54e9ea27fc9232163059a0b8855256f4052e776357ad9add6f1c9 \
|
--hash=sha256:932bb1ea39a54e9ea27fc9232163059a0b8855256f4052e776357ad9add6f1c9 \
|
||||||
--hash=sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe \
|
--hash=sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe \
|
||||||
--hash=sha256:493d3299ebe5f5a7c66b9819eacdcfbbaaf1a8e84911ddffcdc48888497afecf
|
--hash=sha256:493d3299ebe5f5a7c66b9819eacdcfbbaaf1a8e84911ddffcdc48888497afecf
|
||||||
appdirs==1.4.4 \
|
appdirs==1.4.4 \
|
||||||
--hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 \
|
--hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 \
|
||||||
--hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41
|
--hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41
|
||||||
async-timeout==3.0.1; python_full_version >= "3.5.3" and python_version >= "3.6" \
|
async-timeout==3.0.1; python_full_version >= "3.5.3" and python_version >= "3.6" \
|
||||||
--hash=sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f \
|
--hash=sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f \
|
||||||
--hash=sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3
|
--hash=sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3
|
||||||
attrs==19.2.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
attrs==19.2.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
||||||
--hash=sha256:ec20e7a4825331c1b5ebf261d111e16fa9612c1f7a5e1f884f12bd53a664dfd2 \
|
--hash=sha256:ec20e7a4825331c1b5ebf261d111e16fa9612c1f7a5e1f884f12bd53a664dfd2 \
|
||||||
--hash=sha256:f913492e1663d3c36f502e5e9ba6cd13cf19d7fab50aa13239e420fef95e1396
|
--hash=sha256:f913492e1663d3c36f502e5e9ba6cd13cf19d7fab50aa13239e420fef95e1396
|
||||||
blessings==1.7; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
blessings==1.7; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
||||||
--hash=sha256:caad5211e7ba5afe04367cdd4cfc68fa886e2e08f6f35e76b7387d2109ccea6e \
|
--hash=sha256:caad5211e7ba5afe04367cdd4cfc68fa886e2e08f6f35e76b7387d2109ccea6e \
|
||||||
--hash=sha256:b1fdd7e7a675295630f9ae71527a8ebc10bfefa236b3d6aa4932ee4462c17ba3 \
|
--hash=sha256:b1fdd7e7a675295630f9ae71527a8ebc10bfefa236b3d6aa4932ee4462c17ba3 \
|
||||||
--hash=sha256:98e5854d805f50a5b58ac2333411b0482516a8210f23f43308baeb58d77c157d
|
--hash=sha256:98e5854d805f50a5b58ac2333411b0482516a8210f23f43308baeb58d77c157d
|
||||||
cbor2==4.0.1 \
|
cbor2==4.0.1 \
|
||||||
--hash=sha256:b0eb916c9ea226aa81e9091607737475d5b0e5c314fe8d5a87179fba449cd190 \
|
--hash=sha256:b0eb916c9ea226aa81e9091607737475d5b0e5c314fe8d5a87179fba449cd190 \
|
||||||
--hash=sha256:cee0d01e520563b5a73c72eace5c428bb68aefb1b3f7aee5d692d3af6a1e5172
|
--hash=sha256:cee0d01e520563b5a73c72eace5c428bb68aefb1b3f7aee5d692d3af6a1e5172
|
||||||
certifi==2018.4.16 \
|
certifi==2018.4.16 \
|
||||||
--hash=sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0 \
|
--hash=sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0 \
|
||||||
--hash=sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7
|
--hash=sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7
|
||||||
chardet==4.0.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" or python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" \
|
chardet==4.0.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" or python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" \
|
||||||
--hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5 \
|
--hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5 \
|
||||||
--hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa
|
--hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa
|
||||||
click==7.1.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
|
click==7.1.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
|
||||||
--hash=sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc \
|
--hash=sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc \
|
||||||
--hash=sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a
|
--hash=sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a
|
||||||
colorama==0.4.5; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
colorama==0.4.5; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
||||||
--hash=sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da \
|
--hash=sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da \
|
||||||
--hash=sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4
|
--hash=sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4
|
||||||
compare-locales==8.2.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") \
|
compare-locales==8.2.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") \
|
||||||
--hash=sha256:470d50d96c68f8e147daa3d70f29a7b750adefea450c5fa07e0f666c8083d854 \
|
--hash=sha256:470d50d96c68f8e147daa3d70f29a7b750adefea450c5fa07e0f666c8083d854 \
|
||||||
--hash=sha256:e6a1610151d357e74ee6c1f5e944f1868e449f83e478c84d92f7b86132f721d7
|
--hash=sha256:e6a1610151d357e74ee6c1f5e944f1868e449f83e478c84d92f7b86132f721d7
|
||||||
cookies==2.2.1 \
|
cookies==2.2.1 \
|
||||||
--hash=sha256:15bee753002dff684987b8df8c235288eb8d45f8191ae056254812dfd42c81d3 \
|
--hash=sha256:15bee753002dff684987b8df8c235288eb8d45f8191ae056254812dfd42c81d3 \
|
||||||
--hash=sha256:d6b698788cae4cfa4e62ef8643a9ca332b79bd96cb314294b864ae8d7eb3ee8e
|
--hash=sha256:d6b698788cae4cfa4e62ef8643a9ca332b79bd96cb314294b864ae8d7eb3ee8e
|
||||||
cram==0.7 \
|
cram==0.7 \
|
||||||
--hash=sha256:008e4e8b4d325cf040964b5f62460535b004a7bc816d54f8527a4d299edfe4a3 \
|
--hash=sha256:008e4e8b4d325cf040964b5f62460535b004a7bc816d54f8527a4d299edfe4a3 \
|
||||||
--hash=sha256:7da7445af2ce15b90aad5ec4792f857cef5786d71f14377e9eb994d8b8337f2f
|
--hash=sha256:7da7445af2ce15b90aad5ec4792f857cef5786d71f14377e9eb994d8b8337f2f
|
||||||
diskcache==4.1.0 \
|
diskcache==4.1.0 \
|
||||||
--hash=sha256:69b253a6ffe95bb4bafb483b97c24fca3c2c6c47b82e92b36486969a7e80d47d \
|
--hash=sha256:69b253a6ffe95bb4bafb483b97c24fca3c2c6c47b82e92b36486969a7e80d47d \
|
||||||
--hash=sha256:bcee5a59f9c264e2809e58d01be6569a3bbb1e36a1e0fb83f7ef9b2075f95ce0
|
--hash=sha256:bcee5a59f9c264e2809e58d01be6569a3bbb1e36a1e0fb83f7ef9b2075f95ce0
|
||||||
distro==1.4.0 \
|
distro==1.4.0 \
|
||||||
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4 \
|
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4 \
|
||||||
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57
|
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57
|
||||||
ecdsa==0.15; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") \
|
ecdsa==0.15; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") \
|
||||||
--hash=sha256:867ec9cf6df0b03addc8ef66b56359643cb5d0c1dc329df76ba7ecfe256c8061 \
|
--hash=sha256:867ec9cf6df0b03addc8ef66b56359643cb5d0c1dc329df76ba7ecfe256c8061 \
|
||||||
--hash=sha256:8f12ac317f8a1318efa75757ef0a651abe12e51fc1af8838fb91079445227277
|
--hash=sha256:8f12ac317f8a1318efa75757ef0a651abe12e51fc1af8838fb91079445227277
|
||||||
esprima==4.0.1 \
|
esprima==4.0.1 \
|
||||||
--hash=sha256:08db1a876d3c2910db9cfaeb83108193af5411fc3a3a66ebefacd390d21323ee
|
--hash=sha256:08db1a876d3c2910db9cfaeb83108193af5411fc3a3a66ebefacd390d21323ee
|
||||||
fluent.migrate==0.11 \
|
fluent.migrate==0.11 \
|
||||||
--hash=sha256:3b93fdba9cbc8702d160367ba3a0d5c120707fdde752af35aecf516ce80ed252
|
--hash=sha256:3b93fdba9cbc8702d160367ba3a0d5c120707fdde752af35aecf516ce80ed252
|
||||||
fluent.syntax==0.18.1 \
|
fluent.syntax==0.18.1 \
|
||||||
--hash=sha256:0e63679fa4f1b3042565220a5127b4bab842424f07d6a13c12299e3b3835486a \
|
--hash=sha256:0e63679fa4f1b3042565220a5127b4bab842424f07d6a13c12299e3b3835486a \
|
||||||
--hash=sha256:3a55f5e605d1b029a65cc8b6492c86ec4608e15447e73db1495de11fd46c104f
|
--hash=sha256:3a55f5e605d1b029a65cc8b6492c86ec4608e15447e73db1495de11fd46c104f
|
||||||
glean-parser==6.1.2 \
|
giturlparse==0.10.0; python_version >= "3.6" \
|
||||||
--hash=sha256:e801af6463b7e0ba79d97ddfc0a58d9d71121c93cea601417571e33fa8142270 \
|
--hash=sha256:04ba1a3a099c3093fa8d24a422913c6a9b2c2cd22bcffc939cf72e3e98f672d7 \
|
||||||
--hash=sha256:12a0fecedc1144d77fa571e0422ff3fea4dbadc381d631bea800a6b2f58f4f7f
|
--hash=sha256:2595ab291d30717cda8474b874c9fd509f1b9802ad7f6968c36a45e4b13eb337
|
||||||
idna-ssl==1.1.0; python_version < "3.7" and python_version >= "3.6" \
|
glean-parser==6.1.2 \
|
||||||
--hash=sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c
|
--hash=sha256:e801af6463b7e0ba79d97ddfc0a58d9d71121c93cea601417571e33fa8142270 \
|
||||||
idna==2.10; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" or python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version < "3.7" and python_version >= "3.6" and python_full_version >= "3.4.0" or python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \
|
--hash=sha256:12a0fecedc1144d77fa571e0422ff3fea4dbadc381d631bea800a6b2f58f4f7f
|
||||||
--hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 \
|
idna-ssl==1.1.0; python_version < "3.7" and python_version >= "3.6" \
|
||||||
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6
|
--hash=sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c
|
||||||
importlib-metadata==1.7.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
idna==2.10; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" or python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.7" or python_version < "3.7" and python_version >= "3.6" and python_full_version >= "3.4.0" or python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" \
|
||||||
--hash=sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070 \
|
--hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 \
|
||||||
--hash=sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83
|
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6
|
||||||
iso8601==0.1.14; python_version <= "3.6" \
|
importlib-metadata==1.7.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
||||||
--hash=sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004 \
|
--hash=sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070 \
|
||||||
--hash=sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79
|
--hash=sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83
|
||||||
jinja2==2.11.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
|
iso8601==0.1.14; python_version <= "3.6" \
|
||||||
--hash=sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419 \
|
--hash=sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004 \
|
||||||
--hash=sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6
|
--hash=sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79
|
||||||
jsmin==2.1.0 \
|
jinja2==2.11.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \
|
||||||
--hash=sha256:5d07bf0251a4128e5e8e8eef603849b6b5741c337bff087731a248f9cc774f56
|
--hash=sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419 \
|
||||||
json-e==2.7.0 \
|
--hash=sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6
|
||||||
--hash=sha256:d8c1ec3f5bbc7728c3a504ebe58829f283c64eca230871e4eefe974b4cdaae4a
|
jsmin==2.1.0 \
|
||||||
jsonschema==3.2.0 \
|
--hash=sha256:5d07bf0251a4128e5e8e8eef603849b6b5741c337bff087731a248f9cc774f56
|
||||||
--hash=sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163 \
|
json-e==2.7.0 \
|
||||||
--hash=sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a
|
--hash=sha256:d8c1ec3f5bbc7728c3a504ebe58829f283c64eca230871e4eefe974b4cdaae4a
|
||||||
looseversion==1.0.1; python_version >= "3" \
|
jsonschema==3.2.0 \
|
||||||
--hash=sha256:a205beabd0ffd40488edb9ccb3a39134510fc7c0c2847a25079f559e59c004ac \
|
--hash=sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163 \
|
||||||
--hash=sha256:b339dfde67680e9c5c2e96673e52bee9f94d2f0e1b8f4cbfd86d32311e86b952
|
--hash=sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a
|
||||||
markupsafe==1.1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" or python_full_version >= "3.5.0" \
|
looseversion==1.0.1; python_version >= "3" \
|
||||||
--hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \
|
--hash=sha256:a205beabd0ffd40488edb9ccb3a39134510fc7c0c2847a25079f559e59c004ac \
|
||||||
--hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \
|
--hash=sha256:b339dfde67680e9c5c2e96673e52bee9f94d2f0e1b8f4cbfd86d32311e86b952
|
||||||
--hash=sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183 \
|
markupsafe==1.1.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" or python_full_version >= "3.5.0" \
|
||||||
--hash=sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b \
|
--hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \
|
||||||
--hash=sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e \
|
--hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \
|
||||||
--hash=sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f \
|
--hash=sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183 \
|
||||||
--hash=sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1 \
|
--hash=sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b \
|
||||||
--hash=sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5 \
|
--hash=sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e \
|
||||||
--hash=sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1 \
|
--hash=sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f \
|
||||||
--hash=sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735 \
|
--hash=sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1 \
|
||||||
--hash=sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21 \
|
--hash=sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5 \
|
||||||
--hash=sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235 \
|
--hash=sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1 \
|
||||||
--hash=sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b \
|
--hash=sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735 \
|
||||||
--hash=sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f \
|
--hash=sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21 \
|
||||||
--hash=sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905 \
|
--hash=sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235 \
|
||||||
--hash=sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1 \
|
--hash=sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b \
|
||||||
--hash=sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d \
|
--hash=sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f \
|
||||||
--hash=sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff \
|
--hash=sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905 \
|
||||||
--hash=sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5 \
|
--hash=sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1 \
|
||||||
--hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \
|
--hash=sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d \
|
||||||
--hash=sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e \
|
--hash=sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff \
|
||||||
--hash=sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f \
|
--hash=sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5 \
|
||||||
--hash=sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0 \
|
--hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \
|
||||||
--hash=sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7 \
|
--hash=sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e \
|
||||||
--hash=sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66 \
|
--hash=sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f \
|
||||||
--hash=sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5 \
|
--hash=sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0 \
|
||||||
--hash=sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d \
|
--hash=sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7 \
|
||||||
--hash=sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193 \
|
--hash=sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66 \
|
||||||
--hash=sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e \
|
--hash=sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5 \
|
||||||
--hash=sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6 \
|
--hash=sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d \
|
||||||
--hash=sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1 \
|
--hash=sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193 \
|
||||||
--hash=sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1 \
|
--hash=sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e \
|
||||||
--hash=sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f \
|
--hash=sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6 \
|
||||||
--hash=sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2 \
|
--hash=sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1 \
|
||||||
--hash=sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c \
|
--hash=sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1 \
|
||||||
--hash=sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15 \
|
--hash=sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f \
|
||||||
--hash=sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2 \
|
--hash=sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2 \
|
||||||
--hash=sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42 \
|
--hash=sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c \
|
||||||
--hash=sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2 \
|
--hash=sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15 \
|
||||||
--hash=sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032 \
|
--hash=sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2 \
|
||||||
--hash=sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b \
|
--hash=sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42 \
|
||||||
--hash=sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b \
|
--hash=sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2 \
|
||||||
--hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be \
|
--hash=sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032 \
|
||||||
--hash=sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c \
|
--hash=sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b \
|
||||||
--hash=sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb \
|
--hash=sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b \
|
||||||
--hash=sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014 \
|
--hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be \
|
||||||
--hash=sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850 \
|
--hash=sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c \
|
||||||
--hash=sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85 \
|
--hash=sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb \
|
||||||
--hash=sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621 \
|
--hash=sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014 \
|
||||||
--hash=sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39 \
|
--hash=sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850 \
|
||||||
--hash=sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8 \
|
--hash=sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85 \
|
||||||
--hash=sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b
|
--hash=sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621 \
|
||||||
mohawk==0.3.4 \
|
--hash=sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39 \
|
||||||
--hash=sha256:b3f85ffa93a5c7d2f9cc591246ef9f8ac4a9fa716bfd5bae0377699a2d89d78c \
|
--hash=sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8 \
|
||||||
--hash=sha256:e98b331d9fa9ece7b8be26094cbe2d57613ae882133cc755167268a984bc0ab3
|
--hash=sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b
|
||||||
mozilla-version==0.3.4 \
|
mohawk==0.3.4 \
|
||||||
--hash=sha256:3ed4deb7a6fb25c83a5346ef4de08ddff9b2ddc4d16dd8fafb4a84978cc71255 \
|
--hash=sha256:b3f85ffa93a5c7d2f9cc591246ef9f8ac4a9fa716bfd5bae0377699a2d89d78c \
|
||||||
--hash=sha256:ce5741c2e7d12c30b53de9f79e30d6ac2a8bd4c93be711d30c7a7a08e32a094f
|
--hash=sha256:e98b331d9fa9ece7b8be26094cbe2d57613ae882133cc755167268a984bc0ab3
|
||||||
multidict==5.1.0; python_version >= "3.6" \
|
mozilla-repo-urls==0.0.3 \
|
||||||
--hash=sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f \
|
--hash=sha256:3b2f9b42111ce3d50ecdcd081a62229e1fdc8f5472adbf405abe12d3ba8e8af5 \
|
||||||
--hash=sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf \
|
--hash=sha256:673c80a4d0ed449093203b88e119e0bf1074026f891c1dd50aa04d534fd0658c
|
||||||
--hash=sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281 \
|
mozilla-version==0.3.4 \
|
||||||
--hash=sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d \
|
--hash=sha256:3ed4deb7a6fb25c83a5346ef4de08ddff9b2ddc4d16dd8fafb4a84978cc71255 \
|
||||||
--hash=sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d \
|
--hash=sha256:ce5741c2e7d12c30b53de9f79e30d6ac2a8bd4c93be711d30c7a7a08e32a094f
|
||||||
--hash=sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da \
|
multidict==5.1.0; python_version >= "3.6" \
|
||||||
--hash=sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224 \
|
--hash=sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f \
|
||||||
--hash=sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26 \
|
--hash=sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf \
|
||||||
--hash=sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6 \
|
--hash=sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281 \
|
||||||
--hash=sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76 \
|
--hash=sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d \
|
||||||
--hash=sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a \
|
--hash=sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d \
|
||||||
--hash=sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f \
|
--hash=sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da \
|
||||||
--hash=sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348 \
|
--hash=sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224 \
|
||||||
--hash=sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93 \
|
--hash=sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26 \
|
||||||
--hash=sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9 \
|
--hash=sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6 \
|
||||||
--hash=sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37 \
|
--hash=sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76 \
|
||||||
--hash=sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5 \
|
--hash=sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a \
|
||||||
--hash=sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632 \
|
--hash=sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f \
|
||||||
--hash=sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952 \
|
--hash=sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348 \
|
||||||
--hash=sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79 \
|
--hash=sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93 \
|
||||||
--hash=sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456 \
|
--hash=sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9 \
|
||||||
--hash=sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7 \
|
--hash=sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37 \
|
||||||
--hash=sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635 \
|
--hash=sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5 \
|
||||||
--hash=sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a \
|
--hash=sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632 \
|
||||||
--hash=sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea \
|
--hash=sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952 \
|
||||||
--hash=sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656 \
|
--hash=sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79 \
|
||||||
--hash=sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3 \
|
--hash=sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456 \
|
||||||
--hash=sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93 \
|
--hash=sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7 \
|
||||||
--hash=sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647 \
|
--hash=sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635 \
|
||||||
--hash=sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d \
|
--hash=sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a \
|
||||||
--hash=sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8 \
|
--hash=sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea \
|
||||||
--hash=sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1 \
|
--hash=sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656 \
|
||||||
--hash=sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841 \
|
--hash=sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3 \
|
||||||
--hash=sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda \
|
--hash=sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93 \
|
||||||
--hash=sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80 \
|
--hash=sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647 \
|
||||||
--hash=sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359 \
|
--hash=sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d \
|
||||||
--hash=sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5
|
--hash=sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8 \
|
||||||
packaging==20.9; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
--hash=sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1 \
|
||||||
--hash=sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a \
|
--hash=sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841 \
|
||||||
--hash=sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5
|
--hash=sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda \
|
||||||
pathspec==0.9.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
--hash=sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80 \
|
||||||
--hash=sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a \
|
--hash=sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359 \
|
||||||
--hash=sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1
|
--hash=sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5
|
||||||
pip-tools==5.5.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
packaging==20.9; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
||||||
--hash=sha256:cb0108391366b3ef336185097b3c2c0f3fa115b15098dafbda5e78aef70ea114 \
|
--hash=sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a \
|
||||||
--hash=sha256:10841c1e56c234d610d0466447685b9ea4ee4a2c274f858c0ef3c33d9bd0d985
|
--hash=sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5
|
||||||
pip==21.2.4; python_version >= "3.6" \
|
pathspec==0.9.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
||||||
--hash=sha256:fa9ebb85d3fd607617c0c44aca302b1b45d87f9c2a1649b46c26167ca4296323 \
|
--hash=sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a \
|
||||||
--hash=sha256:0eb8a1516c3d138ae8689c0c1a60fde7143310832f9dc77e11d8a4bc62de193b
|
--hash=sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1
|
||||||
ply==3.10 \
|
pip-tools==5.5.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
||||||
--hash=sha256:96e94af7dd7031d8d6dd6e2a8e0de593b511c211a86e28a9c9621c275ac8bacb
|
--hash=sha256:cb0108391366b3ef336185097b3c2c0f3fa115b15098dafbda5e78aef70ea114 \
|
||||||
pyasn1-modules==0.2.8 \
|
--hash=sha256:10841c1e56c234d610d0466447685b9ea4ee4a2c274f858c0ef3c33d9bd0d985
|
||||||
--hash=sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e \
|
pip==21.2.4; python_version >= "3.6" \
|
||||||
--hash=sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199 \
|
--hash=sha256:fa9ebb85d3fd607617c0c44aca302b1b45d87f9c2a1649b46c26167ca4296323 \
|
||||||
--hash=sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405 \
|
--hash=sha256:0eb8a1516c3d138ae8689c0c1a60fde7143310832f9dc77e11d8a4bc62de193b
|
||||||
--hash=sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb \
|
ply==3.10 \
|
||||||
--hash=sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8 \
|
--hash=sha256:96e94af7dd7031d8d6dd6e2a8e0de593b511c211a86e28a9c9621c275ac8bacb
|
||||||
--hash=sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74 \
|
pyasn1-modules==0.2.8 \
|
||||||
--hash=sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d \
|
--hash=sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e \
|
||||||
--hash=sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45 \
|
--hash=sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199 \
|
||||||
--hash=sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4 \
|
--hash=sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405 \
|
||||||
--hash=sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811 \
|
--hash=sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb \
|
||||||
--hash=sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed \
|
--hash=sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8 \
|
||||||
--hash=sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0 \
|
--hash=sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74 \
|
||||||
--hash=sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd
|
--hash=sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d \
|
||||||
pyasn1==0.4.8 \
|
--hash=sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45 \
|
||||||
--hash=sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3 \
|
--hash=sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4 \
|
||||||
--hash=sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf \
|
--hash=sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811 \
|
||||||
--hash=sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00 \
|
--hash=sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed \
|
||||||
--hash=sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8 \
|
--hash=sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0 \
|
||||||
--hash=sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d \
|
--hash=sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd
|
||||||
--hash=sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86 \
|
pyasn1==0.4.8 \
|
||||||
--hash=sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7 \
|
--hash=sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3 \
|
||||||
--hash=sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576 \
|
--hash=sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf \
|
||||||
--hash=sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12 \
|
--hash=sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00 \
|
||||||
--hash=sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2 \
|
--hash=sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8 \
|
||||||
--hash=sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359 \
|
--hash=sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d \
|
||||||
--hash=sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776 \
|
--hash=sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86 \
|
||||||
--hash=sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba
|
--hash=sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7 \
|
||||||
pylru==1.0.9 \
|
--hash=sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576 \
|
||||||
--hash=sha256:71376192671f0ad1690b2a7427d39a29b1df994c8469a9b46b03ed7e28c0172c
|
--hash=sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12 \
|
||||||
pyparsing==2.4.7; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \
|
--hash=sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2 \
|
||||||
--hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
|
--hash=sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359 \
|
||||||
--hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1
|
--hash=sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776 \
|
||||||
pyrsistent==0.16.0 \
|
--hash=sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba
|
||||||
--hash=sha256:28669905fe725965daa16184933676547c5bb40a5153055a8dee2a4bd7933ad3
|
pylru==1.0.9 \
|
||||||
python-hglib==2.4 \
|
--hash=sha256:71376192671f0ad1690b2a7427d39a29b1df994c8469a9b46b03ed7e28c0172c
|
||||||
--hash=sha256:693d6ed92a6566e78802c7a03c256cda33d08c63ad3f00fcfa11379b184b9462
|
pyparsing==2.4.7; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \
|
||||||
pytoml==0.1.10 \
|
--hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
|
||||||
--hash=sha256:98399eabd927cd3e12457525315b6abbc5abf9a6f392ab578cbcec327f73890c
|
--hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1
|
||||||
pyyaml==5.4.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") \
|
pyrsistent==0.16.0 \
|
||||||
--hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \
|
--hash=sha256:28669905fe725965daa16184933676547c5bb40a5153055a8dee2a4bd7933ad3
|
||||||
--hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \
|
python-hglib==2.4 \
|
||||||
--hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \
|
--hash=sha256:693d6ed92a6566e78802c7a03c256cda33d08c63ad3f00fcfa11379b184b9462
|
||||||
--hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \
|
pytoml==0.1.10 \
|
||||||
--hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \
|
--hash=sha256:98399eabd927cd3e12457525315b6abbc5abf9a6f392ab578cbcec327f73890c
|
||||||
--hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \
|
pyyaml==5.4.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") \
|
||||||
--hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \
|
--hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \
|
||||||
--hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \
|
--hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \
|
||||||
--hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \
|
--hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \
|
||||||
--hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \
|
--hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \
|
||||||
--hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \
|
--hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \
|
||||||
--hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \
|
--hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \
|
||||||
--hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \
|
--hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \
|
||||||
--hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0 \
|
--hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \
|
||||||
--hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \
|
--hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \
|
||||||
--hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \
|
--hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \
|
||||||
--hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \
|
--hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \
|
||||||
--hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \
|
--hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \
|
||||||
--hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \
|
--hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \
|
||||||
--hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \
|
--hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0 \
|
||||||
--hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \
|
--hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \
|
||||||
--hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \
|
--hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \
|
||||||
--hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \
|
--hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \
|
||||||
--hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \
|
--hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \
|
||||||
--hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \
|
--hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \
|
||||||
--hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \
|
--hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \
|
||||||
--hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \
|
--hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \
|
||||||
--hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \
|
--hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \
|
||||||
--hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e
|
--hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \
|
||||||
redo==2.0.3 \
|
--hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \
|
||||||
--hash=sha256:36784bf8ae766e14f9db0e377ccfa02835d648321d2007b6ae0bf4fd612c0f94 \
|
--hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \
|
||||||
--hash=sha256:71161cb0e928d824092a5f16203939bbc0867ce4c4685db263cf22c3ae7634a8
|
--hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \
|
||||||
requests-unixsocket==0.2.0 \
|
--hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \
|
||||||
--hash=sha256:9e5c1a20afc3cf786197ae59c79bcdb0e7565f218f27df5f891307ee8817c1ea \
|
--hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \
|
||||||
--hash=sha256:014d07bfb66dc805a011a8b4b306cf4ec96d2eddb589f6b2b5765e626f0dc0cc
|
--hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e
|
||||||
requests==2.25.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
redo==2.0.3 \
|
||||||
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e \
|
--hash=sha256:36784bf8ae766e14f9db0e377ccfa02835d648321d2007b6ae0bf4fd612c0f94 \
|
||||||
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804
|
--hash=sha256:71161cb0e928d824092a5f16203939bbc0867ce4c4685db263cf22c3ae7634a8
|
||||||
responses==0.10.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
requests-unixsocket==0.2.0 \
|
||||||
--hash=sha256:97193c0183d63fba8cd3a041c75464e4b09ea0aff6328800d1546598567dde0b \
|
--hash=sha256:9e5c1a20afc3cf786197ae59c79bcdb0e7565f218f27df5f891307ee8817c1ea \
|
||||||
--hash=sha256:502d9c0c8008439cfcdef7e251f507fcfdd503b56e8c0c87c3c3e3393953f790
|
--hash=sha256:014d07bfb66dc805a011a8b4b306cf4ec96d2eddb589f6b2b5765e626f0dc0cc
|
||||||
rsa==3.1.4 \
|
requests==2.25.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
||||||
--hash=sha256:e2b0b05936c276b1edd2e1525553233b666df9e29b5c3ba223eed738277c82a0
|
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e \
|
||||||
sentry-sdk==0.14.3 \
|
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804
|
||||||
--hash=sha256:bb90a4e19c7233a580715fc986cc44be2c48fc10b31e71580a2037e1c94b6950 \
|
responses==0.10.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
||||||
--hash=sha256:23808d571d2461a4ce3784ec12bbee5bdb8c026c143fe79d36cef8a6d653e71f
|
--hash=sha256:97193c0183d63fba8cd3a041c75464e4b09ea0aff6328800d1546598567dde0b \
|
||||||
setuptools==51.2.0; python_version >= "3.6" \
|
--hash=sha256:502d9c0c8008439cfcdef7e251f507fcfdd503b56e8c0c87c3c3e3393953f790
|
||||||
--hash=sha256:56948bf25c682e166cf2bfe7c1ad63e5745849b50d1ae7b0f8bff5decdcf34f2 \
|
rsa==3.1.4 \
|
||||||
--hash=sha256:7ef59b1790b3491f8d321f531eccc11517a07a4d7637e498465cd834d80d4c2c
|
--hash=sha256:e2b0b05936c276b1edd2e1525553233b666df9e29b5c3ba223eed738277c82a0
|
||||||
six==1.13.0; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.2.0") \
|
sentry-sdk==0.14.3 \
|
||||||
--hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \
|
--hash=sha256:bb90a4e19c7233a580715fc986cc44be2c48fc10b31e71580a2037e1c94b6950 \
|
||||||
--hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66
|
--hash=sha256:23808d571d2461a4ce3784ec12bbee5bdb8c026c143fe79d36cef8a6d653e71f
|
||||||
slugid==2.0.0 \
|
setuptools==51.2.0; python_version >= "3.6" \
|
||||||
--hash=sha256:aec8b0e01c4ad32e38e12d609eab3ec912fd129aaf6b2ded0199b56a5f8fd67c \
|
--hash=sha256:56948bf25c682e166cf2bfe7c1ad63e5745849b50d1ae7b0f8bff5decdcf34f2 \
|
||||||
--hash=sha256:a950d98b72691178bdd4d6c52743c4a2aa039207cf7a97d71060a111ff9ba297
|
--hash=sha256:7ef59b1790b3491f8d321f531eccc11517a07a4d7637e498465cd834d80d4c2c
|
||||||
taskcluster-taskgraph==2.0.0 \
|
six==1.13.0; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.2.0") \
|
||||||
--hash=sha256:93eff40ba39a29cd290fc25a2124ed9bf5806d87891edd7e8de35df568708141 \
|
--hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \
|
||||||
--hash=sha256:3d22ab488071ddc82997b33fc6c1c524a44bdc7e14b30a274d99dbbdd7389502
|
--hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66
|
||||||
taskcluster-urls==13.0.1 \
|
slugid==2.0.0 \
|
||||||
--hash=sha256:b25e122ecec249c4299ac7b20b08db76e3e2025bdaeb699a9d444556de5fd367 \
|
--hash=sha256:aec8b0e01c4ad32e38e12d609eab3ec912fd129aaf6b2ded0199b56a5f8fd67c \
|
||||||
--hash=sha256:5e25e7e6818e8877178b175ff43d2e6548afad72694aa125f404a7329ece0973 \
|
--hash=sha256:a950d98b72691178bdd4d6c52743c4a2aa039207cf7a97d71060a111ff9ba297
|
||||||
--hash=sha256:f66dcbd6572a6216ab65949f0fa0b91f2df647918028436c384e6af5cd12ae2b
|
taskcluster-taskgraph==3.2.0 \
|
||||||
taskcluster==44.2.2 \
|
--hash=sha256:941d96fd36c20b0e84e322d2c25be04fe5f258405793af5e086bbec698cbcb17 \
|
||||||
--hash=sha256:c1b0e82be25b1ed17e07c90b24a382634b2bfce273fdf2682d94568abe10716c \
|
--hash=sha256:fafcd1bfd8ec8b2f57db4e4d87d5b881da3ad7119d78d407d22b4b71b805d1bf
|
||||||
--hash=sha256:846d73c597f0f47dd8525c85c8d9bc41111d5200b090690d3f16b2f57c56a2e1 \
|
taskcluster-urls==13.0.1 \
|
||||||
--hash=sha256:0266a6a901e1a2ec838984a7f24e7adb6d58f9f2e221a7f613388f8f23f786fc
|
--hash=sha256:b25e122ecec249c4299ac7b20b08db76e3e2025bdaeb699a9d444556de5fd367 \
|
||||||
tqdm==4.62.3; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
--hash=sha256:5e25e7e6818e8877178b175ff43d2e6548afad72694aa125f404a7329ece0973 \
|
||||||
--hash=sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c \
|
--hash=sha256:f66dcbd6572a6216ab65949f0fa0b91f2df647918028436c384e6af5cd12ae2b
|
||||||
--hash=sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d
|
taskcluster==44.2.2 \
|
||||||
typing-extensions==3.10.0.0; python_version < "3.8" and python_version >= "3.6" or python_version >= "3.6" \
|
--hash=sha256:c1b0e82be25b1ed17e07c90b24a382634b2bfce273fdf2682d94568abe10716c \
|
||||||
--hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \
|
--hash=sha256:846d73c597f0f47dd8525c85c8d9bc41111d5200b090690d3f16b2f57c56a2e1 \
|
||||||
--hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84 \
|
--hash=sha256:0266a6a901e1a2ec838984a7f24e7adb6d58f9f2e221a7f613388f8f23f786fc
|
||||||
--hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342
|
tqdm==4.62.3; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
||||||
urllib3==1.26.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") \
|
--hash=sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c \
|
||||||
--hash=sha256:bad31cb622ceee0ab46c4c884cf61957def0ff2e644de0a7a093678844c9ccac \
|
--hash=sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d
|
||||||
--hash=sha256:4849f132941d68144df0a3785ccc4fe423430ba5db0108d045c8cadbc90f517a
|
typing-extensions==3.10.0.0; python_version < "3.8" and python_version >= "3.6" or python_version >= "3.6" \
|
||||||
voluptuous==0.12.1 \
|
--hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \
|
||||||
--hash=sha256:8ace33fcf9e6b1f59406bfaf6b8ec7bcc44266a9f29080b4deb4fe6ff2492386 \
|
--hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84 \
|
||||||
--hash=sha256:663572419281ddfaf4b4197fd4942d181630120fb39b333e3adad70aeb56444b
|
--hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342
|
||||||
wheel==0.37.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
urllib3==1.26.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") \
|
||||||
--hash=sha256:21014b2bd93c6d0034b6ba5d35e4eb284340e09d63c59aef6fc14b0f346146fd \
|
--hash=sha256:bad31cb622ceee0ab46c4c884cf61957def0ff2e644de0a7a093678844c9ccac \
|
||||||
--hash=sha256:e2ef7239991699e3355d54f8e968a21bb940a1dbf34a4d226741e64462516fad
|
--hash=sha256:4849f132941d68144df0a3785ccc4fe423430ba5db0108d045c8cadbc90f517a
|
||||||
yamllint==1.23.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
voluptuous==0.12.1 \
|
||||||
--hash=sha256:0fa69bf8a86182b7fe14918bdd3a30354c869966bbc7cbfff176af71bda9c806 \
|
--hash=sha256:8ace33fcf9e6b1f59406bfaf6b8ec7bcc44266a9f29080b4deb4fe6ff2492386 \
|
||||||
--hash=sha256:59f3ff77f44e7f46be6aecdb985830f73a1c51e290b7082a7d38c2ae1940f4a9
|
--hash=sha256:663572419281ddfaf4b4197fd4942d181630120fb39b333e3adad70aeb56444b
|
||||||
yarl==1.6.3; python_version >= "3.6" \
|
wheel==0.37.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0") \
|
||||||
--hash=sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434 \
|
--hash=sha256:21014b2bd93c6d0034b6ba5d35e4eb284340e09d63c59aef6fc14b0f346146fd \
|
||||||
--hash=sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478 \
|
--hash=sha256:e2ef7239991699e3355d54f8e968a21bb940a1dbf34a4d226741e64462516fad
|
||||||
--hash=sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6 \
|
yamllint==1.23.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
|
||||||
--hash=sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e \
|
--hash=sha256:0fa69bf8a86182b7fe14918bdd3a30354c869966bbc7cbfff176af71bda9c806 \
|
||||||
--hash=sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406 \
|
--hash=sha256:59f3ff77f44e7f46be6aecdb985830f73a1c51e290b7082a7d38c2ae1940f4a9
|
||||||
--hash=sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76 \
|
yarl==1.6.3; python_version >= "3.6" \
|
||||||
--hash=sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366 \
|
--hash=sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434 \
|
||||||
--hash=sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721 \
|
--hash=sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478 \
|
||||||
--hash=sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643 \
|
--hash=sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6 \
|
||||||
--hash=sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e \
|
--hash=sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e \
|
||||||
--hash=sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3 \
|
--hash=sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406 \
|
||||||
--hash=sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8 \
|
--hash=sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76 \
|
||||||
--hash=sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a \
|
--hash=sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366 \
|
||||||
--hash=sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c \
|
--hash=sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721 \
|
||||||
--hash=sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f \
|
--hash=sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643 \
|
||||||
--hash=sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970 \
|
--hash=sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e \
|
||||||
--hash=sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e \
|
--hash=sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3 \
|
||||||
--hash=sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50 \
|
--hash=sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8 \
|
||||||
--hash=sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2 \
|
--hash=sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a \
|
||||||
--hash=sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec \
|
--hash=sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c \
|
||||||
--hash=sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71 \
|
--hash=sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f \
|
||||||
--hash=sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc \
|
--hash=sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970 \
|
||||||
--hash=sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959 \
|
--hash=sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e \
|
||||||
--hash=sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2 \
|
--hash=sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50 \
|
||||||
--hash=sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2 \
|
--hash=sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2 \
|
||||||
--hash=sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896 \
|
--hash=sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec \
|
||||||
--hash=sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a \
|
--hash=sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71 \
|
||||||
--hash=sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e \
|
--hash=sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc \
|
||||||
--hash=sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724 \
|
--hash=sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959 \
|
||||||
--hash=sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c \
|
--hash=sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2 \
|
||||||
--hash=sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25 \
|
--hash=sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2 \
|
||||||
--hash=sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96 \
|
--hash=sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896 \
|
||||||
--hash=sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0 \
|
--hash=sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a \
|
||||||
--hash=sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4 \
|
--hash=sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e \
|
||||||
--hash=sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424 \
|
--hash=sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724 \
|
||||||
--hash=sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6 \
|
--hash=sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c \
|
||||||
--hash=sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10
|
--hash=sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25 \
|
||||||
zipp==3.4.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" or python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.5.0" and python_version < "3.8" and python_version >= "3.6" \
|
--hash=sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96 \
|
||||||
--hash=sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098 \
|
--hash=sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0 \
|
||||||
--hash=sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76
|
--hash=sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4 \
|
||||||
|
--hash=sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424 \
|
||||||
|
--hash=sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6 \
|
||||||
|
--hash=sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10
|
||||||
|
zipp==3.4.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" or python_version >= "3.6" and python_full_version < "3.0.0" and python_version < "3.8" or python_full_version >= "3.5.0" and python_version < "3.8" and python_version >= "3.6" \
|
||||||
|
--hash=sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098 \
|
||||||
|
--hash=sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
Metadata-Version: 2.1
|
Metadata-Version: 2.1
|
||||||
Name: taskcluster-taskgraph
|
Name: taskcluster-taskgraph
|
||||||
Version: 3.0.0
|
Version: 3.2.0
|
||||||
Summary: Build taskcluster taskgraphs
|
Summary: Build taskcluster taskgraphs
|
||||||
Home-page: https://github.com/taskcluster/taskgraph
|
Home-page: https://github.com/taskcluster/taskgraph
|
||||||
License: UNKNOWN
|
License: UNKNOWN
|
||||||
|
|
@ -18,6 +18,7 @@ License-File: LICENSE
|
||||||
Requires-Dist: appdirs (>=1.4)
|
Requires-Dist: appdirs (>=1.4)
|
||||||
Requires-Dist: attrs (>=19.1.0)
|
Requires-Dist: attrs (>=19.1.0)
|
||||||
Requires-Dist: json-e (>=2.7)
|
Requires-Dist: json-e (>=2.7)
|
||||||
|
Requires-Dist: mozilla-repo-urls
|
||||||
Requires-Dist: PyYAML (>=5.4)
|
Requires-Dist: PyYAML (>=5.4)
|
||||||
Requires-Dist: redo (>=2.0)
|
Requires-Dist: redo (>=2.0)
|
||||||
Requires-Dist: requests (>=2.25)
|
Requires-Dist: requests (>=2.25)
|
||||||
|
|
@ -9,7 +9,7 @@ taskgraph/generator.py,sha256=ZfSb8dek6tQRxfpHbvQP2KMxXFzmhqwN821tOlNcvzo,15118
|
||||||
taskgraph/graph.py,sha256=9tE3bSSBRHvRLgJzK4dTieGT3RrzQZdR1YbKizEhzlw,4667
|
taskgraph/graph.py,sha256=9tE3bSSBRHvRLgJzK4dTieGT3RrzQZdR1YbKizEhzlw,4667
|
||||||
taskgraph/main.py,sha256=E7dC1q14L4psrNfUe-PMC8QH4cYjsIs91I-aVmzeBaI,23551
|
taskgraph/main.py,sha256=E7dC1q14L4psrNfUe-PMC8QH4cYjsIs91I-aVmzeBaI,23551
|
||||||
taskgraph/morph.py,sha256=8qxYdruEQkbHGqv7dh3e1OWhH9Y5i6bFUKzDMs-Ctnw,9625
|
taskgraph/morph.py,sha256=8qxYdruEQkbHGqv7dh3e1OWhH9Y5i6bFUKzDMs-Ctnw,9625
|
||||||
taskgraph/parameters.py,sha256=rye7dxD3A_Voh9w0Ru28zgZ8rGVv5enUu-k5lE7HvEk,11725
|
taskgraph/parameters.py,sha256=Ke-07fA2Qcynzbp-wfmO-VnQ4BGF9inr0hsrC5iyL-8,11792
|
||||||
taskgraph/target_tasks.py,sha256=41BIVwiATy8DCQujPduTtnFmgHlKOfw6RPGL4b20WO8,3324
|
taskgraph/target_tasks.py,sha256=41BIVwiATy8DCQujPduTtnFmgHlKOfw6RPGL4b20WO8,3324
|
||||||
taskgraph/task.py,sha256=QCrOzMaTsy5QHShKUo89XgjJVMl3cSZGZJPLuHCXItE,3132
|
taskgraph/task.py,sha256=QCrOzMaTsy5QHShKUo89XgjJVMl3cSZGZJPLuHCXItE,3132
|
||||||
taskgraph/taskgraph.py,sha256=tfj0ZMqjuwEQDET0W57EcP-_KBEbqkxJci9Z6DkeOEQ,2397
|
taskgraph/taskgraph.py,sha256=tfj0ZMqjuwEQDET0W57EcP-_KBEbqkxJci9Z6DkeOEQ,2397
|
||||||
|
|
@ -17,7 +17,7 @@ taskgraph/actions/__init__.py,sha256=lVP1e0YyELg7-_42MWWDbT0cKv_p53BApVE6vWOiPww
|
||||||
taskgraph/actions/add_new_jobs.py,sha256=mX_DFDJaQUHetjyMNi5b8zPCCeqfzDrCjDg5DxTaA-I,1831
|
taskgraph/actions/add_new_jobs.py,sha256=mX_DFDJaQUHetjyMNi5b8zPCCeqfzDrCjDg5DxTaA-I,1831
|
||||||
taskgraph/actions/cancel.py,sha256=UQSt_6y3S6PXNmUo_mNaUOuDvK2bixWjzdjTKXieEEg,1309
|
taskgraph/actions/cancel.py,sha256=UQSt_6y3S6PXNmUo_mNaUOuDvK2bixWjzdjTKXieEEg,1309
|
||||||
taskgraph/actions/cancel_all.py,sha256=-ETWKl8BHkk5HjGZRIJpUsFOySE6co0pL0dBDupolu8,1947
|
taskgraph/actions/cancel_all.py,sha256=-ETWKl8BHkk5HjGZRIJpUsFOySE6co0pL0dBDupolu8,1947
|
||||||
taskgraph/actions/registry.py,sha256=p-YTqnhRPSouOqhSoRL5QgUkpO_ab4XIMSFKreu7E_8,13252
|
taskgraph/actions/registry.py,sha256=xmhoEGMyYj6TTRFwMowZAUp0aqvtLvdVfmRWM7Yh7xo,13122
|
||||||
taskgraph/actions/retrigger.py,sha256=awSC8XRtPJxADz5tbEWTKdNEudG8SpwUOM7z2lXxH1U,9382
|
taskgraph/actions/retrigger.py,sha256=awSC8XRtPJxADz5tbEWTKdNEudG8SpwUOM7z2lXxH1U,9382
|
||||||
taskgraph/actions/util.py,sha256=jA5xXehV8N2G542LZOEci_gMHEFN-BrIjkA55On0kc0,10673
|
taskgraph/actions/util.py,sha256=jA5xXehV8N2G542LZOEci_gMHEFN-BrIjkA55On0kc0,10673
|
||||||
taskgraph/loader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
taskgraph/loader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||||
|
|
@ -28,7 +28,7 @@ taskgraph/optimize/strategies.py,sha256=Y5fS-f_3xsQNfFjCXIwDxrwXBvyp4yZxdPVNh49c
|
||||||
taskgraph/run-task/fetch-content,sha256=uUoyua3OdIgynY5Q9K6EojBwuaM2zo2OiN9bmNS646Q,24291
|
taskgraph/run-task/fetch-content,sha256=uUoyua3OdIgynY5Q9K6EojBwuaM2zo2OiN9bmNS646Q,24291
|
||||||
taskgraph/run-task/hgrc,sha256=BybWLDR89bWi3pE5T05UqmDHs02CbLypE-omLZWU6Uk,896
|
taskgraph/run-task/hgrc,sha256=BybWLDR89bWi3pE5T05UqmDHs02CbLypE-omLZWU6Uk,896
|
||||||
taskgraph/run-task/robustcheckout.py,sha256=xc24zaBd6dyuoga1ace0M27jo14K4UXNwhqcbHutJ7U,28977
|
taskgraph/run-task/robustcheckout.py,sha256=xc24zaBd6dyuoga1ace0M27jo14K4UXNwhqcbHutJ7U,28977
|
||||||
taskgraph/run-task/run-task,sha256=TVjIoZO9kbpaG-GCMJV_wjlR9H2xk8vJi0wB_rFleEg,46953
|
taskgraph/run-task/run-task,sha256=76p0Zo19a6f4NkwTq8s9y4Emt3YW6Q-VdTInlcqjPjo,46956
|
||||||
taskgraph/transforms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
taskgraph/transforms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||||
taskgraph/transforms/base.py,sha256=N9ec4kw65V_J2KY4C4QRPlbIREbRDYwTlhClstYmOBU,5285
|
taskgraph/transforms/base.py,sha256=N9ec4kw65V_J2KY4C4QRPlbIREbRDYwTlhClstYmOBU,5285
|
||||||
taskgraph/transforms/cached_tasks.py,sha256=Z10VD1kEBVXJvj8qSsNTq2mYpklh0V1EN8OT6QK3v_E,2607
|
taskgraph/transforms/cached_tasks.py,sha256=Z10VD1kEBVXJvj8qSsNTq2mYpklh0V1EN8OT6QK3v_E,2607
|
||||||
|
|
@ -36,7 +36,7 @@ taskgraph/transforms/code_review.py,sha256=eE2xrDtdD_n3HT3caQ2HGAkPm6Uutdm4hDCpC
|
||||||
taskgraph/transforms/docker_image.py,sha256=ADiOUB-Ngm9Y6uwzGDpQsDJ_-4w6-ZYwLCxQ-0b16E0,7567
|
taskgraph/transforms/docker_image.py,sha256=ADiOUB-Ngm9Y6uwzGDpQsDJ_-4w6-ZYwLCxQ-0b16E0,7567
|
||||||
taskgraph/transforms/fetch.py,sha256=jxJw7wlEh_WxAa1Bmy2WIHfpdvL79PDsKwC1DFymbBQ,9584
|
taskgraph/transforms/fetch.py,sha256=jxJw7wlEh_WxAa1Bmy2WIHfpdvL79PDsKwC1DFymbBQ,9584
|
||||||
taskgraph/transforms/release_notifications.py,sha256=jrb9CCT-z_etDf690T-AeCvdzIoVWBAeM_FGoW7FIzA,3305
|
taskgraph/transforms/release_notifications.py,sha256=jrb9CCT-z_etDf690T-AeCvdzIoVWBAeM_FGoW7FIzA,3305
|
||||||
taskgraph/transforms/task.py,sha256=n73lD8XtzpJm2BqJpZb_oiGqNHBJzTcT7GWX6jk7Xqc,47839
|
taskgraph/transforms/task.py,sha256=kWic-qqvK8vEFxQwojRPxc42GAsdkxoV3HVcG1pdBxE,47942
|
||||||
taskgraph/transforms/job/__init__.py,sha256=GKYODycxov7u05owF_ZWgczd7WHi2yHTd8L5Ftvxge0,16929
|
taskgraph/transforms/job/__init__.py,sha256=GKYODycxov7u05owF_ZWgczd7WHi2yHTd8L5Ftvxge0,16929
|
||||||
taskgraph/transforms/job/common.py,sha256=onHnerPcmmvbSk0oHt8mvJmOo7AnjHQya0ombgMNLG8,7106
|
taskgraph/transforms/job/common.py,sha256=onHnerPcmmvbSk0oHt8mvJmOo7AnjHQya0ombgMNLG8,7106
|
||||||
taskgraph/transforms/job/index_search.py,sha256=Ngh9FFu1bx2kHVTChW2vcrbnb3SzMneRHopXk18RfB4,1220
|
taskgraph/transforms/job/index_search.py,sha256=Ngh9FFu1bx2kHVTChW2vcrbnb3SzMneRHopXk18RfB4,1220
|
||||||
|
|
@ -60,15 +60,15 @@ taskgraph/util/shell.py,sha256=MB9zHVSvxgOuszgmKr2rWUDahANZkbHHNkjjagZG_3I,1317
|
||||||
taskgraph/util/taskcluster.py,sha256=cGUGvkrefRHngjyZm_iQRYKRlGi4jMIr7ky0fi_YBrg,12445
|
taskgraph/util/taskcluster.py,sha256=cGUGvkrefRHngjyZm_iQRYKRlGi4jMIr7ky0fi_YBrg,12445
|
||||||
taskgraph/util/taskgraph.py,sha256=ecKEvTfmLVvEKLPO_0g34CqVvc0iCzuNMh3064BZNrE,1969
|
taskgraph/util/taskgraph.py,sha256=ecKEvTfmLVvEKLPO_0g34CqVvc0iCzuNMh3064BZNrE,1969
|
||||||
taskgraph/util/templates.py,sha256=Dqxfl244u-PX7dnsk3_vYyzDwpDgJtANK6NmZwN3Qow,1417
|
taskgraph/util/templates.py,sha256=Dqxfl244u-PX7dnsk3_vYyzDwpDgJtANK6NmZwN3Qow,1417
|
||||||
taskgraph/util/time.py,sha256=dmR9Y0IGKuE1eHfFZjDuBUroK63XLBxEMM5ploO4li4,3490
|
taskgraph/util/time.py,sha256=pNFcTH-iYRfm2-okm1lMATc4B5wO-_FXbOFXEtXD27g,3390
|
||||||
taskgraph/util/treeherder.py,sha256=XrdE-Je0ZvXe6_8f0DvvqNbrHherUk-hUuxirImPEIo,2138
|
taskgraph/util/treeherder.py,sha256=XrdE-Je0ZvXe6_8f0DvvqNbrHherUk-hUuxirImPEIo,2138
|
||||||
taskgraph/util/vcs.py,sha256=nCmvO_hHJIM4vIJ0vlpbQjdIFRtkpRImCikYde-C_R0,17328
|
taskgraph/util/vcs.py,sha256=i13idS8y9ooR216mnd1gksdjSgHBNlAZEdq7Xr-ROwE,18536
|
||||||
taskgraph/util/verify.py,sha256=YETuZVkwnfYe57GRPx2x_vedstgqdGiH46HLWAdcks8,8827
|
taskgraph/util/verify.py,sha256=YETuZVkwnfYe57GRPx2x_vedstgqdGiH46HLWAdcks8,8827
|
||||||
taskgraph/util/workertypes.py,sha256=5g2mgIbEKMzDpZNnmPMoMNyy7Wahi-jmWcV1amDAcPo,2341
|
taskgraph/util/workertypes.py,sha256=5g2mgIbEKMzDpZNnmPMoMNyy7Wahi-jmWcV1amDAcPo,2341
|
||||||
taskgraph/util/yaml.py,sha256=hfKI_D8Q7dimq4_VvO3WEh8CJsTrsIMwN6set7HIQbY,990
|
taskgraph/util/yaml.py,sha256=hfKI_D8Q7dimq4_VvO3WEh8CJsTrsIMwN6set7HIQbY,990
|
||||||
taskcluster_taskgraph-3.0.0.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
taskcluster_taskgraph-3.2.0.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
||||||
taskcluster_taskgraph-3.0.0.dist-info/METADATA,sha256=rDJwBZW7nHDBPBcMH7n9eTnb2GONIfgG_YHTgsiB7no,1017
|
taskcluster_taskgraph-3.2.0.dist-info/METADATA,sha256=UDpk6d8wAiYmub9zhzF6H5uMIQ4JA91IeeLiZGQw0ls,1050
|
||||||
taskcluster_taskgraph-3.0.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
taskcluster_taskgraph-3.2.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
||||||
taskcluster_taskgraph-3.0.0.dist-info/entry_points.txt,sha256=VoXNtZpN4LvyXYB1wq47AU9CO-DMYMJ0VktKxjugzbY,51
|
taskcluster_taskgraph-3.2.0.dist-info/entry_points.txt,sha256=VoXNtZpN4LvyXYB1wq47AU9CO-DMYMJ0VktKxjugzbY,51
|
||||||
taskcluster_taskgraph-3.0.0.dist-info/top_level.txt,sha256=3JNeYn_hNiNXC7DrdH_vcv-WYSE7QdgGjdvUYvSjVp0,10
|
taskcluster_taskgraph-3.2.0.dist-info/top_level.txt,sha256=3JNeYn_hNiNXC7DrdH_vcv-WYSE7QdgGjdvUYvSjVp0,10
|
||||||
taskcluster_taskgraph-3.0.0.dist-info/RECORD,,
|
taskcluster_taskgraph-3.2.0.dist-info/RECORD,,
|
||||||
5
third_party/python/taskcluster_taskgraph/taskcluster_taskgraph-3.2.0.dist-info/WHEEL
vendored
Normal file
5
third_party/python/taskcluster_taskgraph/taskcluster_taskgraph-3.2.0.dist-info/WHEEL
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Wheel-Version: 1.0
|
||||||
|
Generator: bdist_wheel (0.37.1)
|
||||||
|
Root-Is-Purelib: true
|
||||||
|
Tag: py3-none-any
|
||||||
|
|
||||||
|
|
@ -7,6 +7,8 @@ import json
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from types import FunctionType
|
from types import FunctionType
|
||||||
|
|
||||||
|
from mozilla_repo_urls import parse
|
||||||
|
|
||||||
from taskgraph import create
|
from taskgraph import create
|
||||||
from taskgraph.config import load_graph_config
|
from taskgraph.config import load_graph_config
|
||||||
from taskgraph.parameters import Parameters
|
from taskgraph.parameters import Parameters
|
||||||
|
|
@ -291,24 +293,20 @@ def sanity_check_task_scope(callback, parameters, graph_config):
|
||||||
if action.cb_name == callback:
|
if action.cb_name == callback:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise Exception(f"No action with cb_name {callback}")
|
raise ValueError(f"No action with cb_name {callback}")
|
||||||
|
|
||||||
actionPerm = "generic" if action.generic else action.cb_name
|
actionPerm = "generic" if action.generic else action.cb_name
|
||||||
|
|
||||||
repo_param = "head_repository"
|
repo_param = "head_repository"
|
||||||
head_repository = parameters[repo_param]
|
raw_url = parameters[repo_param]
|
||||||
if not head_repository.startswith(("https://hg.mozilla.org", "https://github.com")):
|
parsed_url = parse(raw_url)
|
||||||
raise Exception(
|
expected_scope = f"assume:{parsed_url.taskcluster_role_prefix}:action:{actionPerm}"
|
||||||
"{} is not either https://hg.mozilla.org or https://github.com !"
|
|
||||||
)
|
|
||||||
|
|
||||||
expected_scope = f"assume:repo:{head_repository[8:]}:action:{actionPerm}"
|
|
||||||
|
|
||||||
# the scope should appear literally; no need for a satisfaction check. The use of
|
# the scope should appear literally; no need for a satisfaction check. The use of
|
||||||
# get_current_scopes here calls the auth service through the Taskcluster Proxy, giving
|
# get_current_scopes here calls the auth service through the Taskcluster Proxy, giving
|
||||||
# the precise scopes available to this task.
|
# the precise scopes available to this task.
|
||||||
if expected_scope not in taskcluster.get_current_scopes():
|
if expected_scope not in taskcluster.get_current_scopes():
|
||||||
raise Exception(f"Expected task scope {expected_scope} for this action")
|
raise ValueError(f"Expected task scope {expected_scope} for this action")
|
||||||
|
|
||||||
|
|
||||||
def trigger_action_callback(
|
def trigger_action_callback(
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ def create_tasks(
|
||||||
target_task_graph.for_each_task(update_dependencies)
|
target_task_graph.for_each_task(update_dependencies)
|
||||||
optimized_task_graph, label_to_taskid = optimize_task_graph(
|
optimized_task_graph, label_to_taskid = optimize_task_graph(
|
||||||
target_task_graph,
|
target_task_graph,
|
||||||
|
to_run,
|
||||||
params,
|
params,
|
||||||
to_run,
|
to_run,
|
||||||
decision_task_id,
|
decision_task_id,
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ from taskgraph.parameters import Parameters, get_version
|
||||||
from taskgraph.taskgraph import TaskGraph
|
from taskgraph.taskgraph import TaskGraph
|
||||||
from taskgraph.util.python_path import find_object
|
from taskgraph.util.python_path import find_object
|
||||||
from taskgraph.util.schema import Schema, validate_schema
|
from taskgraph.util.schema import Schema, validate_schema
|
||||||
from taskgraph.util.vcs import get_repository
|
from taskgraph.util.vcs import Repository, get_repository
|
||||||
from taskgraph.util.yaml import load_yaml
|
from taskgraph.util.yaml import load_yaml
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -143,6 +143,8 @@ def get_decision_parameters(graph_config, options):
|
||||||
n: options[n]
|
n: options[n]
|
||||||
for n in [
|
for n in [
|
||||||
"base_repository",
|
"base_repository",
|
||||||
|
"base_ref",
|
||||||
|
"base_rev",
|
||||||
"head_repository",
|
"head_repository",
|
||||||
"head_rev",
|
"head_rev",
|
||||||
"head_ref",
|
"head_ref",
|
||||||
|
|
@ -166,6 +168,21 @@ def get_decision_parameters(graph_config, options):
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
commit_message = ""
|
commit_message = ""
|
||||||
|
|
||||||
|
parameters["base_ref"] = _determine_more_accurate_base_ref(
|
||||||
|
repo,
|
||||||
|
candidate_base_ref=options.get("base_ref"),
|
||||||
|
head_ref=options.get("head_ref"),
|
||||||
|
base_rev=options.get("base_rev"),
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters["base_rev"] = _determine_more_accurate_base_rev(
|
||||||
|
repo,
|
||||||
|
base_ref=parameters["base_ref"],
|
||||||
|
candidate_base_rev=options.get("base_rev"),
|
||||||
|
head_rev=options.get("head_rev"),
|
||||||
|
env_prefix=_get_env_prefix(graph_config),
|
||||||
|
)
|
||||||
|
|
||||||
# Define default filter list, as most configurations shouldn't need
|
# Define default filter list, as most configurations shouldn't need
|
||||||
# custom filters.
|
# custom filters.
|
||||||
parameters["filters"] = [
|
parameters["filters"] = [
|
||||||
|
|
@ -236,6 +253,68 @@ def get_decision_parameters(graph_config, options):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _determine_more_accurate_base_ref(repo, candidate_base_ref, head_ref, base_rev):
|
||||||
|
base_ref = candidate_base_ref
|
||||||
|
|
||||||
|
if not candidate_base_ref:
|
||||||
|
base_ref = repo.default_branch
|
||||||
|
elif candidate_base_ref == head_ref and base_rev == Repository.NULL_REVISION:
|
||||||
|
logger.info(
|
||||||
|
"base_ref and head_ref are identical but base_rev equals the null revision. "
|
||||||
|
"This is a new branch but Github didn't identify its actual base."
|
||||||
|
)
|
||||||
|
base_ref = repo.default_branch
|
||||||
|
|
||||||
|
if base_ref != candidate_base_ref:
|
||||||
|
logger.info(
|
||||||
|
f'base_ref has been reset from "{candidate_base_ref}" to "{base_ref}".'
|
||||||
|
)
|
||||||
|
|
||||||
|
return base_ref
|
||||||
|
|
||||||
|
|
||||||
|
def _determine_more_accurate_base_rev(
|
||||||
|
repo, base_ref, candidate_base_rev, head_rev, env_prefix
|
||||||
|
):
|
||||||
|
if not candidate_base_rev:
|
||||||
|
logger.info("base_rev is not set.")
|
||||||
|
base_ref_or_rev = base_ref
|
||||||
|
elif candidate_base_rev == Repository.NULL_REVISION:
|
||||||
|
logger.info("base_rev equals the null revision. This branch is a new one.")
|
||||||
|
base_ref_or_rev = base_ref
|
||||||
|
elif not repo.does_revision_exist_locally(candidate_base_rev):
|
||||||
|
logger.warning(
|
||||||
|
"base_rev does not exist locally. It is likely because the branch was force-pushed. "
|
||||||
|
"taskgraph is not able to assess how many commits were changed and assumes it is only "
|
||||||
|
f"the last one. Please set the {env_prefix.upper()}_BASE_REV environment variable "
|
||||||
|
"in the decision task and provide `--base-rev` to taskgraph."
|
||||||
|
)
|
||||||
|
base_ref_or_rev = base_ref
|
||||||
|
else:
|
||||||
|
base_ref_or_rev = candidate_base_rev
|
||||||
|
|
||||||
|
if base_ref_or_rev == base_ref:
|
||||||
|
logger.info(
|
||||||
|
f'Using base_ref "{base_ref}" to determine latest common revision...'
|
||||||
|
)
|
||||||
|
|
||||||
|
base_rev = repo.find_latest_common_revision(base_ref_or_rev, head_rev)
|
||||||
|
if base_rev != candidate_base_rev:
|
||||||
|
if base_ref_or_rev == candidate_base_rev:
|
||||||
|
logger.info("base_rev is not an ancestor of head_rev.")
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f'base_rev has been reset from "{candidate_base_rev}" to "{base_rev}".'
|
||||||
|
)
|
||||||
|
|
||||||
|
return base_rev
|
||||||
|
|
||||||
|
|
||||||
|
def _get_env_prefix(graph_config):
|
||||||
|
repo_keys = list(graph_config["taskgraph"].get("repositories", {}).keys())
|
||||||
|
return repo_keys[0] if repo_keys else ""
|
||||||
|
|
||||||
|
|
||||||
def set_try_config(parameters, task_config_file):
|
def set_try_config(parameters, task_config_file):
|
||||||
if os.path.isfile(task_config_file):
|
if os.path.isfile(task_config_file):
|
||||||
logger.info(f"using try tasks from {task_config_file}")
|
logger.info(f"using try tasks from {task_config_file}")
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,43 @@ Support for optimizing tasks based on the set of files that have changed.
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from redo import retry
|
from redo import retry
|
||||||
|
|
||||||
from .util.memoize import memoize
|
from .util.memoize import memoize
|
||||||
from .util.path import match as match_path
|
from .util.path import match as match_path
|
||||||
|
from .util.vcs import get_repository
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@memoize
|
@memoize
|
||||||
def get_changed_files(repository, revision):
|
def get_changed_files(head_repository_url, head_rev, base_rev=None):
|
||||||
"""
|
"""
|
||||||
Get the set of files changed in the push headed by the given revision.
|
Get the set of files changed between revisions.
|
||||||
Responses are cached, so multiple calls with the same arguments are OK.
|
Responses are cached, so multiple calls with the same arguments are OK.
|
||||||
"""
|
"""
|
||||||
url = "{}/json-automationrelevance/{}".format(repository.rstrip("/"), revision)
|
repo_path = os.getcwd()
|
||||||
|
repository = get_repository(repo_path)
|
||||||
|
|
||||||
|
if repository.tool == "hg":
|
||||||
|
# TODO Use VCS version once tested enough
|
||||||
|
return _get_changed_files_json_automationrelevance(
|
||||||
|
head_repository_url, head_rev
|
||||||
|
)
|
||||||
|
|
||||||
|
return repository.get_changed_files(rev=head_rev, base_rev=base_rev)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_changed_files_json_automationrelevance(head_repository_url, head_rev):
|
||||||
|
"""
|
||||||
|
Get the set of files changed in the push headed by the given revision.
|
||||||
|
"""
|
||||||
|
url = "{}/json-automationrelevance/{}".format(
|
||||||
|
head_repository_url.rstrip("/"), head_rev
|
||||||
|
)
|
||||||
logger.debug("Querying version control for metadata: %s", url)
|
logger.debug("Querying version control for metadata: %s", url)
|
||||||
|
|
||||||
def get_automationrelevance():
|
def get_automationrelevance():
|
||||||
|
|
@ -48,18 +68,20 @@ def get_changed_files(repository, revision):
|
||||||
|
|
||||||
|
|
||||||
def check(params, file_patterns):
|
def check(params, file_patterns):
|
||||||
"""Determine whether any of the files changed in the indicated push to
|
"""Determine whether any of the files changed between 2 revisions
|
||||||
https://hg.mozilla.org match any of the given file patterns."""
|
match any of the given file patterns."""
|
||||||
repository = params.get("head_repository")
|
|
||||||
revision = params.get("head_rev")
|
head_repository_url = params.get("head_repository")
|
||||||
if not repository or not revision:
|
head_rev = params.get("head_rev")
|
||||||
|
if not head_repository_url or not head_rev:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Missing `head_repository` or `head_rev` parameters; "
|
"Missing `head_repository` or `head_rev` parameters; "
|
||||||
"assuming all files have changed"
|
"assuming all files have changed"
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
changed_files = get_changed_files(repository, revision)
|
base_rev = params.get("base_rev")
|
||||||
|
changed_files = get_changed_files(head_repository_url, head_rev, base_rev)
|
||||||
|
|
||||||
for pattern in file_patterns:
|
for pattern in file_patterns:
|
||||||
for path in changed_files:
|
for path in changed_files:
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ class Kind:
|
||||||
config = copy.deepcopy(self.config)
|
config = copy.deepcopy(self.config)
|
||||||
|
|
||||||
kind_dependencies = config.get("kind-dependencies", [])
|
kind_dependencies = config.get("kind-dependencies", [])
|
||||||
kind_dependencies_tasks = [
|
kind_dependencies_tasks = {
|
||||||
task for task in loaded_tasks if task.kind in kind_dependencies
|
task.label: task for task in loaded_tasks if task.kind in kind_dependencies
|
||||||
]
|
}
|
||||||
|
|
||||||
inputs = loader(self.name, self.path, config, parameters, loaded_tasks)
|
inputs = loader(self.name, self.path, config, parameters, loaded_tasks)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -343,7 +343,7 @@ def show_taskgraph(options):
|
||||||
logging.root.setLevel(logging.DEBUG)
|
logging.root.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
repo = None
|
repo = None
|
||||||
cur_ref = None
|
cur_rev = None
|
||||||
diffdir = None
|
diffdir = None
|
||||||
output_file = options["output_file"]
|
output_file = options["output_file"]
|
||||||
|
|
||||||
|
|
@ -361,16 +361,16 @@ def show_taskgraph(options):
|
||||||
# as best we can after we're done. In all known cases, using
|
# as best we can after we're done. In all known cases, using
|
||||||
# branch or bookmark (which are both available on the VCS object)
|
# branch or bookmark (which are both available on the VCS object)
|
||||||
# as `branch` is preferable to a specific revision.
|
# as `branch` is preferable to a specific revision.
|
||||||
cur_ref = repo.branch or repo.head_ref[:12]
|
cur_rev = repo.branch or repo.head_rev[:12]
|
||||||
|
|
||||||
diffdir = tempfile.mkdtemp()
|
diffdir = tempfile.mkdtemp()
|
||||||
atexit.register(
|
atexit.register(
|
||||||
shutil.rmtree, diffdir
|
shutil.rmtree, diffdir
|
||||||
) # make sure the directory gets cleaned up
|
) # make sure the directory gets cleaned up
|
||||||
options["output_file"] = os.path.join(
|
options["output_file"] = os.path.join(
|
||||||
diffdir, f"{options['graph_attr']}_{cur_ref}"
|
diffdir, f"{options['graph_attr']}_{cur_rev}"
|
||||||
)
|
)
|
||||||
print(f"Generating {options['graph_attr']} @ {cur_ref}", file=sys.stderr)
|
print(f"Generating {options['graph_attr']} @ {cur_rev}", file=sys.stderr)
|
||||||
|
|
||||||
parameters: List[Any[str, Parameters]] = options.pop("parameters")
|
parameters: List[Any[str, Parameters]] = options.pop("parameters")
|
||||||
if not parameters:
|
if not parameters:
|
||||||
|
|
@ -418,33 +418,33 @@ def show_taskgraph(options):
|
||||||
del sys.modules[mod]
|
del sys.modules[mod]
|
||||||
|
|
||||||
if options["diff"] == "default":
|
if options["diff"] == "default":
|
||||||
base_ref = repo.base_ref
|
base_rev = repo.base_rev
|
||||||
else:
|
else:
|
||||||
base_ref = options["diff"]
|
base_rev = options["diff"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repo.update(base_ref)
|
repo.update(base_rev)
|
||||||
base_ref = repo.head_ref[:12]
|
base_rev = repo.head_rev[:12]
|
||||||
options["output_file"] = os.path.join(
|
options["output_file"] = os.path.join(
|
||||||
diffdir, f"{options['graph_attr']}_{base_ref}"
|
diffdir, f"{options['graph_attr']}_{base_rev}"
|
||||||
)
|
)
|
||||||
print(f"Generating {options['graph_attr']} @ {base_ref}", file=sys.stderr)
|
print(f"Generating {options['graph_attr']} @ {base_rev}", file=sys.stderr)
|
||||||
generate_taskgraph(options, parameters, logdir)
|
generate_taskgraph(options, parameters, logdir)
|
||||||
finally:
|
finally:
|
||||||
repo.update(cur_ref)
|
repo.update(cur_rev)
|
||||||
|
|
||||||
# Generate diff(s)
|
# Generate diff(s)
|
||||||
diffcmd = [
|
diffcmd = [
|
||||||
"diff",
|
"diff",
|
||||||
"-U20",
|
"-U20",
|
||||||
"--report-identical-files",
|
"--report-identical-files",
|
||||||
f"--label={options['graph_attr']}@{base_ref}",
|
f"--label={options['graph_attr']}@{base_rev}",
|
||||||
f"--label={options['graph_attr']}@{cur_ref}",
|
f"--label={options['graph_attr']}@{cur_rev}",
|
||||||
]
|
]
|
||||||
|
|
||||||
for spec in parameters:
|
for spec in parameters:
|
||||||
base_path = os.path.join(diffdir, f"{options['graph_attr']}_{base_ref}")
|
base_path = os.path.join(diffdir, f"{options['graph_attr']}_{base_rev}")
|
||||||
cur_path = os.path.join(diffdir, f"{options['graph_attr']}_{cur_ref}")
|
cur_path = os.path.join(diffdir, f"{options['graph_attr']}_{cur_rev}")
|
||||||
|
|
||||||
params_name = None
|
params_name = None
|
||||||
if len(parameters) > 1:
|
if len(parameters) > 1:
|
||||||
|
|
@ -593,6 +593,15 @@ def image_digest(args):
|
||||||
help='Type of repository, either "hg" or "git"',
|
help='Type of repository, either "hg" or "git"',
|
||||||
)
|
)
|
||||||
@argument("--base-repository", required=True, help='URL for "base" repository to clone')
|
@argument("--base-repository", required=True, help='URL for "base" repository to clone')
|
||||||
|
@argument(
|
||||||
|
"--base-ref", default="", help='Reference of the revision in the "base" repository'
|
||||||
|
)
|
||||||
|
@argument(
|
||||||
|
"--base-rev",
|
||||||
|
default="",
|
||||||
|
help="Taskgraph decides what to do based on the revision range between "
|
||||||
|
"`--base-rev` and `--head-rev`. Value is determined automatically if not provided",
|
||||||
|
)
|
||||||
@argument(
|
@argument(
|
||||||
"--head-repository",
|
"--head-repository",
|
||||||
required=True,
|
required=True,
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,12 @@ here = os.path.abspath(os.path.dirname(__file__))
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
MAX_ROUTES = 10
|
MAX_ROUTES = 10
|
||||||
|
|
||||||
|
registered_morphs = []
|
||||||
|
|
||||||
|
|
||||||
|
def register_morph(func):
|
||||||
|
registered_morphs.append(func)
|
||||||
|
|
||||||
|
|
||||||
def amend_taskgraph(taskgraph, label_to_taskid, to_add):
|
def amend_taskgraph(taskgraph, label_to_taskid, to_add):
|
||||||
"""Add the given tasks to the taskgraph, returning a new taskgraph"""
|
"""Add the given tasks to the taskgraph, returning a new taskgraph"""
|
||||||
|
|
@ -156,6 +162,7 @@ def make_index_task(parent_task, taskgraph, label_to_taskid, parameters, graph_c
|
||||||
return task, taskgraph, label_to_taskid
|
return task, taskgraph, label_to_taskid
|
||||||
|
|
||||||
|
|
||||||
|
@register_morph
|
||||||
def add_index_tasks(taskgraph, label_to_taskid, parameters, graph_config):
|
def add_index_tasks(taskgraph, label_to_taskid, parameters, graph_config):
|
||||||
"""
|
"""
|
||||||
The TaskCluster queue only allows 10 routes on a task, but we have tasks
|
The TaskCluster queue only allows 10 routes on a task, but we have tasks
|
||||||
|
|
@ -196,8 +203,9 @@ def _get_morph_url():
|
||||||
return f"{taskgraph_repo}/raw-file/{taskgraph_rev}/src/taskgraph/morph.py"
|
return f"{taskgraph_repo}/raw-file/{taskgraph_rev}/src/taskgraph/morph.py"
|
||||||
|
|
||||||
|
|
||||||
|
@register_morph
|
||||||
def add_code_review_task(taskgraph, label_to_taskid, parameters, graph_config):
|
def add_code_review_task(taskgraph, label_to_taskid, parameters, graph_config):
|
||||||
logger.debug("Morphing: adding index tasks")
|
logger.debug("Morphing: adding code review task")
|
||||||
|
|
||||||
review_config = parameters.get("code-review")
|
review_config = parameters.get("code-review")
|
||||||
if not review_config:
|
if not review_config:
|
||||||
|
|
@ -256,12 +264,7 @@ def add_code_review_task(taskgraph, label_to_taskid, parameters, graph_config):
|
||||||
|
|
||||||
def morph(taskgraph, label_to_taskid, parameters, graph_config):
|
def morph(taskgraph, label_to_taskid, parameters, graph_config):
|
||||||
"""Apply all morphs"""
|
"""Apply all morphs"""
|
||||||
morphs = [
|
for m in registered_morphs:
|
||||||
add_index_tasks,
|
|
||||||
add_code_review_task,
|
|
||||||
]
|
|
||||||
|
|
||||||
for m in morphs:
|
|
||||||
taskgraph, label_to_taskid = m(
|
taskgraph, label_to_taskid = m(
|
||||||
taskgraph, label_to_taskid, parameters, graph_config
|
taskgraph, label_to_taskid, parameters, graph_config
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -50,13 +50,8 @@ class IndexSearch(OptimizationStrategy):
|
||||||
@register_strategy("skip-unless-changed")
|
@register_strategy("skip-unless-changed")
|
||||||
class SkipUnlessChanged(OptimizationStrategy):
|
class SkipUnlessChanged(OptimizationStrategy):
|
||||||
def should_remove_task(self, task, params, file_patterns):
|
def should_remove_task(self, task, params, file_patterns):
|
||||||
if params.get("repository_type") != "hg":
|
# pushlog_id == -1 - this is the case when run from a cron.yml job or on a git repository
|
||||||
raise RuntimeError(
|
if params.get("repository_type") == "hg" and params.get("pushlog_id") == -1:
|
||||||
"SkipUnlessChanged optimization only works with mercurial repositories"
|
|
||||||
)
|
|
||||||
|
|
||||||
# pushlog_id == -1 - this is the case when run from a cron.yml job
|
|
||||||
if params.get("pushlog_id") == -1:
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
changed = files_changed.check(params, file_patterns)
|
changed = files_changed.check(params, file_patterns)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ from subprocess import CalledProcessError
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
|
from mozilla_repo_urls import parse
|
||||||
from voluptuous import ALLOW_EXTRA, Any, Optional, Required, Schema
|
from voluptuous import ALLOW_EXTRA, Any, Optional, Required, Schema
|
||||||
|
|
||||||
from taskgraph.util import yaml
|
from taskgraph.util import yaml
|
||||||
|
|
@ -31,6 +32,8 @@ class ParameterMismatch(Exception):
|
||||||
base_schema = Schema(
|
base_schema = Schema(
|
||||||
{
|
{
|
||||||
Required("base_repository"): str,
|
Required("base_repository"): str,
|
||||||
|
Required("base_ref"): str,
|
||||||
|
Required("base_rev"): str,
|
||||||
Required("build_date"): int,
|
Required("build_date"): int,
|
||||||
Required("build_number"): int,
|
Required("build_number"): int,
|
||||||
Required("do_not_optimize"): [str],
|
Required("do_not_optimize"): [str],
|
||||||
|
|
@ -77,22 +80,26 @@ def _get_defaults(repo_root=None):
|
||||||
repo = get_repository(repo_path)
|
repo = get_repository(repo_path)
|
||||||
try:
|
try:
|
||||||
repo_url = repo.get_url()
|
repo_url = repo.get_url()
|
||||||
project = repo_url.rsplit("/", 1)[1]
|
parsed_url = parse(repo_url)
|
||||||
|
project = parsed_url.repo_name
|
||||||
except (CalledProcessError, IndexError):
|
except (CalledProcessError, IndexError):
|
||||||
# IndexError is raised if repo url doesn't have any slashes.
|
# IndexError is raised if repo url doesn't have any slashes.
|
||||||
repo_url = ""
|
repo_url = ""
|
||||||
project = ""
|
project = ""
|
||||||
|
|
||||||
|
default_base_ref = repo.default_branch
|
||||||
return {
|
return {
|
||||||
"base_repository": repo_url,
|
"base_repository": repo_url,
|
||||||
|
"base_ref": default_base_ref,
|
||||||
|
"base_rev": repo.find_latest_common_revision(default_base_ref, repo.head_rev),
|
||||||
"build_date": int(time.time()),
|
"build_date": int(time.time()),
|
||||||
"build_number": 1,
|
"build_number": 1,
|
||||||
"do_not_optimize": [],
|
"do_not_optimize": [],
|
||||||
"existing_tasks": {},
|
"existing_tasks": {},
|
||||||
"filters": ["target_tasks_method"],
|
"filters": ["target_tasks_method"],
|
||||||
"head_ref": repo.head_ref,
|
"head_ref": repo.branch or repo.head_rev,
|
||||||
"head_repository": repo_url,
|
"head_repository": repo_url,
|
||||||
"head_rev": repo.head_ref,
|
"head_rev": repo.head_rev,
|
||||||
"head_tag": "",
|
"head_tag": "",
|
||||||
"level": "3",
|
"level": "3",
|
||||||
"moz_build_date": datetime.now().strftime("%Y%m%d%H%M%S"),
|
"moz_build_date": datetime.now().strftime("%Y%m%d%H%M%S"),
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,13 @@ IS_MACOSX = sys.platform == 'darwin'
|
||||||
IS_POSIX = os.name == 'posix'
|
IS_POSIX = os.name == 'posix'
|
||||||
IS_WINDOWS = os.name == 'nt'
|
IS_WINDOWS = os.name == 'nt'
|
||||||
|
|
||||||
|
# Both mercurial and git use sha1 as revision idenfiers. Luckily, both define
|
||||||
|
# the same value as the null revision.
|
||||||
|
#
|
||||||
|
# https://github.com/git/git/blob/dc04167d378fb29d30e1647ff6ff51dd182bc9a3/t/oid-info/hash-info#L7
|
||||||
|
# https://www.mercurial-scm.org/repo/hg-stable/file/82efc31bd152/mercurial/node.py#l30
|
||||||
|
NULL_REVISION = "0000000000000000000000000000000000000000"
|
||||||
|
|
||||||
|
|
||||||
def print_line(prefix, m):
|
def print_line(prefix, m):
|
||||||
now = datetime.datetime.utcnow().isoformat().encode('utf-8')
|
now = datetime.datetime.utcnow().isoformat().encode('utf-8')
|
||||||
|
|
@ -557,6 +564,8 @@ def git_checkout(
|
||||||
destination_path: str,
|
destination_path: str,
|
||||||
head_repo: str,
|
head_repo: str,
|
||||||
base_repo: Optional[str],
|
base_repo: Optional[str],
|
||||||
|
base_ref: Optional[str],
|
||||||
|
base_rev: Optional[str],
|
||||||
ref: Optional[str],
|
ref: Optional[str],
|
||||||
commit: Optional[str],
|
commit: Optional[str],
|
||||||
ssh_key_file: Optional[Path],
|
ssh_key_file: Optional[Path],
|
||||||
|
|
@ -591,11 +600,47 @@ def git_checkout(
|
||||||
|
|
||||||
retry_required_command(b'vcs', args, extra_env=env)
|
retry_required_command(b'vcs', args, extra_env=env)
|
||||||
|
|
||||||
|
if base_ref:
|
||||||
|
args = [
|
||||||
|
'git',
|
||||||
|
'fetch',
|
||||||
|
'origin',
|
||||||
|
base_ref
|
||||||
|
]
|
||||||
|
|
||||||
|
retry_required_command(b'vcs', args, cwd=destination_path, extra_env=env)
|
||||||
|
|
||||||
|
# Create local branch so that taskgraph is able to compute differences
|
||||||
|
# between the head branch and the base one, if needed
|
||||||
|
args = [
|
||||||
|
'git',
|
||||||
|
'checkout',
|
||||||
|
base_ref
|
||||||
|
]
|
||||||
|
|
||||||
|
retry_required_command(b'vcs', args, cwd=destination_path, extra_env=env)
|
||||||
|
|
||||||
|
# When commits are force-pushed (like on a testing branch), base_rev doesn't
|
||||||
|
# exist on base_ref. Fetching it allows taskgraph to compute differences
|
||||||
|
# between the previous state before the force-push and the current state.
|
||||||
|
#
|
||||||
|
# Unlike base_ref just above, there is no need to checkout the revision:
|
||||||
|
# it's immediately avaiable after the fetch.
|
||||||
|
if base_rev and base_rev != NULL_REVISION:
|
||||||
|
args = [
|
||||||
|
'git',
|
||||||
|
'fetch',
|
||||||
|
'origin',
|
||||||
|
base_rev
|
||||||
|
]
|
||||||
|
|
||||||
|
retry_required_command(b'vcs', args, cwd=destination_path, extra_env=env)
|
||||||
|
|
||||||
# If a ref isn't provided, we fetch all refs from head_repo, which may be slow
|
# If a ref isn't provided, we fetch all refs from head_repo, which may be slow
|
||||||
args = [
|
args = [
|
||||||
'git',
|
'git',
|
||||||
'fetch',
|
'fetch',
|
||||||
'--tags',
|
'--no-tags',
|
||||||
head_repo,
|
head_repo,
|
||||||
ref if ref else '+refs/heads/*:refs/remotes/work/*'
|
ref if ref else '+refs/heads/*:refs/remotes/work/*'
|
||||||
]
|
]
|
||||||
|
|
@ -606,11 +651,31 @@ def git_checkout(
|
||||||
'git',
|
'git',
|
||||||
'checkout',
|
'checkout',
|
||||||
'-f',
|
'-f',
|
||||||
commit if commit else ref
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if ref:
|
||||||
|
args.extend(['-B', ref])
|
||||||
|
args.append(commit if commit else ref)
|
||||||
|
|
||||||
run_required_command(b'vcs', args, cwd=destination_path)
|
run_required_command(b'vcs', args, cwd=destination_path)
|
||||||
|
|
||||||
|
if os.path.exists(os.path.join(destination_path, '.gitmodules')):
|
||||||
|
args = [
|
||||||
|
'git',
|
||||||
|
'submodule',
|
||||||
|
'init',
|
||||||
|
]
|
||||||
|
|
||||||
|
run_required_command(b'vcs', args, cwd=destination_path)
|
||||||
|
|
||||||
|
args = [
|
||||||
|
'git',
|
||||||
|
'submodule',
|
||||||
|
'update',
|
||||||
|
]
|
||||||
|
|
||||||
|
run_required_command(b'vcs', args, cwd=destination_path)
|
||||||
|
|
||||||
_clean_git_checkout(destination_path)
|
_clean_git_checkout(destination_path)
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
|
|
@ -818,6 +883,8 @@ def collect_vcs_options(args, project, name):
|
||||||
|
|
||||||
repo_type = os.environ.get('%s_REPOSITORY_TYPE' % env_prefix)
|
repo_type = os.environ.get('%s_REPOSITORY_TYPE' % env_prefix)
|
||||||
base_repo = os.environ.get('%s_BASE_REPOSITORY' % env_prefix)
|
base_repo = os.environ.get('%s_BASE_REPOSITORY' % env_prefix)
|
||||||
|
base_ref = os.environ.get('%s_BASE_REF' % env_prefix)
|
||||||
|
base_rev = os.environ.get('%s_BASE_REV' % env_prefix)
|
||||||
head_repo = os.environ.get('%s_HEAD_REPOSITORY' % env_prefix)
|
head_repo = os.environ.get('%s_HEAD_REPOSITORY' % env_prefix)
|
||||||
revision = os.environ.get('%s_HEAD_REV' % env_prefix)
|
revision = os.environ.get('%s_HEAD_REV' % env_prefix)
|
||||||
ref = os.environ.get('%s_HEAD_REF' % env_prefix)
|
ref = os.environ.get('%s_HEAD_REF' % env_prefix)
|
||||||
|
|
@ -849,6 +916,8 @@ def collect_vcs_options(args, project, name):
|
||||||
'checkout': checkout,
|
'checkout': checkout,
|
||||||
'sparse-profile': sparse_profile,
|
'sparse-profile': sparse_profile,
|
||||||
'base-repo': base_repo,
|
'base-repo': base_repo,
|
||||||
|
'base-ref': base_ref,
|
||||||
|
'base-rev': base_rev,
|
||||||
'head-repo': head_repo,
|
'head-repo': head_repo,
|
||||||
'revision': revision,
|
'revision': revision,
|
||||||
'ref': ref,
|
'ref': ref,
|
||||||
|
|
@ -896,6 +965,8 @@ def vcs_checkout_from_args(options, *, hgmo_fingerprint):
|
||||||
options['checkout'],
|
options['checkout'],
|
||||||
options['head-repo'],
|
options['head-repo'],
|
||||||
options['base-repo'],
|
options['base-repo'],
|
||||||
|
options['base-ref'],
|
||||||
|
options['base-rev'],
|
||||||
ref,
|
ref,
|
||||||
revision,
|
revision,
|
||||||
ssh_key_file,
|
ssh_key_file,
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ class TransformConfig:
|
||||||
# the parameters for this task-graph generation run
|
# the parameters for this task-graph generation run
|
||||||
params = attr.ib(type=Parameters)
|
params = attr.ib(type=Parameters)
|
||||||
|
|
||||||
# a list of all the tasks associated with the kind dependencies of the
|
# a dict of all the tasks associated with the kind dependencies of the
|
||||||
# current kind
|
# current kind
|
||||||
kind_dependencies_tasks = attr.ib()
|
kind_dependencies_tasks = attr.ib(type=dict)
|
||||||
|
|
||||||
# Global configuration of the taskgraph
|
# Global configuration of the taskgraph
|
||||||
graph_config = attr.ib(type=GraphConfig)
|
graph_config = attr.ib(type=GraphConfig)
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ def cache_task(config, tasks):
|
||||||
return
|
return
|
||||||
|
|
||||||
digests = {}
|
digests = {}
|
||||||
for task in config.kind_dependencies_tasks:
|
for task in config.kind_dependencies_tasks.values():
|
||||||
if "cached_task" in task.attributes:
|
if "cached_task" in task.attributes:
|
||||||
digests[task.label] = format_task_digest(task.attributes["cached_task"])
|
digests[task.label] = format_task_digest(task.attributes["cached_task"])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ def add_dependencies(config, jobs):
|
||||||
job.setdefault("soft-dependencies", [])
|
job.setdefault("soft-dependencies", [])
|
||||||
job["soft-dependencies"] += [
|
job["soft-dependencies"] += [
|
||||||
dep_task.label
|
dep_task.label
|
||||||
for dep_task in config.kind_dependencies_tasks
|
for dep_task in config.kind_dependencies_tasks.values()
|
||||||
if dep_task.attributes.get("code-review") is True
|
if dep_task.attributes.get("code-review") is True
|
||||||
]
|
]
|
||||||
yield job
|
yield job
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ transforms.add_validate(docker_image_schema)
|
||||||
@transforms.add
|
@transforms.add
|
||||||
def fill_template(config, tasks):
|
def fill_template(config, tasks):
|
||||||
available_packages = set()
|
available_packages = set()
|
||||||
for task in config.kind_dependencies_tasks:
|
for task in config.kind_dependencies_tasks.values():
|
||||||
if task.kind != "packages":
|
if task.kind != "packages":
|
||||||
continue
|
continue
|
||||||
name = task.label.replace("packages-", "")
|
name = task.label.replace("packages-", "")
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ def use_fetches(config, jobs):
|
||||||
if value:
|
if value:
|
||||||
aliases[f"{config.kind}-{value}"] = label
|
aliases[f"{config.kind}-{value}"] = label
|
||||||
|
|
||||||
for task in config.kind_dependencies_tasks:
|
for task in config.kind_dependencies_tasks.values():
|
||||||
if task.kind in ("fetch", "toolchain"):
|
if task.kind in ("fetch", "toolchain"):
|
||||||
get_attribute(
|
get_attribute(
|
||||||
artifact_names,
|
artifact_names,
|
||||||
|
|
@ -275,8 +275,8 @@ def use_fetches(config, jobs):
|
||||||
else:
|
else:
|
||||||
dep_tasks = [
|
dep_tasks = [
|
||||||
task
|
task
|
||||||
for task in config.kind_dependencies_tasks
|
for label, task in config.kind_dependencies_tasks.items()
|
||||||
if task.label == dep_label
|
if label == dep_label
|
||||||
]
|
]
|
||||||
if len(dep_tasks) != 1:
|
if len(dep_tasks) != 1:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
|
|
|
||||||
|
|
@ -998,6 +998,8 @@ def build_task(config, tasks):
|
||||||
# (and causes scope issues) if it doesn't match the name of the
|
# (and causes scope issues) if it doesn't match the name of the
|
||||||
# base repo
|
# base repo
|
||||||
base_project = config.params["base_repository"].split("/")[-1]
|
base_project = config.params["base_repository"].split("/")[-1]
|
||||||
|
if base_project.endswith(".git"):
|
||||||
|
base_project = base_project[:-4]
|
||||||
th_project_suffix = "-pr"
|
th_project_suffix = "-pr"
|
||||||
else:
|
else:
|
||||||
base_project = config.params["project"]
|
base_project = config.params["project"]
|
||||||
|
|
|
||||||
|
|
@ -99,9 +99,8 @@ def json_time_from_now(input_str, now=None, datetime_format=False):
|
||||||
else:
|
else:
|
||||||
# Sorta a big hack but the json schema validator for date does not like the
|
# Sorta a big hack but the json schema validator for date does not like the
|
||||||
# ISO dates until 'Z' (for timezone) is added...
|
# ISO dates until 'Z' (for timezone) is added...
|
||||||
# the [:23] ensures only whole seconds or milliseconds are included,
|
# Microseconds are excluded (see bug 1381801)
|
||||||
# not microseconds (see bug 1381801)
|
return time.isoformat(timespec="milliseconds") + "Z"
|
||||||
return time.isoformat()[:23] + "Z"
|
|
||||||
|
|
||||||
|
|
||||||
def current_json_time(datetime_format=False):
|
def current_json_time(datetime_format=False):
|
||||||
|
|
@ -112,6 +111,5 @@ def current_json_time(datetime_format=False):
|
||||||
if datetime_format is True:
|
if datetime_format is True:
|
||||||
return datetime.datetime.utcnow()
|
return datetime.datetime.utcnow()
|
||||||
else:
|
else:
|
||||||
# the [:23] ensures only whole seconds or milliseconds are included,
|
# Microseconds are excluded (see bug 1381801)
|
||||||
# not microseconds (see bug 1381801)
|
return datetime.datetime.utcnow().isoformat(timespec="milliseconds") + "Z"
|
||||||
return datetime.datetime.utcnow().isoformat()[:23] + "Z"
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
from abc import ABC, abstractmethod, abstractproperty
|
from abc import ABC, abstractmethod, abstractproperty
|
||||||
from shutil import which
|
from shutil import which
|
||||||
|
|
@ -15,38 +17,91 @@ from taskgraph.util.path import ancestors
|
||||||
|
|
||||||
PUSHLOG_TMPL = "{}/json-pushes?version=2&changeset={}&tipsonly=1&full=1"
|
PUSHLOG_TMPL = "{}/json-pushes?version=2&changeset={}&tipsonly=1&full=1"
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Repository(ABC):
|
class Repository(ABC):
|
||||||
|
# Both mercurial and git use sha1 as revision idenfiers. Luckily, both define
|
||||||
|
# the same value as the null revision.
|
||||||
|
#
|
||||||
|
# https://github.com/git/git/blob/dc04167d378fb29d30e1647ff6ff51dd182bc9a3/t/oid-info/hash-info#L7
|
||||||
|
# https://www.mercurial-scm.org/repo/hg-stable/file/82efc31bd152/mercurial/node.py#l30
|
||||||
|
NULL_REVISION = "0000000000000000000000000000000000000000"
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.binary = which(self.tool)
|
self.binary = which(self.tool)
|
||||||
if self.binary is None:
|
if self.binary is None:
|
||||||
raise OSError(f"{self.tool} not found!")
|
raise OSError(f"{self.tool} not found!")
|
||||||
|
self._valid_diff_filter = ("m", "a", "d")
|
||||||
|
|
||||||
self._env = os.environ.copy()
|
self._env = os.environ.copy()
|
||||||
|
|
||||||
def run(self, *args: str, **kwargs):
|
def run(self, *args: str, **kwargs):
|
||||||
|
return_codes = kwargs.pop("return_codes", [])
|
||||||
cmd = (self.binary,) + args
|
cmd = (self.binary,) + args
|
||||||
return subprocess.check_output(
|
|
||||||
cmd, cwd=self.path, env=self._env, encoding="utf-8", **kwargs
|
try:
|
||||||
)
|
return subprocess.check_output(
|
||||||
|
cmd, cwd=self.path, env=self._env, encoding="utf-8", **kwargs
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
if e.returncode in return_codes:
|
||||||
|
return ""
|
||||||
|
raise
|
||||||
|
|
||||||
@abstractproperty
|
@abstractproperty
|
||||||
def tool(self) -> str:
|
def tool(self) -> str:
|
||||||
"""Version control system being used, either 'hg' or 'git'."""
|
"""Version control system being used, either 'hg' or 'git'."""
|
||||||
|
|
||||||
@abstractproperty
|
@abstractproperty
|
||||||
def head_ref(self) -> str:
|
def head_rev(self) -> str:
|
||||||
"""Hash of HEAD revision."""
|
"""Hash of HEAD revision."""
|
||||||
|
|
||||||
@abstractproperty
|
@abstractproperty
|
||||||
def base_ref(self):
|
def base_rev(self):
|
||||||
"""Hash of revision the current topic branch is based on."""
|
"""Hash of revision the current topic branch is based on."""
|
||||||
|
|
||||||
@abstractproperty
|
@abstractproperty
|
||||||
def branch(self):
|
def branch(self):
|
||||||
"""Current branch or bookmark the checkout has active."""
|
"""Current branch or bookmark the checkout has active."""
|
||||||
|
|
||||||
|
@abstractproperty
|
||||||
|
def all_remote_names(self):
|
||||||
|
"""Name of all configured remote repositories."""
|
||||||
|
|
||||||
|
@abstractproperty
|
||||||
|
def default_remote_name(self):
|
||||||
|
"""Name the VCS defines for the remote repository when cloning
|
||||||
|
it for the first time. This name may not exist anymore if users
|
||||||
|
changed the default configuration, for instance."""
|
||||||
|
|
||||||
|
@abstractproperty
|
||||||
|
def remote_name(self):
|
||||||
|
"""Name of the remote repository."""
|
||||||
|
|
||||||
|
def _get_most_suitable_remote(self, remote_instructions):
|
||||||
|
remotes = self.all_remote_names
|
||||||
|
if len(remotes) == 1:
|
||||||
|
return remotes[0]
|
||||||
|
|
||||||
|
if self.default_remote_name in remotes:
|
||||||
|
return self.default_remote_name
|
||||||
|
|
||||||
|
first_remote = remotes[0]
|
||||||
|
logger.warning(
|
||||||
|
f"Unable to determine which remote repository to use between: {remotes}. "
|
||||||
|
f'Arbitrarily using the first one "{first_remote}". Please set an '
|
||||||
|
f"`{self.default_remote_name}` remote if the arbitrarily selected one "
|
||||||
|
f"is not right. To do so: {remote_instructions}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return first_remote
|
||||||
|
|
||||||
|
@abstractproperty
|
||||||
|
def default_branch(self):
|
||||||
|
"""Name of the default branch."""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_url(self, remote=None):
|
def get_url(self, remote=None):
|
||||||
"""Get URL of the upstream repository."""
|
"""Get URL of the upstream repository."""
|
||||||
|
|
@ -55,6 +110,43 @@ class Repository(ABC):
|
||||||
def get_commit_message(self, revision=None):
|
def get_commit_message(self, revision=None):
|
||||||
"""Commit message of specified revision or current commit."""
|
"""Commit message of specified revision or current commit."""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_changed_files(self, diff_filter, mode="unstaged", rev=None, base_rev=None):
|
||||||
|
"""Return a list of files that are changed in:
|
||||||
|
* either this repository's working copy,
|
||||||
|
* or at a given revision (``rev``)
|
||||||
|
* or between 2 revisions (``base_rev`` and ``rev``)
|
||||||
|
|
||||||
|
``diff_filter`` controls which kinds of modifications are returned.
|
||||||
|
It is a string which may only contain the following characters:
|
||||||
|
|
||||||
|
A - Include files that were added
|
||||||
|
D - Include files that were deleted
|
||||||
|
M - Include files that were modified
|
||||||
|
|
||||||
|
By default, all three will be included.
|
||||||
|
|
||||||
|
``mode`` can be one of 'unstaged', 'staged' or 'all'. Only has an
|
||||||
|
effect on git. Defaults to 'unstaged'.
|
||||||
|
|
||||||
|
``rev`` is a specifier for which changesets to consider for
|
||||||
|
changes. The exact meaning depends on the vcs system being used.
|
||||||
|
|
||||||
|
``base_rev`` specifies the range of changesets. This parameter cannot
|
||||||
|
be used without ``rev``. The range includes ``rev`` but excludes
|
||||||
|
``base_rev``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_outgoing_files(self, diff_filter, upstream):
|
||||||
|
"""Return a list of changed files compared to upstream.
|
||||||
|
|
||||||
|
``diff_filter`` works the same as `get_changed_files`.
|
||||||
|
``upstream`` is a remote ref to compare against. If unspecified,
|
||||||
|
this will be determined automatically. If there is no remote ref,
|
||||||
|
a MissingUpstreamRepo exception will be raised.
|
||||||
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def working_directory_clean(self, untracked=False, ignored=False):
|
def working_directory_clean(self, untracked=False, ignored=False):
|
||||||
"""Determine if the working directory is free of modifications.
|
"""Determine if the working directory is free of modifications.
|
||||||
|
|
@ -71,20 +163,33 @@ class Repository(ABC):
|
||||||
def update(self, ref):
|
def update(self, ref):
|
||||||
"""Update the working directory to the specified reference."""
|
"""Update the working directory to the specified reference."""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def find_latest_common_revision(self, base_ref_or_rev, head_rev):
|
||||||
|
"""Find the latest revision that is common to both the given
|
||||||
|
``head_rev`` and ``base_ref_or_rev``"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def does_revision_exist_locally(self, revision):
|
||||||
|
"""Check whether this revision exists in the local repository.
|
||||||
|
|
||||||
|
If this function returns an unexpected value, then make sure
|
||||||
|
the revision was fetched from the remote repository."""
|
||||||
|
|
||||||
|
|
||||||
class HgRepository(Repository):
|
class HgRepository(Repository):
|
||||||
tool = "hg"
|
tool = "hg"
|
||||||
|
default_remote_name = "default"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self._env["HGPLAIN"] = "1"
|
self._env["HGPLAIN"] = "1"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def head_ref(self):
|
def head_rev(self):
|
||||||
return self.run("log", "-r", ".", "-T", "{node}").strip()
|
return self.run("log", "-r", ".", "-T", "{node}").strip()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def base_ref(self):
|
def base_rev(self):
|
||||||
return self.run("log", "-r", "last(ancestors(.) and public())", "-T", "{node}")
|
return self.run("log", "-r", "last(ancestors(.) and public())", "-T", "{node}")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -97,13 +202,85 @@ class HgRepository(Repository):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def all_remote_names(self):
|
||||||
|
remotes = self.run("paths", "--quiet").splitlines()
|
||||||
|
if not remotes:
|
||||||
|
raise RuntimeError("No remotes defined")
|
||||||
|
return remotes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def remote_name(self):
|
||||||
|
return self._get_most_suitable_remote(
|
||||||
|
"Edit .hg/hgrc and add:\n\n[paths]\ndefault = $URL",
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_branch(self):
|
||||||
|
# Mercurial recommends keeping "default"
|
||||||
|
# https://www.mercurial-scm.org/wiki/StandardBranching#Don.27t_use_a_name_other_than_default_for_your_main_development_branch
|
||||||
|
return "default"
|
||||||
|
|
||||||
def get_url(self, remote="default"):
|
def get_url(self, remote="default"):
|
||||||
return self.run("path", "-T", "{url}", remote).strip()
|
return self.run("path", "-T", "{url}", remote).strip()
|
||||||
|
|
||||||
def get_commit_message(self, revision=None):
|
def get_commit_message(self, revision=None):
|
||||||
revision = revision or self.head_ref
|
revision = revision or self.head_rev
|
||||||
return self.run("log", "-r", ".", "-T", "{desc}")
|
return self.run("log", "-r", ".", "-T", "{desc}")
|
||||||
|
|
||||||
|
def _format_diff_filter(self, diff_filter, for_status=False):
|
||||||
|
df = diff_filter.lower()
|
||||||
|
assert all(f in self._valid_diff_filter for f in df)
|
||||||
|
|
||||||
|
# When looking at the changes in the working directory, the hg status
|
||||||
|
# command uses 'd' for files that have been deleted with a non-hg
|
||||||
|
# command, and 'r' for files that have been `hg rm`ed. Use both.
|
||||||
|
return df.replace("d", "dr") if for_status else df
|
||||||
|
|
||||||
|
def _files_template(self, diff_filter):
|
||||||
|
template = ""
|
||||||
|
df = self._format_diff_filter(diff_filter)
|
||||||
|
if "a" in df:
|
||||||
|
template += "{file_adds % '{file}\\n'}"
|
||||||
|
if "d" in df:
|
||||||
|
template += "{file_dels % '{file}\\n'}"
|
||||||
|
if "m" in df:
|
||||||
|
template += "{file_mods % '{file}\\n'}"
|
||||||
|
return template
|
||||||
|
|
||||||
|
def get_changed_files(
|
||||||
|
self, diff_filter="ADM", mode="unstaged", rev=None, base_rev=None
|
||||||
|
):
|
||||||
|
if rev is None:
|
||||||
|
if base_rev is not None:
|
||||||
|
raise ValueError("Cannot specify `base_rev` without `rev`")
|
||||||
|
# Use --no-status to print just the filename.
|
||||||
|
df = self._format_diff_filter(diff_filter, for_status=True)
|
||||||
|
return self.run("status", "--no-status", f"-{df}").splitlines()
|
||||||
|
else:
|
||||||
|
template = self._files_template(diff_filter)
|
||||||
|
revision_argument = rev if base_rev is None else f"{base_rev}~-1::{rev}"
|
||||||
|
return self.run("log", "-r", revision_argument, "-T", template).splitlines()
|
||||||
|
|
||||||
|
def get_outgoing_files(self, diff_filter="ADM", upstream=None):
|
||||||
|
template = self._files_template(diff_filter)
|
||||||
|
|
||||||
|
if not upstream:
|
||||||
|
return self.run(
|
||||||
|
"log", "-r", "draft() and ancestors(.)", "--template", template
|
||||||
|
).split()
|
||||||
|
|
||||||
|
return self.run(
|
||||||
|
"outgoing",
|
||||||
|
"-r",
|
||||||
|
".",
|
||||||
|
"--quiet",
|
||||||
|
"--template",
|
||||||
|
template,
|
||||||
|
upstream,
|
||||||
|
return_codes=(1,),
|
||||||
|
).split()
|
||||||
|
|
||||||
def working_directory_clean(self, untracked=False, ignored=False):
|
def working_directory_clean(self, untracked=False, ignored=False):
|
||||||
args = ["status", "--modified", "--added", "--removed", "--deleted"]
|
args = ["status", "--modified", "--added", "--removed", "--deleted"]
|
||||||
if untracked:
|
if untracked:
|
||||||
|
|
@ -118,34 +295,171 @@ class HgRepository(Repository):
|
||||||
def update(self, ref):
|
def update(self, ref):
|
||||||
return self.run("update", "--check", ref)
|
return self.run("update", "--check", ref)
|
||||||
|
|
||||||
|
def find_latest_common_revision(self, base_ref_or_rev, head_rev):
|
||||||
|
return self.run(
|
||||||
|
"log",
|
||||||
|
"-r",
|
||||||
|
f"last(ancestors('{base_ref_or_rev}') and ancestors('{head_rev}'))",
|
||||||
|
"--template",
|
||||||
|
"{node}",
|
||||||
|
).strip()
|
||||||
|
|
||||||
|
def does_revision_exist_locally(self, revision):
|
||||||
|
try:
|
||||||
|
return self.run("log", "-r", revision).strip() != ""
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
# Error code 255 comes with the message:
|
||||||
|
# "abort: unknown revision $REVISION"
|
||||||
|
if e.returncode == 255:
|
||||||
|
return False
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
class GitRepository(Repository):
|
class GitRepository(Repository):
|
||||||
tool = "git"
|
tool = "git"
|
||||||
|
default_remote_name = "origin"
|
||||||
|
|
||||||
|
_LS_REMOTE_PATTERN = re.compile(r"ref:\s+refs/heads/(?P<branch_name>\S+)\s+HEAD")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def head_ref(self):
|
def head_rev(self):
|
||||||
return self.run("rev-parse", "--verify", "HEAD").strip()
|
return self.run("rev-parse", "--verify", "HEAD").strip()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def base_ref(self):
|
def base_rev(self):
|
||||||
refs = self.run(
|
refs = self.run(
|
||||||
"rev-list", "HEAD", "--topo-order", "--boundary", "--not", "--remotes"
|
"rev-list", "HEAD", "--topo-order", "--boundary", "--not", "--remotes"
|
||||||
).splitlines()
|
).splitlines()
|
||||||
if refs:
|
if refs:
|
||||||
return refs[-1][1:] # boundary starts with a prefix `-`
|
return refs[-1][1:] # boundary starts with a prefix `-`
|
||||||
return self.head_ref
|
return self.head_rev
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def branch(self):
|
def branch(self):
|
||||||
return self.run("branch", "--show-current").strip() or None
|
return self.run("branch", "--show-current").strip() or None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def all_remote_names(self):
|
||||||
|
remotes = self.run("remote").splitlines()
|
||||||
|
if not remotes:
|
||||||
|
raise RuntimeError("No remotes defined")
|
||||||
|
return remotes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def remote_name(self):
|
||||||
|
try:
|
||||||
|
remote_branch_name = self.run(
|
||||||
|
"rev-parse", "--verify", "--abbrev-ref", "--symbolic-full-name", "@{u}"
|
||||||
|
).strip()
|
||||||
|
return remote_branch_name.split("/")[0]
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
# Error code 128 comes with the message:
|
||||||
|
# "fatal: no upstream configured for branch $BRANCH"
|
||||||
|
if e.returncode != 128:
|
||||||
|
raise
|
||||||
|
|
||||||
|
return self._get_most_suitable_remote("`git remote add origin $URL`")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_branch(self):
|
||||||
|
try:
|
||||||
|
# this one works if the current repo was cloned from an existing
|
||||||
|
# repo elsewhere
|
||||||
|
return self._get_default_branch_from_cloned_metadata()
|
||||||
|
except (subprocess.CalledProcessError, RuntimeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
# This call works if you have (network) access to the repo
|
||||||
|
return self._get_default_branch_from_remote_query()
|
||||||
|
except (subprocess.CalledProcessError, RuntimeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# this one is the last resort in case the remote is not accessible and
|
||||||
|
# the local repo is where `git init` was made
|
||||||
|
return self._guess_default_branch()
|
||||||
|
|
||||||
|
def _get_default_branch_from_remote_query(self):
|
||||||
|
# This function requires network access to the repo
|
||||||
|
remote_name = self.remote_name
|
||||||
|
output = self.run("ls-remote", "--symref", remote_name, "HEAD")
|
||||||
|
matches = self._LS_REMOTE_PATTERN.search(output)
|
||||||
|
if not matches:
|
||||||
|
raise RuntimeError(
|
||||||
|
f'Could not find the default branch of remote repository "{remote_name}". '
|
||||||
|
"Got: {output}"
|
||||||
|
)
|
||||||
|
|
||||||
|
branch_name = matches.group("branch_name")
|
||||||
|
return f"{remote_name}/{branch_name}"
|
||||||
|
|
||||||
|
def _get_default_branch_from_cloned_metadata(self):
|
||||||
|
return self.run("rev-parse", "--abbrev-ref", f"{self.remote_name}/HEAD").strip()
|
||||||
|
|
||||||
|
def _guess_default_branch(self):
|
||||||
|
branches = [
|
||||||
|
line.strip()
|
||||||
|
for line in self.run(
|
||||||
|
"branch", "--all", "--no-color", "--format=%(refname)"
|
||||||
|
).splitlines()
|
||||||
|
for candidate_branch in ("main", "master", "branches/default/tip")
|
||||||
|
if line.strip().endswith(candidate_branch)
|
||||||
|
]
|
||||||
|
|
||||||
|
if len(branches) == 1:
|
||||||
|
return branches[0]
|
||||||
|
|
||||||
|
raise RuntimeError(f"Unable to find default branch. Got: {branches}")
|
||||||
|
|
||||||
def get_url(self, remote="origin"):
|
def get_url(self, remote="origin"):
|
||||||
return self.run("remote", "get-url", remote).strip()
|
return self.run("remote", "get-url", remote).strip()
|
||||||
|
|
||||||
def get_commit_message(self, revision=None):
|
def get_commit_message(self, revision=None):
|
||||||
revision = revision or self.head_ref
|
revision = revision or self.head_rev
|
||||||
return self.run("log", "-n1", "--format=%B")
|
return self.run("log", "-n1", "--format=%B")
|
||||||
|
|
||||||
|
def get_changed_files(
|
||||||
|
self, diff_filter="ADM", mode="unstaged", rev=None, base_rev=None
|
||||||
|
):
|
||||||
|
assert all(f.lower() in self._valid_diff_filter for f in diff_filter)
|
||||||
|
|
||||||
|
if rev is None:
|
||||||
|
if base_rev is not None:
|
||||||
|
raise ValueError("Cannot specify `base_rev` without `rev`")
|
||||||
|
cmd = ["diff"]
|
||||||
|
if mode == "staged":
|
||||||
|
cmd.append("--cached")
|
||||||
|
elif mode == "all":
|
||||||
|
cmd.append("HEAD")
|
||||||
|
else:
|
||||||
|
revision_argument = (
|
||||||
|
f"{rev}~1..{rev}" if base_rev is None else f"{base_rev}..{rev}"
|
||||||
|
)
|
||||||
|
cmd = ["log", "--format=format:", revision_argument]
|
||||||
|
|
||||||
|
cmd.append("--name-only")
|
||||||
|
cmd.append("--diff-filter=" + diff_filter.upper())
|
||||||
|
|
||||||
|
files = self.run(*cmd).splitlines()
|
||||||
|
return [f for f in files if f]
|
||||||
|
|
||||||
|
def get_outgoing_files(self, diff_filter="ADM", upstream=None):
|
||||||
|
assert all(f.lower() in self._valid_diff_filter for f in diff_filter)
|
||||||
|
|
||||||
|
not_condition = upstream if upstream else "--remotes"
|
||||||
|
|
||||||
|
files = self.run(
|
||||||
|
"log",
|
||||||
|
"--name-only",
|
||||||
|
f"--diff-filter={diff_filter.upper()}",
|
||||||
|
"--oneline",
|
||||||
|
"--pretty=format:",
|
||||||
|
"HEAD",
|
||||||
|
"--not",
|
||||||
|
not_condition,
|
||||||
|
).splitlines()
|
||||||
|
return [f for f in files if f]
|
||||||
|
|
||||||
def working_directory_clean(self, untracked=False, ignored=False):
|
def working_directory_clean(self, untracked=False, ignored=False):
|
||||||
args = ["status", "--porcelain"]
|
args = ["status", "--porcelain"]
|
||||||
|
|
||||||
|
|
@ -167,6 +481,19 @@ class GitRepository(Repository):
|
||||||
def update(self, ref):
|
def update(self, ref):
|
||||||
self.run("checkout", ref)
|
self.run("checkout", ref)
|
||||||
|
|
||||||
|
def find_latest_common_revision(self, base_ref_or_rev, head_rev):
|
||||||
|
return self.run("merge-base", base_ref_or_rev, head_rev).strip()
|
||||||
|
|
||||||
|
def does_revision_exist_locally(self, revision):
|
||||||
|
try:
|
||||||
|
return self.run("cat-file", "-t", revision).strip() == "commit"
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
# Error code 128 comes with the message:
|
||||||
|
# "git cat-file: could not get object info"
|
||||||
|
if e.returncode == 128:
|
||||||
|
return False
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def get_repository(path):
|
def get_repository(path):
|
||||||
"""Get a repository object for the repository at `path`.
|
"""Get a repository object for the repository at `path`.
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ from taskgraph.config import GraphConfig
|
||||||
from taskgraph.parameters import Parameters
|
from taskgraph.parameters import Parameters
|
||||||
from taskgraph.taskgraph import TaskGraph
|
from taskgraph.taskgraph import TaskGraph
|
||||||
from taskgraph.util.attributes import match_run_on_projects
|
from taskgraph.util.attributes import match_run_on_projects
|
||||||
|
from taskgraph.util.treeherder import join_symbol
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -131,15 +132,26 @@ def verify_task_graph_symbol(task, taskgraph, scratch_pad, graph_config, paramet
|
||||||
treeherder = extra["treeherder"]
|
treeherder = extra["treeherder"]
|
||||||
|
|
||||||
collection_keys = tuple(sorted(treeherder.get("collection", {}).keys()))
|
collection_keys = tuple(sorted(treeherder.get("collection", {}).keys()))
|
||||||
|
if len(collection_keys) != 1:
|
||||||
|
raise Exception(
|
||||||
|
"Task {} can't be in multiple treeherder collections "
|
||||||
|
"(the part of the platform after `/`): {}".format(
|
||||||
|
task.label, collection_keys
|
||||||
|
)
|
||||||
|
)
|
||||||
platform = treeherder.get("machine", {}).get("platform")
|
platform = treeherder.get("machine", {}).get("platform")
|
||||||
group_symbol = treeherder.get("groupSymbol")
|
group_symbol = treeherder.get("groupSymbol")
|
||||||
symbol = treeherder.get("symbol")
|
symbol = treeherder.get("symbol")
|
||||||
|
|
||||||
key = (collection_keys, platform, group_symbol, symbol)
|
key = (platform, collection_keys[0], group_symbol, symbol)
|
||||||
if key in scratch_pad:
|
if key in scratch_pad:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
"conflict between `{}`:`{}` for values `{}`".format(
|
"Duplicate treeherder platform and symbol in tasks "
|
||||||
task.label, scratch_pad[key], key
|
"`{}`and `{}`: {} {}".format(
|
||||||
|
task.label,
|
||||||
|
scratch_pad[key],
|
||||||
|
f"{platform}/{collection_keys[0]}",
|
||||||
|
join_symbol(group_symbol, symbol),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue