69 lines
2.2 KiB
Python
69 lines
2.2 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/.
|
|
|
|
import functools
|
|
from pathlib import Path
|
|
|
|
from gecko_taskgraph import GECKO
|
|
|
|
|
|
@functools.cache
|
|
def _get_taskgraph_sparse_profile():
|
|
"""
|
|
Parse the taskgraph sparse profile and return the paths and globs it includes.
|
|
"""
|
|
|
|
# We need this nested function to handle %include directives recursively
|
|
def parse(profile_path):
|
|
paths = set()
|
|
globs = set()
|
|
|
|
full_path = Path(GECKO) / profile_path
|
|
if not full_path.exists():
|
|
raise FileNotFoundError(
|
|
f"Sparse profile '{full_path.stem}' not found at {full_path}"
|
|
)
|
|
|
|
for raw_line in full_path.read_text().splitlines():
|
|
line = raw_line.strip()
|
|
if not line or line.startswith("#") or line.startswith("["):
|
|
continue
|
|
if line.startswith("%include "):
|
|
included_profile = line[len("%include ") :].strip()
|
|
included_paths, included_globs = parse(included_profile)
|
|
paths.update(included_paths)
|
|
globs.update(included_globs)
|
|
elif line.startswith("path:"):
|
|
path = line[len("path:") :].strip()
|
|
paths.add(Path(path))
|
|
elif line.startswith("glob:"):
|
|
glob = line[len("glob:") :].strip()
|
|
globs.add(glob)
|
|
|
|
return paths, globs
|
|
|
|
return parse("build/sparse-profiles/taskgraph")
|
|
|
|
|
|
@functools.cache
|
|
def is_path_covered_by_taskgraph_sparse_profile(path):
|
|
"""
|
|
Check if a given path would be included in the taskgraph sparse checkout.
|
|
"""
|
|
profile_paths, profile_globs = _get_taskgraph_sparse_profile()
|
|
path = Path(path)
|
|
|
|
for profile_path in profile_paths:
|
|
if path == profile_path or profile_path in path.parents:
|
|
return True
|
|
|
|
# Path.match requires at least one directory for ** patterns to match
|
|
# root-level files, so we prepend a fake parent directory
|
|
path_with_parent = Path("_", path)
|
|
for pattern in profile_globs:
|
|
if path_with_parent.match(pattern):
|
|
return True
|
|
|
|
return False
|