mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:10:12 +01:00
We only had the single `clang` symlink, but in case its useful to use the toolchain with some other build system that expects `clang++`, or even `clang-cl` or `clang-cpp`, fill in the rest of the symlinks. The different `clang` flavors don't really need anything to support in the subcommand as there is already an excellent way to get the exact behavior of these names using Clang's `--driver-mode` flag, so these just use that. That makes this change really *only* about busybox behavior. We don't really have a dedicated test path for things that are only exposed via the symlinks, so I've added a simple Python integration test we can use for that. I can backfill some testing of other symlinks if useful (the `ld.lld` one might be worthwhile), although there is minimal interesting logic to cover there.
112 lines
3.2 KiB
Python
Executable File
112 lines
3.2 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:
|
|
# Need to quote targets for inclusion in another query.
|
|
quoted_targets = "\n".join([f'"{t}"' for t in targets.splitlines()])
|
|
|
|
with tempfile.NamedTemporaryFile(mode="w+") as tmp:
|
|
query = (
|
|
f"let t = set({quoted_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_release(
|
|
scripts_utils.Release.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()
|