Minimal, zero-dependency bash dependency manager. Declare URLs;
bashdep downloads them into lib/ and keeps installs idempotent via a
per-directory .bashdep.lock. No registry, no runtime — just curl
(or wget).
1. Vendor bashdep into your repo (pinned release, verified against
its published checksum — recommended for reproducibility):
mkdir -p lib
curl -fsSLo lib/bashdep https://github.com/Chemaclass/bashdep/releases/latest/download/bashdep
curl -fsSLo checksum https://github.com/Chemaclass/bashdep/releases/latest/download/checksum
( cd lib && shasum -a 256 -c ../checksum ) && chmod +x lib/bashdepPrefer the bleeding edge? Grab the main branch instead (unversioned,
no checksum):
curl -fsSLo lib/bashdep https://raw.githubusercontent.com/Chemaclass/bashdep/main/bashdep
chmod +x lib/bashdep2. Declare your dependencies in a .bashdep file (one URL per
line; # comments allowed; @dev suffix routes to lib/dev/;
optional #sha256=<hex> verifies the download):
https://github.com/TypedDevs/bashunit/releases/download/0.17.0/bashunit
https://github.com/Chemaclass/create-pr/releases/download/0.6/create-pr
https://github.com/Chemaclass/bash-dumper/releases/download/0.1/dumper.sh@dev
https://example.com/pinned.sh#sha256=e3b0c44298fc1c149afbf4c8996fb924...
3. Install:
./lib/bashdep installThat's it. The first run downloads everything and writes
.bashdep.lock. Re-runs skip already-installed deps; bumping a URL
version re-downloads only that entry. Commit .bashdep.lock to lock
versions across collaborators.
Everyday commands:
./lib/bashdep list # what's installed (path + source URL)
./lib/bashdep doctor # detect lockfile drift
./lib/bashdep clean --dry-run # preview orphan removal
./lib/bashdep --help # all commands and flagsEnable tab completion: source <(./lib/bashdep completion bash) (or zsh).
Prefer a programmatic setup (custom dirs, inline arrays)? Source bashdep and call the same functions:
#!/bin/bash
set -euo pipefail
source lib/bashdep
bashdep::install_from # reads ./.bashdepSee the API reference for bashdep::setup,
bashdep::install, and friends.
Every command returns a meaningful, capped-at-255 count, so it drops into CI as-is:
./lib/bashdep doctor || echo "lockfile drift: $? issue(s)" # 0 = clean
./lib/bashdep install || echo "$? download(s) failed"install returns the failure count, doctor the issue count, clean
the number of orphans it could not remove, and uninstall the count of
names not found. See Behavior.
- Idempotent installs via per-directory
.bashdep.lock. - Parallel downloads — dependencies fetch concurrently (tune with
BASHDEP_JOBS, default 4;BASHDEP_JOBS=1for sequential). - Optional integrity checks — pin a dependency with
#sha256=<hex>and bashdep verifies the download before recording it. - Dev/prod separation via the
@devURL suffix (lib/vslib/dev/). curlorwget— uses whichever is installed.- File-driven, array-driven, or CLI —
install_from,install, or./lib/bashdep <command>(withbash/zshtab completion). - Lifecycle commands —
list,uninstall,clean,doctor,self_update,completion. - Modes —
force,dry-run,silent,verbose.
- API reference — the CLI plus
install,install_from,setup,list,uninstall,clean,doctor,self_update,completion,version. - Behavior — lockfile rules, dev dependencies, checksum verification, parallel downloads, error handling.
- Releasing — how maintainers cut a new tagged
release with
release.sh. - Contributing — project layout, test conventions, coding guidelines.
make deps # Install bashunit (test runner)
make check # Full gate: test + ShellCheck + editorconfig
make test # Run the suite (BASHUNIT_FLAGS=--simple for quiet)
make sa # ShellCheck
make lint # editorconfig-checker
make pre_commit/installSee CONTRIBUTING for the full guide.