Add git database locks and db_dir config#307
Conversation
48e81f8 to
b2b3116
Compare
Modeled on memora-rs's RAII flock pattern: introduces an `FsLock` guard in `src/lock.rs` backed by `fs4`, and takes a per-`(name, url)` exclusive lock under `<database>/git/locks/` around `git_database` and `checkout_git`. Locks released automatically on drop (and by the kernel on crash). `clone` and `snapshot` subcommands intentionally remain unguarded. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds an optional `db_dir` config field that overrides only the bare-repo and lock-file locations (`<db_dir>/git/db/` and `<db_dir>/git/locks/`), while working-tree checkouts and everything else continue to derive from `database`. This lets a single shared config enable cross-project cache sharing without forcing same-named projects to commit a `workspace.checkout_dir` in their `Bender.yml`. The field is purely additive and unknown to older Bender versions, which silently ignore it and fall back to their per-project default — strictly safer than today's shared-`database:` recipe in mixed-version setups. Docs updated: `book/src/configuration.md` documents the new field; `book/src/workflow/ci.md` rewrites the shared-cache recipe around `db_dir` and retires the now-fixed concurrent-runs caveat; `book/src/local.md` mentions it in the example block. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- src/progress.rs: collapse nested `if self.git_op == Submodule { ... }`
blocks into match guards on the relevant arms; the existing `_ => {}`
wildcard now handles the non-submodule case.
- src/config.rs: collapse the inner glob/non-glob `if` in `glob_file`
into a match guard; the pre-existing `_ => Ok(vec![self])` arm covers
the fall-through.
- Drop redundant `.into_iter()` on values passed to `.chain()`
in `src/sess.rs`, `src/src.rs`, and `src/config.rs`.
- tests/cli_regression.rs: pass an array directly to `Command::args`
instead of borrowing it.
`cargo clippy --all-targets -- -D warnings` is clean; `cargo test`
unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Honoured only when no configuration file sets `db_dir`; any `Bender.local`/`.bender.yml`/user/system config still wins. Empty strings are treated as unset. Lets a CI runner export the shared cache path once instead of maintaining a `Bender.local` next to every project. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fischeti
left a comment
There was a problem hiding this comment.
Nice addition! I definitely think sharing the database is the way to go. I have some optional comments, but otherwise LGTM.
| regex = "1.12.2" | ||
| log = "0.4" | ||
| env_logger = { version = "0.11", default-features = false, features = ["auto-color"] } | ||
| fs4 = "1.1" |
There was a problem hiding this comment.
The standard library also has locking capabilities since 1.89.0 (with the same API). Although this requires increasing the MSRV
There was a problem hiding this comment.
Nice catch, MSRV bump drags with it a few clippy changes, but I think it makes more sense to bump that and align.
|
|
||
| # Share only the bare git repos and lock files across projects, while | ||
| # keeping per-project checkouts under each project's own .bender/. | ||
| # Older Bender versions silently ignore this field. |
There was a problem hiding this comment.
maybe the exact version could be stated
|
|
||
| ### Legacy `database:` recipe | ||
|
|
||
| Earlier docs recommended sharing via [`database`](../configuration.md#database), which relocates both the bare repos *and* the checkouts: |
There was a problem hiding this comment.
I don't think we need to reference "earlier" docs that have not been released yet
|
|
||
| If you'd rather not place a `Bender.local` on the runner at all, exporting `BENDER_DB_DIR=/var/cache/bender_shared` in the job environment has the same effect — any project that explicitly sets `db_dir` in its own configuration overrides the env var. | ||
|
|
||
| > **Older Bender versions** silently ignore both `db_dir` and `BENDER_DB_DIR` and fall back to their normal per-project `.bender/` cache, so the shared config above is safe to deploy on a runner that still hosts pinned-to-old-bender projects — those projects simply won't benefit from the shared cache, but they won't misbehave either. |
There was a problem hiding this comment.
maybe the exact version could be stated
Rust 1.89 stabilized `File::lock`/`try_lock`/`unlock` and `std::fs::TryLockError` with semantics identical to what `fs4` was providing (same `flock`/`LockFileEx` backing, kernel-released on fd close). Drop the dependency and bump `rust-version` to 1.89.0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The MSRV bump to 1.89 makes let-chains (stabilized in 1.88) available,
so clippy's `collapsible_if` lint now suggests collapsing 20 nested
`if let { if cond { ... } }` (and three-deep variants) into single
let-chain expressions. Purely mechanical rewrite; behavior unchanged.
`cargo fmt` applied to reindent the affected blocks.
`cargo clippy --all-targets -- -D warnings` clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- State the exact version (0.32) instead of "older Bender versions" in configuration.md, local.md, and ci.md. - Drop the "earlier docs recommended..." framing in ci.md — the `database:`-sharing recipe was never released, so reference it neutrally as the alternative for "share working-tree checkouts too" rather than as a historical pattern. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
git_databaseandcheckout_gitin a cross-processflock(fs4) keyed per dependency, so concurrentbenderinvocations against the same dep serialize safely. Locks live at<database>/git/locks/and are released by the kernel on process exit.db_dirconfig field: new optional setting that overrides only the bare-repo and lock paths, leaving checkouts underdatabase. Lets a single sharedBender.localenable cross-project cache reuse without forcing per-projectworkspace.checkout_dir. Older bender versions silently ignore the field and fall back to per-project caches — safer than the legacydatabase:-only sharing recipe in mixed-version setups.collapsible_match, redundant.into_iter(),args(&[...])).cargo clippy --all-targets -- -D warningsnow passes.Docs updated:
configuration.md(newdb_direntry),workflow/ci.md(db_diris now the recommended sharing recipe; retires the concurrent-runs caveat),local.md,CHANGELOG.md.