Skip to content

fix(#4): stop build.sh when the engine version cannot be read - #11

Merged
robfrank merged 1 commit into
mainfrom
fix/4-build-sh-extract-version-swallowed
Oct 23, 2026
Merged

robfrank merged 1 commit into
mainfrom
fix/4-build-sh-extract-version-swallowed

Conversation

@robfrank

Copy link
Copy Markdown
Contributor

Closes #4

scripts/build.sh read the engine version for its integration-jar check as a prefix assignment: ARCADEDB_VERSION="$(python3 extract_version.py ...)" BUILD_VERSION=... python3 - << 'PY'. Bash ignores the exit status of a command substitution in a prefix assignment, so set -euo pipefail let a failing extract_version.py through, for example with no engine jar or with two engine versions. The script went on with an empty version and failed later with an unrelated message. The version is now read in its own assignment. A failure stops the build at that line, and the extractor's own Error: ... message is the last thing printed.

Test plan

  • tests/test_build_scripts.py::test_no_command_substitution_in_a_prefix_assignment scans scripts/*.sh. RED: on main it flags exactly build.sh:405. GREEN: it passes with this change.
  • test_scanner_tells_a_prefix_from_a_plain_assignment pins the scanner on 15 cases. Among them:
    • nested $(cd "$(dirname ...)" && pwd) and <(...) inside a substitution;
    • ; cmd and && cmd after an assignment;
    • backticks;
    • local/export/readonly substitutions.
  • Full suite on darwin/arm64: 1062 passed.
  • bash -n scripts/build.sh and pre-commit pass.

Coverage

Invariant: in the build scripts, a failing command substitution stops the build under set -e.

The callers of the version extractor, found with grep -nE 'extract_version\.py|write_version\.py' scripts/*.sh:

  • build-native.sh:311, PYTHON_VERSION=$(...): a plain assignment, so it was already stopped by set -e.
  • build-native.sh:330, write_version.py: a plain command.
  • build.sh:405: fixed here.

The workflows' ARCADEDB_TAG=$(python3 scripts/extract_version.py ...) lines are plain assignments in a bash -e step, so they were already safe.

For other lines of the same shape, the test scans every scripts/*.sh for:

  • prefix assignments holding $(...) or backticks, and
  • local, export, readonly and declare assignments holding a substitution.

After the fix it finds none.

Known gaps: None in the scripts. The scanner reads one line at a time, so a substitution split across lines or built with eval would not be seen; the test's docstring says so.

Adversarial pass

I ran one independent review. It confirmed that the fix holds and runs in CI (both workflows pass a jars dir, which sets JAR_LIB_DIR), and found these scanner gaps:

  1. False positive on V="$(a)"; cmd. Fixed: an unquoted ;, & or | now ends the word.
  2. local/export/readonly V=$(cmd) and backticks not caught. Fixed: both are flagged now. None appear in the scripts today.
  3. Multi-line, eval and heredoc forms. Documented in the test's docstring as out of scope; none are used in the scripts.
  4. read_text() without an encoding fails on Windows outside UTF-8 mode. Fixed: it now reads with encoding="utf-8".
  5. The bash-semantics test could pick up WSL's bash.exe on Windows. Fixed by dropping that test; it tested bash itself, not our scripts.

Review cycles

This repository has no Claude review workflow, so no bot review was waited for. Final state: no-reviewer.

🤖 Generated with Claude Code

The jar check read the version as a prefix assignment
(VAR="$(extract_version.py ...)" python3 - ...), whose substitution status
set -e ignores, so a failing extract_version.py went on with an empty
version. It is now its own assignment. tests/test_build_scripts.py scans
the build scripts for that pattern and for local/export/readonly/declare
substitutions, which hide the status the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@robfrank
robfrank merged commit 05c0590 into main Oct 23, 2026
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build.sh: extract_version failure at line 405 is swallowed, fails later with a misleading message

1 participant