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
27 changes: 27 additions & 0 deletions .aspect/axl.axl
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,32 @@ def test_http(ctx: TaskContext, tc: int, temp_dir: str) -> int:

return tc

def test_conditional_flags(ctx: TaskContext, tc: int) -> int:
# Test 1: plain string flags still work (backward compat)
build1 = ctx.bazel.build(
"//crates/aspect-cli:aspect-cli",
flags = ["--nobuild"],
)
tc = test_case(tc, build1.wait().success, "plain flags should still work")

# Test 2: always-matching conditional flag is applied
# ("--nobuild", ">=1") should always match; build completes with analysis only
build2 = ctx.bazel.build(
"//crates/aspect-cli:aspect-cli",
flags = [("--nobuild", ">=1")],
)
tc = test_case(tc, build2.wait().success, "always-matching conditional flag should be applied")

# Test 3: never-matching conditional flag is dropped
# "--ASPECT_NEVER_MATCH_FLAG_XYZ" would cause a hard bazel error if NOT dropped
build3 = ctx.bazel.build(
"//crates/aspect-cli:aspect-cli",
flags = ["--nobuild", ("--ASPECT_NEVER_MATCH_FLAG_XYZ", ">=99999")],
)
tc = test_case(tc, build3.wait().success, "never-matching conditional flag should be silently dropped")

return tc

def test_http_get_post(ctx: TaskContext, tc: int, temp_dir: str) -> int:
# Test HTTP get and post methods including unix_socket support

Expand Down Expand Up @@ -482,6 +508,7 @@ def impl(ctx: TaskContext) -> int:
tc = test_http(ctx, tc, temp_dir)
tc = test_bazel_info(ctx, tc)
tc = test_http_get_post(ctx, tc, temp_dir)
tc = test_conditional_flags(ctx, tc)

print(tc, "tests passed")
return 0
Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/axl-runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ rust_library(
"@crates//:wasmi",
"@crates//:zstd",
"@crates//:base64",
"@crates//:semver",
"//crates/axl-proto",
"//crates/build-event-stream",
"//crates/galvanize",
Expand Down
1 change: 1 addition & 0 deletions crates/axl-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ starlark_derive = "0.13.0"
starlark_map = "0.13.0"

anyhow = "1.0.98"
semver = "1"
thiserror = "2.0.12"

prost = "0.14.1"
Expand Down
51 changes: 46 additions & 5 deletions crates/axl-runtime/src/engine/bazel/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,19 +143,60 @@ pub struct Build {
}

impl Build {
pub fn pid() -> io::Result<u32> {
pub fn server_info() -> io::Result<(u32, semver::Version)> {
let mut cmd = Command::new("bazel");
cmd.arg("info");
cmd.arg("server_pid");
cmd.arg("release");
cmd.stdout(Stdio::piped());
cmd.stderr(Stdio::null());
cmd.stdin(Stdio::null());
let c = cmd.spawn()?.wait_with_output()?;
if !c.status.success() {
return Err(io::Error::other(anyhow!("failed to determine Bazel pid")));
return Err(io::Error::other(anyhow!(
"failed to determine Bazel server info"
)));
}
let bytes: [u8; 4] = c.stdout[0..4].try_into().unwrap();
Ok(u32::from_be_bytes(bytes))

// When bazel info is called with multiple keys it emits "key: value" lines.
let stdout = String::from_utf8_lossy(&c.stdout);
let mut pid: Option<u32> = None;
let mut version: Option<semver::Version> = None;
for line in stdout.lines() {
if let Some((key, value)) = line.split_once(": ") {
match key.trim() {
"server_pid" => {
pid = value.trim().parse::<u32>().ok();
}
"release" => {
// Value is like "release 9.0.0" or "release 9.0.0-rc1"
let ver_str = value.trim().trim_start_matches("release ").trim();
// Strip pre-release suffix: "9.0.0-rc1" -> "9.0.0"
let ver_str = ver_str.split('-').next().unwrap_or(ver_str);
version = semver::Version::parse(ver_str)
.map_err(|e| {
io::Error::other(anyhow!(
"failed to parse Bazel version '{}': {}",
ver_str,
e
))
})
.ok();
}
_ => {}
}
}
}

let pid =
pid.ok_or_else(|| io::Error::other(anyhow!("bazel info did not return server_pid")))?;
let version = version.ok_or_else(|| {
io::Error::other(anyhow!(
"bazel info did not return a parseable release version"
))
})?;

Ok((pid, version))
}

// TODO: this should return a thiserror::Error
Expand All @@ -172,7 +213,7 @@ impl Build {
current_dir: Option<String>,
rt: AsyncRuntime,
) -> Result<Build, std::io::Error> {
let pid = Self::pid()?;
let (pid, _) = Self::server_info()?;

let span = tracing::info_span!(
"ctx.bazel.build",
Expand Down
Loading