Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/bazel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1552,7 +1552,14 @@ impl BazelOptions {
if "IncompatiblePlatformProvider" not in providers(target):
target_repr = repr(target)
if "<alias target" in target_repr:
return target_repr.split(" ")[2]
# repr() prints a main-repository alias with its apparent label
# (`//:tool`) even under --consistent_labels, while every other
# target is canonical (`@@//:tool`). Normalize so the alias
# matches the label it is later looked up by.
label = target_repr.split(" ")[2]
if label.startswith("//"):
label = "@@" + label
return label
return str(target.label)
return ""
"#,
Expand Down
81 changes: 81 additions & 0 deletions tests/e2e/regressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1259,3 +1259,84 @@ fn serve_rejects_packages_the_revision_does_not_track() {
assert!(labels.is_superset(&expected_after_deletion()), "{labels:?}");
}
}

/// Control for <https://github.com/Tinder/bazel-diff/issues/612>: in query mode a change
/// behind a main-repository `alias` reaches the target that uses the alias.
#[test]
fn main_repo_alias_change_reaches_consumer_query() {
let first = copy_workspace("cquery_main_repo_alias");
let second = copy_workspace("cquery_main_repo_alias");
fs::write(second.path().join("bar/baz.txt"), "after\n").unwrap();
let impacted = diff_workspaces(first.path(), second.path(), &[]);
for name in ["//bar:baz.txt", "//bar:baz", "//:tool", "//:wrapper"] {
assert!(
impacted
.iter()
.any(|label| label == name || label.trim_start_matches("@@") == name),
"{name} should be impacted through the alias, got {impacted:?}"
);
}
}

/// Reproducer for <https://github.com/Tinder/bazel-diff/issues/612>: under `--useCquery`
/// the compatible-target cquery names a main-repository alias by `repr(target)`, which
/// Bazel prints with its apparent label (`//:tool`) even under `--consistent_labels`,
/// while the target itself is named canonically (`@@//:tool`). The two never match, so
/// the alias is filtered out as if it were platform-incompatible and takes its edges with
/// it: `//:wrapper` has no node for `//:tool` to depend on and is never impacted.
#[test]
fn main_repo_alias_change_reaches_consumer_cquery() {
let first = copy_workspace("cquery_main_repo_alias");
let second = copy_workspace("cquery_main_repo_alias");
fs::write(second.path().join("bar/baz.txt"), "after\n").unwrap();

let output = tempfile::tempdir().unwrap();
let from = output.path().join("from.json");
let to = output.path().join("to.json");
let edges_file = output.path().join("edges.json");
let result = output.path().join("impacted.txt");
assert!(generate(first.path(), &from, &["--useCquery"])
.status
.success());
assert!(generate(
second.path(),
&to,
&[
"--useCquery",
"--depEdgesFile",
edges_file.to_str().unwrap()
],
)
.status
.success());
assert!(impacted(second.path(), &from, &to, &result, &[])
.status
.success());

let hashes = hashes(&to);
assert!(
hashes.keys().any(|label| label.ends_with("//:tool")),
"the alias //:tool was dropped from the cquery hashes: {:?}",
hashes.keys().collect::<Vec<_>>()
);
let edges = dep_edges(&edges_file);
let wrapper_edges = edges
.iter()
.find(|(label, _)| label.ends_with("//:wrapper"))
.map(|(_, deps)| deps.clone())
.expect("//:wrapper has dep edges");
assert!(
wrapper_edges.iter().any(|dep| dep.ends_with("//:tool")),
"//:wrapper lost its edge to the alias //:tool: {wrapper_edges:?}"
);

let impacted = read_lines(&result);
for name in ["//bar:baz.txt", "//bar:baz", "//:tool", "//:wrapper"] {
assert!(
impacted
.iter()
.any(|label| label == name || label.trim_start_matches("@@") == name),
"{name} should be impacted through the alias under cquery, got {impacted:?}"
);
}
}
14 changes: 14 additions & 0 deletions tests/resources/workspaces/cquery_main_repo_alias/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# A main-repository alias in front of the file that changes. `//:wrapper`
# reaches `bar/baz.txt` only through the alias, so it must be impacted when
# the file changes.
alias(
name = "tool",
actual = "//bar:baz",
)

genrule(
name = "wrapper",
srcs = [":tool"],
outs = ["wrapper.txt"],
cmd = "cat $(SRCS) > $@",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module(
name = "cquery_main_repo_alias",
version = "0.0.0",
)
25 changes: 25 additions & 0 deletions tests/resources/workspaces/cquery_main_repo_alias/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Main-repository alias under cquery

Reproduces [GitHub Issue #612](https://github.com/Tinder/bazel-diff/issues/612):
with `--useCquery`, a target that reaches its inputs through a main-repository
`alias` stops seeing changes to them.

## The graph

`//:wrapper` (a `genrule`) lists `//:tool` in its `srcs`. `//:tool` is an
`alias` of `//bar:baz`, a `filegroup` over `bar/baz.txt`.

## Expected behaviour

Changing `bar/baz.txt` impacts `//bar:baz.txt`, `//bar:baz`, `//:tool`,
`//:wrapper` and `//:wrapper.txt`, in query mode and in cquery mode alike.

## Behaviour before the fix

The compatible-target cquery that filters out `IncompatiblePlatformProvider`
targets names an alias by `repr(target)`, and Bazel prints a main-repository
alias with its apparent label (`//:tool`) even under `--consistent_labels`,
while every other target is canonical (`@@//:tool`). The two never match, so
the alias is dropped as if it were incompatible, and with it every edge from
`//:wrapper` through it. Under cquery only `@@//bar:baz` and `@@//bar:baz.txt`
are reported as impacted.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
filegroup(
name = "baz",
srcs = ["baz.txt"],
visibility = ["//visibility:public"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
before
8 changes: 8 additions & 0 deletions tools/e2e/rust_e2e_cases.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ RUST_E2E_SUITES = [
"name": "regressions::macro_bzl_change_impacts_callers",
"timeout": "moderate",
},
{
"name": "regressions::main_repo_alias_change_reaches_consumer_cquery",
"timeout": "moderate",
},
{
"name": "regressions::main_repo_alias_change_reaches_consumer_query",
"timeout": "moderate",
},
{
"name": "regressions::module_comment_and_lock_reformat_are_noops",
"timeout": "moderate",
Expand Down
Loading