Documentation
¶
Overview ¶
Package lockfile provides a tiny, dependency-free advisory file lock scoped to a single named operation (e.g. "selfinstall"). It exists to prevent two `gitmap self-install` processes from racing each other — concurrent installs would otherwise re-prompt the user, double-write PATH entries, and overlap binary downloads in the same dir.
Design choices:
- PID-based, advisory: stale locks (process exited without cleanup) are auto-recovered on the next acquire by checking process liveness.
- Lives in os.TempDir(): works even before any gitmap data dir exists, so it can guard the *very first* install.
- Exported `Acquire`+`Release` keep the surface tiny; callers always pair them with `defer release()` and never touch the path directly.
Mirrors the established store/lock.go pattern but is exported so cmd/ can reuse it without importing the whole store package.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrAlreadyHeld = errors.New("lockfile: already held by another process")
ErrAlreadyHeld is returned by Acquire when a live process already holds the named lock. Callers check with errors.Is to distinguish it from filesystem errors.
Functions ¶
Types ¶
type Releaser ¶
type Releaser func()
Releaser is the cleanup callback returned by Acquire. Always defer it immediately after a successful Acquire.
func Acquire ¶
Acquire takes the named lock or returns ErrAlreadyHeld. The lock file is written under os.TempDir() as `gitmap-<name>.lock` and contains the holder's PID. If a lock file exists but its PID no longer maps to a live process, the stale file is removed and the lock is reacquired.
Returned Releaser is a no-op-safe func: it deletes the file and can be called multiple times.
func ForceAcquire ¶
ForceAcquire ignores any existing lock (stale or live) and writes a fresh one. Used by `--force-lock` to recover from a crashed installer that left the file behind but somehow evaded the PID liveness check (e.g. PID was recycled by the OS).