forked from mirrors/gecko-dev
91 lines
2.7 KiB
Python
91 lines
2.7 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
"""
|
|
Support for optimizing tasks based on the set of files that have changed.
|
|
"""
|
|
|
|
|
|
import logging
|
|
import os
|
|
|
|
import requests
|
|
from redo import retry
|
|
|
|
from .util.memoize import memoize
|
|
from .util.path import match as match_path
|
|
from .util.vcs import get_repository
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@memoize
|
|
def get_changed_files(head_repository_url, head_rev, base_rev=None):
|
|
"""
|
|
Get the set of files changed between revisions.
|
|
Responses are cached, so multiple calls with the same arguments are OK.
|
|
"""
|
|
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)
|
|
|
|
def get_automationrelevance():
|
|
response = requests.get(url, timeout=30)
|
|
return response.json()
|
|
|
|
contents = retry(get_automationrelevance, attempts=10, sleeptime=10)
|
|
|
|
logger.debug(
|
|
"{} commits influencing task scheduling:".format(len(contents["changesets"]))
|
|
)
|
|
changed_files = set()
|
|
for c in contents["changesets"]:
|
|
desc = "" # Support empty desc
|
|
if c["desc"]:
|
|
desc = c["desc"].splitlines()[0].encode("ascii", "ignore")
|
|
logger.debug(" {cset} {desc}".format(cset=c["node"][0:12], desc=desc))
|
|
changed_files |= set(c["files"])
|
|
|
|
return changed_files
|
|
|
|
|
|
def check(params, file_patterns):
|
|
"""Determine whether any of the files changed between 2 revisions
|
|
match any of the given file patterns."""
|
|
|
|
head_repository_url = params.get("head_repository")
|
|
head_rev = params.get("head_rev")
|
|
if not head_repository_url or not head_rev:
|
|
logger.warning(
|
|
"Missing `head_repository` or `head_rev` parameters; "
|
|
"assuming all files have changed"
|
|
)
|
|
return True
|
|
|
|
base_rev = params.get("base_rev")
|
|
changed_files = get_changed_files(head_repository_url, head_rev, base_rev)
|
|
|
|
for pattern in file_patterns:
|
|
for path in changed_files:
|
|
if match_path(path, pattern):
|
|
return True
|
|
|
|
return False
|