lockfile-committed (BTSTRUC007)¶
Added in 0.13.0 · Preview · Off by default (error)
Family: structure · Standard: CES-109 · Languages: all
This rule is unstable and in preview. It runs only with preview = true, and only when it is selected.
Directive¶
Each manifest that declares dependencies has the lockfile of one package manager, next to it or in
a folder above it (the root of its workspace), and the lockfile is committed. The rule runs once
for the whole project, on every botica lint, and reports at the manifest. An error by default.
| Manifest | Declares dependencies when | Lockfiles |
|---|---|---|
pyproject.toml |
it has a [project] table |
uv.lock, poetry.lock, pdm.lock, Pipfile.lock |
package.json |
dependencies, devDependencies or optionalDependencies is not empty |
pnpm-lock.yaml, package-lock.json, npm-shrinkwrap.json, yarn.lock, bun.lock, bun.lockb |
go.mod |
it has a require directive |
go.sum |
Cargo.toml |
it has a [package] or [workspace] table |
Cargo.lock |
It reports a manifest when:
- no folder from the manifest up to the root of the project holds a lockfile of its ecosystem;
- its folder holds the lockfiles of two package managers, such as
package-lock.jsonandpnpm-lock.yaml; - the
packageManagerof apackage.jsonnames a manager (pnpm@10.18.0) and the lockfile found is that of another.
A lockfile that .gitignore leaves out counts as missing, because the walk of botica honours it.
Why¶
Without a lockfile each install resolves the versions again, so CI and each machine can run
different code, and osv-scanner has no resolved set to check. Two lockfiles in one folder mean
two managers installed the project, such as npm install run in a repository of pnpm,
and the two sets of versions drift apart. A library commits its lockfile too: uv says that
uv.lock "should be checked into version control", and Cargo suggests committing Cargo.lock "as
a starting point".
Do¶
Don't¶
pyproject.toml # no uv.lock, or uv.lock in .gitignore
web/package.json
web/package-lock.json
web/pnpm-lock.yaml
Suppression¶
The rule is of project scope, and only the configuration of botica silences it: the manifest in
extend-ignores of [rules.lockfile-committed], or ignore = ["lockfile-committed"]. A comment
that names it is invalid-suppression.