Skip to content
Merged
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
118 changes: 104 additions & 14 deletions src/bazel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,29 @@ impl BazelOptions {
&self,
mut transform: impl FnMut(&mut Target),
) -> Result<Vec<Target>> {
let bzlmod_repos = if self.is_bzlmod_enabled()
&& self.version().is_ok_and(|version| {
version >= BazelVersion(8, 6, 0) && version != BazelVersion(9, 0, 0)
}) {
self.query_bzlmod_repos(&mut transform)
.unwrap_or_else(|error| {
eprintln!("[Warn] failed to hash Bzlmod repositories: {error:#}");
Vec::new()
})
let bzlmod_repos = if self.is_bzlmod_enabled() {
let supports_bzlmod = match self.version() {
Ok(version) => version >= BazelVersion(8, 6, 0) && version != BazelVersion(9, 0, 0),
Err(error) if self.keep_going => {
eprintln!(
"[Warn] failed to check Bazel version for Bzlmod repositories: {error:#}"
);
false
}
Err(error) => return Err(error),
};
if supports_bzlmod {
match self.query_bzlmod_repos(&mut transform) {
Ok(repos) => repos,
Err(error) if self.keep_going => {
eprintln!("[Warn] failed to hash Bzlmod repositories: {error:#}");
Vec::new()
}
Err(error) => return Err(error),
}
} else {
Vec::new()
}
} else {
Vec::new()
};
Expand Down Expand Up @@ -260,11 +274,11 @@ impl BazelOptions {
bail!("bazel mod show_repo failed with {}", output.status);
}
let repositories = decode_delimited::<Repository>(output_file.path())?;
let module_edges = self
.module_graph_json()
.as_deref()
.map(parse_module_dependency_edges)
.unwrap_or_default();
let module_edges = match self.module_graph_json() {
Some(json) => parse_module_dependency_edges(&json),
None if self.keep_going => BTreeMap::new(),
None => bail!("bazel mod graph --output=json failed"),
};
Ok(lower_repositories(
repositories,
&canonical_to_apparent,
Expand Down Expand Up @@ -1614,4 +1628,80 @@ exit 1
.all(|character| character.is_ascii_hexdigit()));
assert!(selected_repos_marker.is_file());
}

#[test]
#[cfg(unix)]
fn query_bzlmod_repos_honors_keep_going() {
let workspace = tempfile::tempdir().unwrap();
let query_proto = workspace.path().join("query-result.pb");
write_delimited(&query_proto, &[rule_target("//app:lib")]);

// Fake Bazel where `mod graph` succeeds (`is_bzlmod_enabled()` is true),
// `version` returns 8.6.1, `mod dump_repo_mapping` returns an external repo,
// `mod show_repo` fails, and `query` writes `//app:lib` to `--output_file`.
let show_repo_fail_script = workspace.path().join("fake-bazel-show-repo-fail.sh");
let body = format!(
r#"#!/bin/sh
args="$*"
if echo "$args" | grep -q "mod graph"; then
echo "root"
exit 0
fi
if echo "$args" | grep -q "version"; then
echo "Build label: 8.6.1"
exit 0
fi
if echo "$args" | grep -q "mod dump_repo_mapping"; then
echo '{{"pip":"rules_python+0.31.0"}}'
exit 0
fi
if echo "$args" | grep -q "mod show_repo"; then
echo "transient fetch failure" >&2
exit 2
fi
while [ "$#" -gt 0 ]; do
if [ "$1" = "--output_file" ]; then
cp "{}" "$2"
exit 0
fi
shift
done
exit 1
"#,
query_proto.display(),
);
fs::write(&show_repo_fail_script, body).unwrap();
let mut permissions = fs::metadata(&show_repo_fail_script).unwrap().permissions();
permissions.set_mode(0o755);
fs::set_permissions(&show_repo_fail_script, permissions).unwrap();

let mut options = BazelOptions {
workspace: workspace.path().to_path_buf(),
bazel: show_repo_fail_script,
startup_options: Vec::new(),
command_options: Vec::new(),
cquery_options: Vec::new(),
use_cquery: false,
cquery_expression: None,
keep_going: false,
fine_grained_external_repos: BTreeSet::new(),
exclude_external_targets: true,
exclude_targets_query: None,
no_bazelrc: false,
verbose: false,
};

let show_repo_err = options.query_all_targets().unwrap_err();
assert!(show_repo_err
.to_string()
.contains("bazel mod show_repo failed"));

// With `keep_going = true`, `query_all_targets` logs a warning and falls back to main targets.
options.keep_going = true;
let targets = options.query_all_targets().unwrap();
assert_eq!(
targets.iter().filter_map(target_name).collect::<Vec<_>>(),
["//app:lib"]
);
}
}
Loading