Bash Versioning and Distribution
Script versioning is the practice of stamping each release with a version number and a changelog entry. A clear version tells users exactly which behaviour they run.
A --version flag reports the release
The script checks its first argument for --version and prints its stamp. Any other run prints usage instead, so the flag is easy to tell apart.
cat > tool.sh <<'TOOLEOF'
VERSION="1.2.0"
if [[ "${1:-}" == "--version" ]]; then
echo "tool $VERSION"
exit 0
fi
echo "usage: tool <name>"
TOOLEOF
bash tool.sh --version
bash tool.shInstall means copy, make executable, and put on PATH
The script is copied into a bin directory, made executable, and that directory joins PATH. Running tool by name then prints its version, which proves the install worked.
mkdir bin
cat > tool.sh <<'TOOLEOF'
#!/usr/bin/env bash
VERSION="1.2.0"
if [[ "${1:-}" == "--version" ]]; then
echo "tool $VERSION"
exit 0
fi
echo "usage: tool <name>"
TOOLEOF
cp tool.sh bin/tool
chmod +x bin/tool
PATH="$PWD/bin:$PATH"
tool --versionThe changelog must hold the shipped version
The changelog lists one heading per release. Grepping for the version stamp finds its heading, which proves the shipped release has a changelog entry.
printf '## 1.2.0\n- Fixed a crash on empty input.\n## 1.1.0\n- First public release.\n' > CHANGELOG.md
VERSION="1.2.0"
grep "^## $VERSION" CHANGELOG.mdExample
cat > tool.sh <<'TOOLEOF'
#!/usr/bin/env bash
VERSION="2.0.0"
usage() {
echo "usage: tool [--version] [--help] <name>"
}
if [[ "${1:-}" == "--version" ]]; then
echo "tool $VERSION"
exit 0
fi
if [[ "${1:-}" == "--help" ]]; then
usage
exit 0
fi
if [[ -z "${1:-}" ]]; then
usage
exit 1
fi
echo "hello $1"
TOOLEOF
mkdir bin
cp tool.sh bin/tool
chmod +x bin/tool
PATH="$PWD/bin:$PATH"
tool --version
tool --help
tool AdaKey points
- --version: a flag that prints the program name and version, and nothing else.
- Semantic parts: major for breaking changes, minor for new features, and patch for fixes.
- Changelog: one entry per release, newest first, listing what changed.
- Shebang: #!/usr/bin/env bash finds bash through PATH instead of a fixed path.
- Install step: copy the script into a bin directory on PATH and make it executable.
- Version check: a release step should confirm the version stamp matches the changelog before it ships.
- No silent drift: never ship two files that claim different versions.
In this example, a tool script carries a version stamp, a usage function, and flags for version and help. The script is copied into a bin directory on PATH and made executable. The three runs prove the installed tool answers its version flag, its help flag, and a real name.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Why should a distributed script answer a --version flag?