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
4 changes: 2 additions & 2 deletions .github/workflows/serve-harness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: Serve Harness

# Integration validation for the `bazel-diff serve` query service. Runs tools/serve_harness.py,
# which builds //cli:bazel-diff and drives the real binary over HTTP against a live git:// remote
# (git daemon) across both git engines x full/shallow/partial clones -- coverage the in-process
# E2ETest cannot reach. See the harness module docstring for the scenario matrix.
# (git daemon) across full/shallow/partial clones -- coverage the in-process E2ETest cannot reach.
# See the harness module docstring for the scenario matrix.

# Cron-only for now while we confirm the harness is stable on CI runners. Once it has a healthy
# track record, add `pull_request` / `push` triggers (and/or make it a required status check) to
Expand Down
9 changes: 0 additions & 9 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ maven.install(
artifacts = [
"com.google.code.gson:gson:2.9.0@jar",
"com.google.guava:guava:31.1-jre",
# JGit powers the `serve` command's in-process git engine. Pinned to the 5.13.x line, the
# last release series that still targets Java 8 (matching bazel-diff's documented minimum).
"org.eclipse.jgit:org.eclipse.jgit:5.13.3.202401111512-r",
"com.willowtreeapps.assertk:assertk-jvm:0.25",
"info.picocli:picocli:4.6.3@jar",
"io.insert-koin:koin-core-jvm:3.1.6",
Expand All @@ -61,12 +58,6 @@ maven.install(
"org.apache.commons:commons-pool2:2.11.1",
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2",
"org.mockito.kotlin:mockito-kotlin:5.4.0",
# SLF4J binding for JGit (serve command). JGit depends on slf4j-api but ships no binding, so
# without one SLF4J prints a "Failed to load class StaticLoggerBinder / Defaulting to NOP"
# warning to stderr on first use. slf4j-nop supplies the binding (silencing the warning) and
# discards JGit's internal logs, keeping the CLI's stderr clean. Version tracks the slf4j-api
# that JGit 5.13.x resolves (1.7.30).
"org.slf4j:slf4j-nop:1.7.30",
],
fail_if_repin_required = True,
lock_file = "//:maven_install.json",
Expand Down
30 changes: 9 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ curl 'http://localhost:8080/metrics'
"version": "31.4.0",
"uptimeSeconds": 3600,
"ready": true,
"gitEngine": "jgit",
"gitEngine": "subprocess",
"trackDeps": false,
"cache": {"directory": "/var/cache/bazel-diff", "entries": 128, "sizeBytes": 4823913, "sizeHuman": "4.6 MB"},
"jvm": {"usedBytes": 123456789, "maxBytes": 2147483648}
Expand All @@ -204,17 +204,11 @@ Notes and current limitations:
* The service checks out revisions inside `--workspacePath`, so point it at a dedicated clone, not a
working tree you edit. All workspace-mutating work (git checkout + `bazel query`) is serialized,
so a single instance answers one cold query at a time; the per-SHA cache absorbs the rest.
* Git operations run in-process via JGit by default (no `git` binary required). Pass
`--gitEngine=subprocess` to shell out to the `git` binary at `--gitPath` instead -- useful for
workspaces that depend on checkout filters or hooks that JGit does not run. Note that JGit only
moves the git plumbing in-process; the working tree is still materialized on disk for `bazel query`.
JGit cannot fetch some clone shapes native git handles fine -- notably shallow (`--depth`) and
partial (`--filter=blob:none`) clones, whose thin packs are delta-compressed against objects the
clone does not have ("Missing delta base"). When an in-process JGit fetch fails, the service
automatically falls back to the native `git` binary (at `--gitPath`) for that fetch and logs a
warning; point `--gitEngine=subprocess` at such workspaces to skip the in-process attempt (a
partial clone in particular needs the subprocess engine to *serve* queries, since JGit cannot
lazily fetch the missing blobs a checkout needs).
* Git operations (fetch and checkout) shell out to the `git` binary at `--gitPath` (default `git`
on the `PATH`), so a `git` binary must be available on the host. The working tree is checked out
on disk for `bazel query` to read. Because native git performs every fetch, all clone shapes are
supported -- including shallow (`--depth`) and partial (`--filter=blob:none`) clones, whose thin
packs are delta-compressed against objects the clone does not have.
* Hashes are cached on local disk via `--cacheDir` and survive restarts. Left unbounded the cache
grows by one entry per distinct commit SHA queried, so a long-running server can bound it with any
combination of `--cacheMaxAge` (expire entries not read or written within a window, e.g. `7d`),
Expand Down Expand Up @@ -498,8 +492,7 @@ Usage: bazel-diff serve [-hkvV] [--[no-]excludeExternalTargets]
[--cqueryExpression=<cqueryExpression>]
[--excludeTargetsQuery=<excludeTargetsQuery>]
[--fineGrainedHashExternalReposFile=<fineGrainedHashExte
rnalReposFile>] [--gitEngine=<gitEngine>]
[--gitPath=<gitPath>] [--port=<port>]
rnalReposFile>] [--gitPath=<gitPath>] [--port=<port>]
[--requestTimeout=<requestTimeoutSeconds>]
[-s=<seedFilepaths>] -w=<workspacePath>
[-co=<bazelCommandOptions>]...
Expand Down Expand Up @@ -562,13 +555,8 @@ targets between two git revisions, caching generated hashes per commit SHA.
A text file with a newline separated list of
external repos. Mutually exclusive with
--fineGrainedHashExternalRepos.
--gitEngine=<gitEngine>
Git backend: 'jgit' (in-process, no git binary
required) or 'subprocess' (shells out to
--gitPath). Defaults to 'jgit'.
--gitPath=<gitPath> Path to the git binary, used only when
--gitEngine=subprocess. Defaults to 'git' on the
PATH.
--gitPath=<gitPath> Path to the git binary used for fetch/checkout
operations. Defaults to 'git' on the PATH.
-h, --help Show this help message and exit.
--ignoredRuleHashingAttributes=<ignoredRuleHashingAttributes>
Attributes that should be ignored when hashing rule
Expand Down
21 changes: 0 additions & 21 deletions cli/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ kt_jvm_library(
name = "cli-lib",
srcs = glob(["src/main/kotlin/**/*.kt"]),
resources = [":version_file"],
# SLF4J binding for JGit. Not referenced by bazel-diff code (JGit uses it internally), so it is a
# pure runtime dep: it supplies org.slf4j.impl.StaticLoggerBinder, silencing the "Defaulting to
# NOP logger" warning SLF4J prints to stderr when no binding is on the classpath.
runtime_deps = [
"@bazel_diff_maven//:org_slf4j_slf4j_nop",
],
deps = [
"//proto:analysis_v2_java_proto",
"//proto:build_java_proto",
Expand All @@ -44,7 +38,6 @@ kt_jvm_library(
"@bazel_diff_maven//:info_picocli_picocli",
"@bazel_diff_maven//:io_insert_koin_koin_core_jvm",
"@bazel_diff_maven//:org_apache_commons_commons_pool2",
"@bazel_diff_maven//:org_eclipse_jgit_org_eclipse_jgit",
"@bazel_diff_maven//:org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm",
],
)
Expand Down Expand Up @@ -193,12 +186,6 @@ kt_jvm_test(
runtime_deps = [":cli-test-lib"],
)

kt_jvm_test(
name = "Slf4jBindingTest",
test_class = "com.bazel_diff.log.Slf4jBindingTest",
runtime_deps = [":cli-test-lib"],
)

kt_jvm_test(
name = "BazelModServiceTest",
test_class = "com.bazel_diff.bazel.BazelModServiceTest",
Expand Down Expand Up @@ -273,12 +260,6 @@ kt_jvm_test(
runtime_deps = [":cli-test-lib"],
)

kt_jvm_test(
name = "JGitClientTest",
test_class = "com.bazel_diff.server.JGitClientTest",
runtime_deps = [":cli-test-lib"],
)

kt_jvm_test(
name = "HashServiceTest",
jvm_flags = [
Expand Down Expand Up @@ -315,8 +296,6 @@ kt_jvm_library(
"@bazel_diff_maven//:io_insert_koin_koin_test_jvm",
"@bazel_diff_maven//:junit_junit",
"@bazel_diff_maven//:org_mockito_kotlin_mockito_kotlin",
# Compile-time API for Slf4jBindingTest; the runtime binding (slf4j-nop) comes via cli-lib.
"@bazel_diff_maven//:org_slf4j_slf4j_api",
],
)

Expand Down
30 changes: 5 additions & 25 deletions cli/src/main/kotlin/com/bazel_diff/cli/ServeCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import com.bazel_diff.server.HashCacheStorage
import com.bazel_diff.server.HashProvider
import com.bazel_diff.server.HashService
import com.bazel_diff.server.ImpactedTargetsService
import com.bazel_diff.server.JGitClient
import com.bazel_diff.server.LocalDiskHashCacheStorage
import com.bazel_diff.server.MetricsService
import com.bazel_diff.server.ProcessGitClient
Expand Down Expand Up @@ -56,8 +55,6 @@ import picocli.CommandLine
class ServeCommand : Callable<Int> {
@CommandLine.ParentCommand private lateinit var parent: BazelDiff

@CommandLine.Spec lateinit var spec: CommandLine.Model.CommandSpec

@CommandLine.Option(
names = ["-w", "--workspacePath"],
description = ["Path to the Bazel workspace git clone the service checks out and queries."],
Expand All @@ -77,18 +74,10 @@ class ServeCommand : Callable<Int> {
names = ["--gitPath"],
description =
[
"Path to the git binary, used only when --gitEngine=subprocess. Defaults to 'git' on the PATH."],
"Path to the git binary used for fetch/checkout operations. Defaults to 'git' on the PATH."],
defaultValue = "git")
var gitPath: String = "git"

@CommandLine.Option(
names = ["--gitEngine"],
description =
[
"Git backend: 'jgit' (in-process, no git binary required) or 'subprocess' (shells out to --gitPath). Defaults to 'jgit'."],
defaultValue = "jgit")
var gitEngine: String = "jgit"

@CommandLine.Option(
names = ["--port"],
description = ["Port to listen on. Defaults to 8080."],
Expand Down Expand Up @@ -304,19 +293,10 @@ class ServeCommand : Callable<Int> {
}

/**
* Builds the [GitClient] for the configured [gitEngine]. Defaults to the in-process JGit engine;
* `subprocess` falls back to shelling out to [gitPath] (matching C-git behavior exactly, useful
* for workspaces relying on checkout filters/hooks JGit does not run).
* Builds the [GitClient]. Git fetch/checkout operations shell out to the `git` binary at
* [gitPath], so a `git` binary must be available on the host.
*/
fun createGitClient(): GitClient =
when (gitEngine.lowercase()) {
"jgit" -> JGitClient(workspacePath, gitPath)
"subprocess" -> ProcessGitClient(workspacePath, gitPath)
else ->
throw CommandLine.ParameterException(
spec.commandLine(),
"Unknown --gitEngine '$gitEngine' (expected 'jgit' or 'subprocess')")
}
fun createGitClient(): GitClient = ProcessGitClient(workspacePath, gitPath)

/**
* Wires the services, starts the HTTP server, and performs the initial git fetch + readiness
Expand All @@ -341,7 +321,7 @@ class ServeCommand : Callable<Int> {
MetricsService(
version = VersionProvider().version.firstOrNull() ?: "unknown",
startedAtMillis = System.currentTimeMillis(),
gitEngine = gitEngine,
gitEngine = "subprocess",
trackDeps = trackDeps,
cacheDir = cacheDir.toString(),
storage = storage,
Expand Down
177 changes: 0 additions & 177 deletions cli/src/main/kotlin/com/bazel_diff/server/JGitClient.kt

This file was deleted.

Loading
Loading