fix(test): keep test-local.sh from silently dying on missing ~/.lucli/express#2796
fix(test): keep test-local.sh from silently dying on missing ~/.lucli/express#2796bpamiri wants to merge 1 commit into
Conversation
…/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>
There was a problem hiding this comment.
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 -1assigns exit status 1 to the pipeline (viapipefail) when~/.lucli/expressis absent —2>/dev/nullhides stderr but not the exit code. - The
|| trueinside the command substitution is the right idiom: bash'sset -edoes not exit when a command is the left-hand side of||, so the failing pipeline is suppressed before|| trueruns, and the substitution exits 0 with empty output. - A missing
~/.wheels/express(truly fresh install, beforewheels starthas run) also works:findexits 1,|| truefires,LUCEE_LIB="", and the downstream[ -n "$LUCEE_LIB" ]guard cleanly skips the JDBC pre-install. No silent abort. - The removal of
~/.lucli/expressas 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, scopetest— both valid percommitlint.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+pipefailchain. - 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
docslabel but this is a tooling/infrastructure fix. Purely cosmetic; worth switching to atoolingorfixlabel if one exists, but doesn't affect merge. tools/test-local.sh:21(pre-existing, not introduced here) still readsrun \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 — 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. SycophancyNone detected. A cites the exact shell semantics (find exit status surviving False positivesNone detected. I verified each claim against the diff:
Missed issuesNone detected. This is a bash tooling fix — cross-engine CFML concerns do not apply. The single commit is clean (type Verdict alignmentA's ConvergenceAligned. A's analysis is accurate, the approval is warranted, and I have no remaining disputes or missed-issue findings. Joint recommendation: approve and merge. |
Summary
tools/test-local.shsilently aborts withEXIT=1(no/tmp/wheels-test-server.logproduced) on every install whose~/.lucli/express/directory never existed — i.e. every install since the lucli→wheels rebrand window closed.set -euo pipefail(line 26) andfind ~/.wheels/express ~/.lucli/express -path "*/lib/ext" -type d 2>/dev/null | head -1(line 81).findexits non-zero whenever any path argument is missing;2>/dev/nullhides the stderr but not the exit status.pipefailpropagates it throughhead -1, the assignment tripsset -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…".~/.lucli/expressfallback (rename landed in 3.0; recent CLI releases extract Lucee Express to~/.wheels/express/only) and add|| truefor defense in depth so a truly fresh install (beforewheels starthas ever run) leavesLUCEE_LIBempty and the downstream[ -n "$LUCEE_LIB" ]guard skips the JDBC pre-install cleanly.Test plan
~/.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.find /missing /existing 2>/dev/null | head -1exits 1 underset -euo pipefail, killing the assignment viaset -e.bash tools/test-local.sh wheels.tests.specs.wheelstestruns end-to-end — server starts,/tmp/wheels-test-server.logproduced (~69 KiB), 137 specs across 38 suites pass in ~17s.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 000000because 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