Repository navigation
Description
Problem
install.sh decides whether an argument is a version by matching X.Y.Z, latest or beta; anything else is a directory. A version typed with a v prefix, as release tags are often written, becomes a folder.
./install.sh v0.52.0Output: > Downloading the latest version: '0.52.0', > bashunit has been installed in the 'v0.52.0' folder, exit 0. A directory named v0.52.0 now holds the latest release, and no error was printed.
Where
install.sh:164-166:is_versionaccepts only^[0-9]+\.[0-9]+\.[0-9]+$,latestandbeta.install.sh:169-174: with one argument, a non-version is the directory.
Why it matters
A CI step pinning v0.51.0 silently installs the current release into a directory the job never looks at, and the next step fails on a missing binary or, worse, picks up an unpinned version from elsewhere on PATH.
Suggested change
Treat an argument that looks like a version with a prefix (v0.52.0, 0.52) as a version and either accept it (strip the v) or refuse it with Error: unknown version 'v0.52.0'; use 0.52.0, latest or beta. Keep the free-form directory for arguments that do not look like a version at all.
Acceptance criteria
-
./install.sh v0.52.0installs 0.52.0 intolib, or exits 1 naming the version; it never createsv0.52.0/. -
./install.sh lib v0.52.0behaves the same way. - A test covers it and fails on the current code.
Proposed fix
In install.sh, after is_version (install.sh:164-166), add looks_like_version that matches ^v?[0-9]+(\.[0-9]+){0,2}$ with the existing regex_match helper (the script already uses [[ =~ ]] there). In the argument parsing at :168-186, an argument that looks like a version but is not one accepted by is_version is an error, never a directory:
function looks_like_version() {
regex_match "$1" '^v?[0-9]+(\.[0-9]+){0,2}$'
}
# in the parse, before treating an argument as DIR:
if looks_like_version "$1"; then
echo "Error: unknown version '$1'. Use a release such as $LATEST_BASHUNIT_VERSION, 'latest' or 'beta'." >&2
exit 1
fiAlternatively strip a leading v and accept v0.52.0 as 0.52.0; the error is the smaller change and avoids guessing. Bash 3.0: [[ =~ ]] is already in the file through regex_match; keep the pattern free of quotes and backslashes so 3.0 and 3.2 read it the same. Public behaviour that must not change: ./install.sh lib, ./install.sh 0.52.0, ./install.sh lib 0.52.0, latest and beta. Docs: docs/installation.md:76 can say the version is written without a v; add a CHANGELOG line under Unreleased.
Agent brief
- Branch:
fix/1409-install-rejects-mistyped-versionfrom freshorigin/main. Commit:fix(install): refuse a version that is not a release instead of using it as a directorywithCloses #1409in the body. - Files:
install.sh,docs/installation.md,CHANGELOG.md. Test: extendtests/acceptance/install_test.sh, next totest_install_fails_loudly_on_unknown_version(install_test.sh:128). This case needs no network: the script must exit before downloading. - RED first:
function test_install_refuses_a_version_with_a_v_prefix() {
local output
local exit_code=0
output="$(./install.sh v0.52.0 2>&1)" || exit_code=$?
assert_equals "1" "$exit_code"
assert_contains "unknown version 'v0.52.0'" "$output"
assert_directory_not_exists "./v0.52.0"
}Run only that file: ./bashunit tests/acceptance/install_test.sh.
- Non-goals: do not touch the download or checksum code (install.sh removes the installed binary before downloading, so a failed download leaves nothing #1406), the
cd(install.sh resolves a relative directory against its own location instead of the current directory #1408) or the beta build. - Gate, once, when the change is complete:
./bashunit tests/,./bashunit --parallel --simple --strict tests/,make sa,make lint.make lintis the formatting authority; nevershfmt -w; 2-space indent. - Done when: every acceptance box is checked, the gate is green, CHANGELOG and docs are updated, and a PR is open with the
prskill.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
fix(install): reject mistyped versions