mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
108 lines
3.0 KiB
Python
Executable File
108 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
"""Computes the potentially differing rules from some git commit.
|
|
|
|
Wraps the "target-determinator" Go program here:
|
|
https://github.com/bazel-contrib/target-determinator
|
|
|
|
The purpose is to compute the potentially impacted set of targets from some
|
|
provided Git commit to the current checkout.
|
|
|
|
This script will ensure a cached version of the latest release is available, and
|
|
then forward a limited set of flags to it. This script also filters the
|
|
resulting targets using `bazel query` to make it the most relevant list for
|
|
continuous integration.
|
|
"""
|
|
|
|
__copyright__ = """
|
|
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
Exceptions. See /LICENSE for license information.
|
|
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
"""
|
|
|
|
import subprocess
|
|
import argparse
|
|
import tempfile
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import scripts_utils
|
|
|
|
|
|
def log(s: str) -> None:
|
|
print(s, file=sys.stderr)
|
|
|
|
|
|
def filter_targets(bazel: Path, targets: str) -> str:
|
|
with tempfile.NamedTemporaryFile(mode="w+") as tmp:
|
|
query = (
|
|
f"let t = set({targets}) in "
|
|
"kind(rule, $t) except attr(tags, manual, $t)\n"
|
|
)
|
|
query_lines = query.splitlines()
|
|
if len(query_lines) <= 10:
|
|
query_snippet = "\n".join(query_lines)
|
|
else:
|
|
query_snippet = "\n".join(
|
|
query_lines[:5] + ["..."] + query_lines[-5:]
|
|
)
|
|
log(f"Bazel query snippet:\n```\n{query_snippet}\n```")
|
|
tmp.write(query)
|
|
tmp.flush()
|
|
try:
|
|
p = subprocess.run(
|
|
[str(bazel), "query", f"--query_file={tmp.name}"],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
check=True,
|
|
encoding="utf-8",
|
|
)
|
|
return p.stdout
|
|
except subprocess.CalledProcessError as err:
|
|
log(err.stderr)
|
|
log("Full query file:\n```")
|
|
with open(tmp.name) as f:
|
|
log(f.read())
|
|
log("```")
|
|
raise
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(__doc__)
|
|
parser.add_argument(
|
|
"baseline", nargs=1, help="Git commit of the diff baseline."
|
|
)
|
|
parser.add_argument(
|
|
"args",
|
|
nargs="*",
|
|
help="Remaining args to forward to the underlying tool.",
|
|
)
|
|
parsed_args = parser.parse_args()
|
|
|
|
scripts_utils.chdir_repo_root()
|
|
bazel = Path(scripts_utils.locate_bazel())
|
|
target_determinator = scripts_utils.get_target_determinator()
|
|
|
|
p = subprocess.run(
|
|
[
|
|
target_determinator,
|
|
f"--bazel={bazel}",
|
|
parsed_args.baseline[0],
|
|
]
|
|
+ parsed_args.args,
|
|
check=True,
|
|
stdout=subprocess.PIPE,
|
|
encoding="utf-8",
|
|
)
|
|
|
|
targets = p.stdout
|
|
if targets.strip() != "":
|
|
targets = filter_targets(bazel, targets)
|
|
log(f"Found {len(targets.splitlines())} impacted targets!")
|
|
|
|
print(targets.rstrip())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|