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
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module(
name = "bazel-diff",
version = "17.0.3",
version = "17.1.0",
compatibility_level = 0,
)

Expand Down
2 changes: 1 addition & 1 deletion MODULE.bazel.lock

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

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ First, add the following snippet to your project:
#### Bzlmod snippet

```bazel
bazel_dep(name = "bazel-diff", version = "15.0.5")
bazel_dep(name = "bazel-diff", version = "17.1.0")
```

You can now run the tool with:
Expand Down
19 changes: 13 additions & 6 deletions cli/src/main/kotlin/com/bazel_diff/bazel/BazelQueryService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class BazelQueryService(

@OptIn(ExperimentalCoroutinesApi::class)
private suspend fun determineBazelVersion(): Triple<Int, Int, Int> {
val cmd = arrayOf(bazelPath.toString(), "--version")
val cmd = arrayOf(bazelPath.toString(), "version")
logger.i { "Executing Bazel version command: ${cmd.joinToString()}" }
val result =
process(
Expand All @@ -45,12 +45,19 @@ class BazelQueryService(
throw RuntimeException("Bazel version command failed, exit code ${result.resultCode}")
}

if (result.output.size != 1 || !result.output.first().startsWith("bazel ")) {
throw RuntimeException("Bazel version command returned unexpected output: ${result.output}")
}
// "bazel version" outputs "Build label: X.Y.Z" on one of the lines; accept that or legacy "bazel X.Y.Z".
val versionString =
result.output
.firstOrNull { it.startsWith("Build label: ") }
?.removePrefix("Build label: ")?.trim()
?: result.output
.firstOrNull { it.startsWith("bazel ") }
?.removePrefix("bazel ")?.trim()
?: throw RuntimeException(
"Bazel version command returned unexpected output: ${result.output}")
// Trim off any prerelease suffixes (e.g., 8.6.0-rc1 or 8.6.0rc1).
val versionString = result.output.first().removePrefix("bazel ").trim().split('-')[0]
val version = versionString.split('.').map { it.takeWhile { c -> c.isDigit() }.toInt() }.toTypedArray()
val version =
versionString.split('-')[0].split('.').map { it.takeWhile { c -> c.isDigit() }.toInt() }.toTypedArray()
return Triple(version[0], version[1], version[2])
}

Expand Down
44 changes: 44 additions & 0 deletions cli/src/test/kotlin/com/bazel_diff/e2e/E2ETest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,37 @@ class E2ETest {
testE2E(emptyList(), emptyList(), "/fixture/impacted_targets-1-2.txt")
}

@Test
fun testDetermineBazelVersion() {
// E2E coverage for BazelQueryService.determineBazelVersion(): version is resolved lazily
// when the first query runs. Running generate-hashes to completion validates that
// "bazel version" is executed and parsed successfully (e.g. "Build label: X.Y.Z").
val projectA = extractFixtureProject("/fixture/integration-test-1.zip")
val workingDirectory = File(projectA, "integration")
val outputDir = temp.newFolder()
val outputPath = File(outputDir, "hashes.json")

val cli = CommandLine(BazelDiff())
val exitCode = cli.execute(
"generate-hashes",
"-w",
workingDirectory.absolutePath,
"-b",
"bazel",
outputPath.absolutePath)

assertThat(exitCode).isEqualTo(0)
assertThat(outputPath.readText().isNotEmpty()).isEqualTo(true)
}

@Test
fun testE2EWithNoKeepGoing() {
testE2E(
listOf("--no-keep_going"),
emptyList(),
"/fixture/impacted_targets-1-2.txt")
}

@Test
fun testE2EIncludingTargetType() {
testE2E(
Expand Down Expand Up @@ -996,6 +1027,19 @@ class E2ETest {
// which is designed to fail during analysis
assertThat(exitCodeWithCquery).isEqualTo(1)

// Test with --no-keep_going: cquery should fail (no partial results, immediate failure)
val outputNoKeepGoing = File(outputDir, "hashes_no_keep_going.json")
val exitCodeWithNoKeepGoing = cli.execute(
"generate-hashes",
"-w",
workspace.absolutePath,
"-b",
"bazel",
"--useCquery",
"--no-keep_going",
outputNoKeepGoing.absolutePath)
assertThat(exitCodeWithNoKeepGoing).isEqualTo(1)

// Test with --keep_going enabled (default behavior)
// With keep_going, cquery returns partial results but still exits with code 1
// The current implementation allows exit codes 0 and 3, but cquery with keep_going
Expand Down
Loading