1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 Support for optimizing tasks based on the set of files that have changed.
11 from subprocess
import CalledProcessError
13 from mozbuild
.util
import memoize
14 from mozpack
.path
import join
as join_path
15 from mozpack
.path
import match
as mozpackmatch
16 from mozversioncontrol
import InvalidRepoPath
, get_repository_object
18 from gecko_taskgraph
import GECKO
19 from gecko_taskgraph
.util
.hg
import get_json_pushchangedfiles
21 logger
= logging
.getLogger(__name__
)
25 def get_changed_files(repository
, revision
):
27 Get the set of files changed in the push headed by the given revision.
28 Responses are cached, so multiple calls with the same arguments are OK.
31 return get_json_pushchangedfiles(repository
, revision
)["files"]
33 # We shouldn't hit this error in CI.
34 if os
.environ
.get("MOZ_AUTOMATION"):
37 # We're likely on an unpublished commit, grab changed files from
39 return get_locally_changed_files(GECKO
)
42 def check(params
, file_patterns
):
43 """Determine whether any of the files changed in the indicated push to
44 https://hg.mozilla.org match any of the given file patterns."""
45 repository
= params
.get("head_repository")
46 revision
= params
.get("head_rev")
47 if not repository
or not revision
:
49 "Missing `head_repository` or `head_rev` parameters; "
50 "assuming all files have changed"
54 changed_files
= get_changed_files(repository
, revision
)
56 if "comm_head_repository" in params
:
57 repository
= params
.get("comm_head_repository")
58 revision
= params
.get("comm_head_rev")
61 "Missing `comm_head_rev` parameters; " "assuming all files have changed"
66 join_path("comm", file) for file in get_changed_files(repository
, revision
)
69 for pattern
in file_patterns
:
70 for path
in changed_files
:
71 if mozpackmatch(path
, pattern
):
78 def get_locally_changed_files(repo
):
80 vcs
= get_repository_object(repo
)
81 return set(vcs
.get_outgoing_files("AM"))
82 except (InvalidRepoPath
, CalledProcessError
):