Reproducible Builds — fobos.lock
The problem
Without a lock file, two developers running fobis fetch on the same fobos get different results if a dependency's default branch advanced between their fetches. The same fobos file is no longer a reproducible build recipe.
The solution: fobos.lock
After every successful fobis fetch, FoBiS writes fobos.lock next to the fobos file. It records the exact git HEAD commit SHA and a SHA-256 checksum of every fetched dependency:
# fobos.lock — auto-generated by FoBiS.py fetch — do not edit by hand
[PENF]
url = https://github.com/szaghi/PENF
commit = a1b2c3d4e5f6789012345678901234567890abcd
sha256 = deadbeefdeadbeef...
tag = v1.5.0
[stdlib]
url = https://github.com/fortran-lang/stdlib
commit = 9f8e7d6c5b4a3210fedcba9876543210fedcba98
sha256 = 0102030405060708...
semver = ^0.5
resolved = v0.5.3Commit the lock file
git add fobos.lock
git commit -m "chore: lock dependency versions"Committing fobos.lock guarantees that every checkout — CI, collaborators, release builds — uses the exact same dependency commits.
Frozen builds (--frozen)
The --frozen flag makes fobis fetch refuse to run without a lock file and pins every dependency to the commit recorded in fobos.lock instead of performing a live clone:
fobis fetch --frozen # abort if fobos.lock is missingUse --frozen in CI pipelines where the lock file is committed:
- name: Fetch dependencies (locked)
run: fobis fetch --frozenUpdating the lock file
# Re-fetch and update fobos.lock to latest commits
fobis fetch --update
# Commit the updated lock
git add fobos.lock && git commit -m "chore: update dependency locks"Semver version constraints
Instead of pinning to an exact tag=, you can declare a version constraint:
[dependencies]
PENF = https://github.com/szaghi/PENF :: semver=^1.5
stdlib = https://github.com/fortran-lang/stdlib :: semver=>=0.5,<1.0fobis fetch queries the remote tags and resolves the highest tag satisfying the constraint:
| Constraint | Meaning |
|---|---|
^1.5 | >=1.5.0, <2.0.0 (compatible release) |
^1.5.2 | >=1.5.2, <2.0.0 |
~1.5.2 | >=1.5.2, <1.6.0 (patch-level) |
>=1.0,<2.0 | explicit range |
=1.5.0 | exact version |
* | any version |
The resolved tag is written to fobos.lock under resolved. On subsequent non---update runs the locked resolved tag is used without re-querying the remote.
semver= cannot be combined with tag=, branch=, or rev= — they are mutually exclusive.
Lock verification
After cloning, FoBiS compares the current HEAD of each dependency against the lock file. A mismatch emits a warning (non-fatal):
Warning: dependency 'PENF' HEAD (a1b2c3d) does not match
fobos.lock (deadbeef). Run 'fobis fetch --update' to refresh.This typically means the dependency was updated outside of FoBiS (e.g. a manual git pull inside the dep directory).