Skip to content

fix(script-owners): parse under macOS bash 3.2 so the restatement guard runs - #532

Closed
saingge wants to merge 1 commit into
MendixMau:masterfrom
saingge:fix/script-owners-bash32
Closed

saingge wants to merge 1 commit into
MendixMau:masterfrom
saingge:fix/script-owners-bash32

Conversation

@saingge

@saingge saingge commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Direct lane (changes to bin/, project-bin/)

What changed and why: project-bin/script-owners.sh did not parse under macOS's default /bin/bash (3.2.57). exec.sh calls it as bash …/script-owners.sh check … 2>/dev/null || true (project-bin/exec.sh:1139), so on a Mac where bash is /bin/bash the restatement guard (#498) printed nothing and warned about nothing, with no error. Two bash 3.2 scanner limits inside the OUT="$( … )" block caused it:

  1. An apostrophe in a comment (# rc 0: O's work …) opens a quote that never closes (bash -n fails: "unexpected EOF while looking for matching `''"). The comment now reads "the work of O".
  2. A case pattern without a leading ( ends the $( … ) early (case a in a) … fails at run time with "syntax error near unexpected token newline'"). bash -ndoes NOT catch this one. The four patterns in the block's twocase statements (not_live, revert) now use the POSIX form (pattern)`.

bin/check-scripts.sh now also runs /bin/bash -n when the bash on PATH is a different bash, so a Mac contributor with a newer bash first on PATH still sees the first kind of failure. CI (ubuntu) has only bash 5, so CI cannot catch either; the second kind is only caught by running the fixture under /bin/bash on a Mac.

Impact

Row Answer
Process none: no step, gate or artifact added or removed. The restatement guard that #498 already describes starts working on bash 3.2.
Dependencies project-bin/script-owners.sh (10 lines), bin/check-scripts.sh. Draft #311 also edits script-owners.sh (an earlier form of the same guard; #498 merged the guard); if #311 is revived it will conflict here. No new tools; the check-scripts change only reads /bin/bash, and is skipped when /bin/bash is the bash on PATH (Linux, Git Bash).
Context cost none: no routed or always-loaded file touched.
Behaviour n/a: scripts only.
Runtime check-scripts.sh parses each shell script a second time on a Mac that has a newer bash on PATH (bash -n, milliseconds per file). Nothing in exec.

Field evidence: exec.sh's guard call on macOS (Darwin 25.6.0), /bin/bash 3.2.57. Reproduced with a two-script project built from the fixture's captured mxcli DESCRIBE output (tests/wave2/fixtures/context-pack/capture/describe): the older script is replayed over the newer owner's write. Before: check prints nothing, rc=2 (stderr dropped as exec.sh does). After: REVERT MICROFLOW Sales.ACT_ApprovalStep_Reject mdlsource/09-reject-fix.mdl newer owner mdlsource/09-reject-fix.mdl — replaying this script reverts it, rc=1. No full app run; the evidence is the toolkit's own fixture.

  • No client data anywhere in the diff
  • Size cap: 3 files, 17 insertions / 7 deletions (CHANGELOG included)
  • Test tier reached: T0 + T1. T1 is tests/wave2/test-restatement-guard.sh under /bin/bash 3.2.57 (16 of 58 pass on origin/master, 58 of 58 here) and, for the same file, under bash 5.2.37/5.2.21 in containers (see Verification).
  • Instrument: golden input is the fixture's captured DESCRIBE files (unchanged); layouts unaffected (no path logic touched); platforms: the change is bash-version portability, /bin/bash guard is skipped where it is the same bash as PATH (Linux, Git Bash).
  • New skill: n/a
  • CHANGELOG.md line appended, credited
  • New bug entries: none

Verification

  • Cause, smallest repro under /bin/bash 3.2.57: x="$(echo hi / # O's work / echo there / )" → bash -n: "unexpected EOF while looking for matching ''"; same text with "Os" parses. Second repro: x="$(case a in a) echo ok ;; esac)"→bash -npasses, running it fails with "command substitution: line 1: syntax error near unexpected tokennewline'"; (a) instead of a) works.
  • /bin/bash -n project-bin/script-owners.sh: fails on origin/master 393d253 (line 290 / 295), passes after.
  • bash 5: bash -n project-bin/script-owners.sh passes in debian:stable-slim (5.2.37), python:3.12-slim (5.2.37) and ubuntu:24.04 (5.2.21).
  • bin/check-scripts.sh: "120/120 shell script(s) parse"; with the /bin/bash branch forced on over origin/master's script-owners.sh it reports "FAIL … does not parse under this bash (or /bin/bash)", with the fix 120/120.
  • /bin/bash tests/wave2/test-restatement-guard.sh <origin/master project-bin/exec.sh> → "== 16 passed, 42 failed"; on this branch → "== 58 passed, 0 failed".
  • Same fixture in ubuntu:24.04 (bash 5.2.21, no java): 44 passed, 14 failed; every failure is in the "exec.sh:" sections, which need java for the gate (origin/master fails the same sections there). The parser, order, check and ledger sections, which run script-owners.sh directly, pass.
  • bin/check-portability.sh on the two changed scripts: clean. bin/check-pr-discipline.sh origin/master: clean. bin/check-no-client-data.sh and LEAKGUARD_BASE=origin/master bin/check-no-client-data.sh: clean, no new capitalised words.
  • No open PR or issue fixes this: gh pr list --state all --search script-owners shows exec.sh: warn on stale-DESCRIBE and co-owned restatements; roll back an mxbuild crash on the written model #311 (draft), fix(exec): warn when replaying an older owning script reverts newer work (#269) #498 (merged, the guard), fix(exec): warn when a script restates from a stale DESCRIBE (#261) #503; none touches the bash 3.2 parse. Issue Restatement guard: mark the ledger on git pull/checkout of the model #504 is a different change to the ledger.

…rd runs; check-scripts also parses with /bin/bash
@MendixMau

Copy link
Copy Markdown
Owner

Thanks @saingge! Independent review: MERGE. We moved your commit unchanged, with your authorship, into #552, so CI runs without fork approval and we can handle CHANGELOG conflicts. This PR closes when #552 merges; the merge commit carries a Co-authored-by line for you.


Generated by Claude Code

MendixMau added a commit that referenced this pull request Oct 22, 2026
…rd runs (#552, from #532)

project-bin/script-owners.sh drops an apostrophe in a comment inside $(...) and uses (pat) case patterns so bash 3.2 parses it; bin/check-scripts.sh also parses with /bin/bash when that differs from the bash on PATH. Contributed by @saingge in #532.

Review: MERGE — correct bash 3.2 parse fix; check-scripts 120/120 on Linux. Security review: safe.

Co-authored-by: saingge <262679532+saingge@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
@MendixMau MendixMau closed this Oct 22, 2026
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.

2 participants