cli

Adapter commands

Adapter commands are the preferred path for tools that already speak a remote-cache protocol.

Use them when you want BoringCache to:

Supported adapter commands today:

Common commands

# Archive mode (run/save/restore)
boringcache run -- bundle install

# Docker adapter from repo config
boringcache docker

# Same adapter without repo config
boringcache docker --tag docker-cache -- docker buildx build .

# Direct BuildKit adapter
boringcache buildkit --tag docker-cache -- buildctl build --frontend dockerfile.v0

# Long-lived local proxy
boringcache cache-registry my-org/app registry-cache --port 5000

Archive mode commands (run, save, and restore) are for explicit directory caches. Adapter commands are for supported remote-cache tools. Use cache-registry when the repo already has a checked-in local endpoint setup or another process should keep the proxy alive. When .boringcache.toml stores the Docker command, boringcache docker is the short form. Use the longer version when you want to pass the Docker command inline. Proxy-backed adapter commands start in warm mode by default. Use --on-demand when a proxy-backed command should skip startup warming and serve colder first reads.

The product split is:

Repo config

Put repeated adapter setup in .boringcache.toml:

workspace = "my-org/my-project"

[adapters.docker]
tag = "docker-cache"
command = ["docker", "buildx", "build", "."]

Then:

boringcache docker

Useful adapter fields:

Session hints

Proxy-backed CLI flows can label sessions directly. This is the non-GitHub path for grouping dashboard sessions and misses by stable labels instead of anonymous traffic.

Use CLI flags when you want one-off labels:

boringcache run --proxy bazel-main \
  --metadata-hint project=web \
  --metadata-hint tool=bazel \
  --metadata-hint lane=ci \
  -- bazel build //...

Use repo config when the labels are part of the normal adapter contract:

[proxy]
metadata-hints = ["project=web"]

[adapters.turbo]
tag = "turbo-main"
command = ["pnpm", "turbo", "run", "build"]
metadata-hints = ["tool=turborepo", "lane=ci"]

Use BORINGCACHE_PROXY_METADATA_HINTS when another script or service starts cache-registry and you do not want to repeat --metadata-hint flags:

export BORINGCACHE_PROXY_METADATA_HINTS=project=web,tool=gradle,lane=ci
boringcache cache-registry my-org/my-project gradle-main --port 5000

Keep these hints low-cardinality and replayable. Good values are project=web, benchmark=grpc-bazel, tool=gradle, lane=ci, and workflow=build. Avoid commit SHAs, run ids, timestamps, and other per-run values. Normal sessions do not need cold or warm labels; BoringCache derives new-vs-recurring misses from cache target and lifecycle telemetry. The normal precedence is repo config first, then BORINGCACHE_PROXY_METADATA_HINTS, then explicit CLI flags. Use the same kebab-case spellings in .boringcache.toml that you see in CLI flags and docs; the config reader accepts both kebab-case and snake_case for adapter proxy fields.

command is repo config, not a general templating system. For proxy-backed commands, BoringCache only substitutes these placeholders inside command arguments:

Example:

[adapters.bazel]
tag = "bazel-cache"
command = ["bazel", "build", "--remote_cache={ENDPOINT}", "//..."]

What gets wired automatically

These adapters inject the tool-specific settings for you:

For Bazel, the adapter injects the remote-cache flags directly. For BuildKit, the adapter injects --import-cache and --export-cache for buildctl build. For Gradle, the adapter adds --build-cache plus a generated init script that points the remote cache at the local proxy. For Maven, the adapter injects the maven.build.cache.* remote endpoint properties, but the Maven build cache extension still needs to be present in the repo. For sccache, the adapter injects RUSTC_WRAPPER, SCCACHE_WEBDAV_ENDPOINT, SCCACHE_WEBDAV_KEY_PREFIX, and CARGO_INCREMENTAL=0 when the caller has not set it, then prints a best-effort sccache --show-stats summary and records normalized native tool evidence after the wrapped command. Leave sccache-key-prefix unset unless you need a stable WebDAV sub-root within the proxy cache.

If a repo already has a stable checked-in cache config, that still works. Explicit tool flags and checked-in config stay user-owned.

CLI overrides

Adapter commands accept direct overrides when you need them:

boringcache turbo \
  --workspace my-org/my-project \
  --tag turbo-cache \
  -- pnpm turbo run build

Useful flags:

Docker and BuildKit also support:

Override precedence:

Input kind Rule
Scalars CLI value wins when provided
Lists CLI list replaces repo config
Metadata hints repo config and CLI merge; CLI wins on duplicate keys

For Docker and BuildKit, --tag is the cache tag all the way through: the proxy session, BuildKit registry ref, backend cache entry, and human-visible tag all use the resolved human tag. The CLI still applies the shared branch/default/PR restore ordering, but it expresses those candidates as human tags rather than Docker-specific ref aliases. The direct buildkit adapter uses the same OCI plan as Docker, but injects buildctl build flags as --import-cache and --export-cache.

So the common Docker command can stay short:

boringcache docker \
  --workspace my-org/my-project \
  --tag docker-cache \
  -- docker buildx build .

Use Tool guides for per-tool examples and local endpoint setup.