Skip to content

fix(test): keep test-local.sh from silently dying on missing ~/.lucli/express#2796

Open
bpamiri wants to merge 1 commit into
developfrom
claude/zealous-edison-35742b
Open

fix(test): keep test-local.sh from silently dying on missing ~/.lucli/express#2796
bpamiri wants to merge 1 commit into
developfrom
claude/zealous-edison-35742b

Conversation

@bpamiri
Copy link
Copy Markdown
Collaborator

@bpamiri bpamiri commented May 22, 2026

Summary

  • tools/test-local.sh silently aborts with EXIT=1 (no /tmp/wheels-test-server.log produced) on every install whose ~/.lucli/express/ directory never existed — i.e. every install since the lucli→wheels rebrand window closed.
  • Root cause is the interaction between set -euo pipefail (line 26) and find ~/.wheels/express ~/.lucli/express -path "*/lib/ext" -type d 2>/dev/null | head -1 (line 81). find exits non-zero whenever any path argument is missing; 2>/dev/null hides the stderr but not the exit status. pipefail propagates it through head -1, the assignment trips set -e, the cleanup trap fires with nothing to clean up, and the user sees the script just stop after "Starting Wheels CLI server on port 8080…".
  • Drop the now-dead ~/.lucli/express fallback (rename landed in 3.0; recent CLI releases extract Lucee Express to ~/.wheels/express/ only) and add || true for defense in depth so a truly fresh install (before wheels start has ever run) leaves LUCEE_LIB empty and the downstream [ -n "$LUCEE_LIB" ] guard skips the JDBC pre-install cleanly.

Test plan

  • Reproduced the silent fail locally on a system with only ~/.wheels/express/ and no ~/.lucli/express/ (post-rename setup): script exits 1 after "Starting Wheels CLI server on port 8080…" with no /tmp/wheels-test-server.log.
  • Confirmed find /missing /existing 2>/dev/null | head -1 exits 1 under set -euo pipefail, killing the assignment via set -e.
  • After fix: bash tools/test-local.sh wheels.tests.specs.wheelstest runs end-to-end — server starts, /tmp/wheels-test-server.log produced (~69 KiB), 137 specs across 38 suites pass in ~17s.
  • CI green across the compat matrix.

Follow-up (not in this PR)

While verifying, noticed a separate pre-existing bug: even after the tests pass, the script exits 1 with Tests returned HTTP 000000 because the --write-out "%{http_code}" capture (lines 129–132) appears to come back empty (likely a curl-output / response-handling quirk against the long-running test endpoint). This was previously masked by the silent-fail blocking the script from ever reaching the HTTP check. Out of scope here; will look at separately.

🤖 Generated with Claude Code

…/express

Under `set -euo pipefail`, `find ~/.wheels/express ~/.lucli/express ...`
exits non-zero whenever any path arg is missing (stderr suppressed via
`2>/dev/null`, but the exit status survives), `pipefail` propagates it
through `head -1`, and the command-substitution assignment trips `set -e`.
The cleanup trap then fires with no server to clean up, so the user sees
"Starting Wheels CLI server on port 8080..." with EXIT=1 and no
`/tmp/wheels-test-server.log` produced — broken for every install since
the lucli→wheels rebrand window closed and `~/.lucli/express/` stopped
being created.

Drop the now-dead `~/.lucli/express` fallback (the rename landed in 3.0
and recent CLI releases extract Lucee Express to `~/.wheels/express/`
only) and add `|| true` for defense in depth so a truly fresh install
(before `wheels start` has ever run) leaves `LUCEE_LIB` empty and the
downstream `[ -n "\$LUCEE_LIB" ]` guard skips the JDBC pre-install
cleanly.

Verified: `bash tools/test-local.sh wheels.tests.specs.wheelstest` now
runs the server, produces `/tmp/wheels-test-server.log`, and passes all
137 specs across 38 suites in ~17s.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
@github-actions github-actions Bot added the docs label May 22, 2026
Copy link
Copy Markdown
Contributor

@wheels-bot wheels-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wheels Bot — Reviewer A

TL;DR: This PR correctly fixes a silent set -e death in tools/test-local.sh that has been breaking local test runs for every developer who installed the CLI after the lucli → wheels rebrand (i.e., anyone whose ~/.lucli/express/ never existed). The root-cause analysis is accurate, the fix is minimal and technically sound, the CHANGELOG entry is thorough, and the commit carries a DCO sign-off. Verdict: approve.


Correctness

The fix is correct. The failure mode is real and the shell semantics are accurately diagnosed:

  • Under set -euo pipefail, find ~/.wheels/express ~/.lucli/express ... 2>/dev/null | head -1 assigns exit status 1 to the pipeline (via pipefail) when ~/.lucli/express is absent — 2>/dev/null hides stderr but not the exit code.
  • The || true inside the command substitution is the right idiom: bash's set -e does not exit when a command is the left-hand side of ||, so the failing pipeline is suppressed before || true runs, and the substitution exits 0 with empty output.
  • A missing ~/.wheels/express (truly fresh install, before wheels start has run) also works: find exits 1, || true fires, LUCEE_LIB="", and the downstream [ -n "$LUCEE_LIB" ] guard cleanly skips the JDBC pre-install. No silent abort.
  • The removal of ~/.lucli/express as a search path is correct; per the PR body and CLAUDE.md, the rename landed in Wheels 3.0 and recent CLI releases only write to ~/.wheels/express/.

The follow-up bug mentioned in the PR body (HTTP 000 on the curl result capture) is pre-existing and appropriately out of scope.

Commits

Single commit fix(test): keep test-local.sh from silently dying on missing ~/.lucli/express (74 chars):

  • Type fix, scope test — both valid per commitlint.config.js.
  • Subject is under 100 chars, not ALL-CAPS.
  • Commit body explains the why (not just the what), including the exact set -euo pipefail + find + pipefail chain.
  • DCO sign-off present: Signed-off-by: Peter Amiri <peter@alurium.com>.

Docs

CHANGELOG [Unreleased] entry present and detailed — covers root cause, observable symptom, and the defense-in-depth rationale. No .ai/wheels/ doc updates needed (this is bash tooling, not framework behavior).


Nits (non-blocking):

  • The PR carries the docs label but this is a tooling/infrastructure fix. Purely cosmetic; worth switching to a tooling or fix label if one exists, but doesn't affect merge.
  • tools/test-local.sh:21 (pre-existing, not introduced here) still reads run \wheels browser:install`— CLAUDE.md documents the canonical form aswheels browser setup`. Out of scope for this PR; just flagging for a follow-up.

@wheels-bot
Copy link
Copy Markdown
Contributor

wheels-bot Bot commented May 22, 2026

Wheels Bot — Reviewer B (round 1)

A's review checks out. The technical analysis is accurate, the approval is backed by concrete evidence, and I found no sycophancy, false positives, or missed issues on a re-scan of the diff.

Sycophancy

None detected. A cites the exact shell semantics (find exit status surviving pipefail through head -1, tripping set -e on the assignment) rather than issuing a blanket LGTM.

False positives

None detected. I verified each claim against the diff:

  • The set -euo pipefail + find + pipefail failure chain is correctly described.
  • The || true idiom inside the command substitution is correctly explained: find ... | head -1 is the left-hand side of ||; when it exits non-zero (pipefail propagates find's failure even though head exits 0), bash evaluates true, the compound command exits 0, and the substitution carries empty output without triggering set -e on the assignment.
  • The fresh-install path (no ~/.wheels/express/ yet) is traced correctly: find exits 1, || true fires, LUCEE_LIB="", downstream [ -n "$LUCEE_LIB" ] guard skips the JDBC step.
  • DCO sign-off confirmed in the commit: Signed-off-by: Peter Amiri <peter@alurium.com>.
  • CHANGELOG [Unreleased] entry confirmed in the diff.
  • The wheels browser:install nit (line 21 of test-local.sh) is confirmed pre-existing and not introduced by this PR.

Missed issues

None detected. This is a bash tooling fix — cross-engine CFML concerns do not apply. The single commit is clean (type fix, scope test, subject 74 chars, DCO present). No framework behavior changed; no .ai/wheels/ doc updates needed.

Verdict alignment

A's approve verdict is consistent with the findings: minimal, correct fix, clean commit, CHANGELOG updated, no outstanding blocking concerns.

Convergence

Aligned. A's analysis is accurate, the approval is warranted, and I have no remaining disputes or missed-issue findings. Joint recommendation: approve and merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant