Repository navigation
Conversation
) The top-level `wheels --help` summary advertised `wheels upgrade` as "Upgrade the Wheels framework version in your project," and the misleading phrasing implied flags (`--to`, `--dry-run`) that the runtime dispatcher never honoured. Running `wheels upgrade --dry-run` or `wheels upgrade --to=4.0.0` landed on a terse `Usage: wheels upgrade check [...]` line with no further explanation. Realign every public-facing description with the read-only scanner that the command actually is: showHelp() summary, the upgrade() docblock hint, and the function's own usage block. The new usage block enumerates the supported `--to=<version>` flag, calls out that `--dry-run` is not supported (and never was), and points users at `brew upgrade wheels` / `scoop update wheels` for the actual install. When the user passes `--dry-run` or `--to=` without `check`, the usage block also appends a `Did you mean: wheels upgrade check ...` nudge. Add a source-level regression at vendor/wheels/tests/specs/cli/UpgradeCommandHelpSpec.cfc that asserts the three description sites stay in sync. Fixes #2629 Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
…k subcommand Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Wheels Bot — Docs updatedAdded a doc commit to this PR:
The dedicated |
There was a problem hiding this comment.
Wheels Bot - Reviewer A
TL;DR: PR 2642 correctly aligns the wheels upgrade help surface with scanner-only reality. The Module.cfc changes are accurate, the CHANGELOG.md entry is thorough, and six of the seven new regression specs provide solid coverage. The seventh spec contains two correctness bugs making it pass vacuously. Verdict: comment -- implementation is shippable; spec needs one fix.
CORRECTNESS
Bug 1 - UpgradeCommandHelpSpec.cfc line 104: no-match guard is always true
When reFindNoCase finds no match with returnSubExpressions=true, CFML returns a struct whose match array always has exactly one element (empty string). arrayLen(hintMatch.match) > 0 is therefore permanently true regardless of whether a match was found.
The guards on lines 104 and 108 should both use hintMatch.pos[1] > 0 instead -- position 0 is the canonical CFML no-match sentinel. The current guard always enters the if-block even when no hint line was found, so hintLine is set to empty string.
Bug 2 - UpgradeCommandHelpSpec.cfc lines 97-102: lookahead regex fails on the expanded multi-line docblock
The lookahead requires only whitespace between the hint line and the closing */. The prior one-liner docblock satisfied this. But this PR expands the docblock to 14 lines with comment paragraphs containing asterisk characters that are not whitespace. The regex returns no match on the current source.
Combined effect: hintLine is always set to empty string. reFindNoCase of the bad phrase against an empty string returns 0, so toBeFalse() trivially passes. The spec provides no protection against restoring the old hint wording.
Recommended fix: drop the lookahead, use findNoCase and mid to extract the hint line:
var hintStart = findNoCase("hint:", source);
expect(hintStart > 0).toBeTrue("Could not find hint: in Module.cfc.");
if (hintStart > 0) {
var hintEnd = find(chr(10), source, hintStart);
var hintLen = (hintEnd > hintStart ? hintEnd - hintStart : len(source));
var hintLine = mid(source, hintStart, hintLen);
expect(reFindNoCase("upgrade.*framework", hintLine) > 0).toBeFalse(...);
}
TESTS
The other six it() blocks are well-constructed: negative assertion for old upgrade summary, positive assertion for scanner phrasing, check-subcommand mention, brew-upgrade pointer, --dry-run not-supported note, and file-reachability check. All six provide meaningful protection. Only the seventh is broken.
CONVENTIONS
No issues -- no mixed positional/named arg styles, no query-vs-array confusion. Help-text-only change.
COMMITS
fix(cli): align wheels upgrade help with the scanner-only reality (#2629) -- valid type, scope, subject under 100 chars, not ALL-CAPS. Clean.
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: The new commit (f12dcd1b7) adds a clean and correct docs fix — both v4-0-0 and v4-0-1-snapshot release-channels.mdx now show the required wheels upgrade check --to=<version> form. However, the two correctness bugs in UpgradeCommandHelpSpec.cfc that were identified in the previous review (SHA 6d4d0f771) remain entirely unaddressed: the spec's 7th it block still passes vacuously because the lookahead regex cannot match through the expanded multi-line docblock, leaving the hint-line assertion without any real enforcement. The implementation itself (cli/lucli/Module.cfc) is correct and the first six specs provide solid coverage.
Correctness
Bug 1 (unchanged) — UpgradeCommandHelpSpec.cfc line 98: lookahead regex cannot match through the expanded docblock
var hintMatch = reFindNoCase(
"hint:\s*[^\r\n]*(?=\s*\*/\s*public\s+string\s+function\s+upgrade)",
source,
1,
true
);The lookahead (?=\s*\*/\s*public\s+string\s+function\s+upgrade) requires that only \s* (whitespace characters) separate the end of the hint line from the closing */. The current docblock contains 14 lines of non-whitespace text between the hint line and */ — asterisks, backticks, letters, and other non-whitespace characters. \s* cannot skip over those characters, so the regex returns no match.
Bug 2 (unchanged) — UpgradeCommandHelpSpec.cfc line 104: guard is permanently true on no-match
expect(arrayLen(hintMatch.match) > 0).toBeTrue(...)When reFindNoCase finds no match with returnSubExpressions=true, CFML returns a struct whose .match array always contains exactly one element — an empty string. So arrayLen(hintMatch.match) > 0 is permanently true regardless of whether a match was found, and the toBeTrue() assertion passes vacuously.
Combined effect: hintLine is set to "". reFindNoCase("\bupgrade\s+the\s+wheels\s+framework\b", "") returns 0, so toBeFalse() passes trivially. The spec provides no real protection against reverting the hint to the old upgrader phrasing.
Recommended fix (same as previous review): drop the lookahead entirely and use positional string functions to extract the hint line:
var hintStart = findNoCase("hint:", source);
expect(hintStart > 0).toBeTrue("Could not find hint: in Module.cfc.");
if (hintStart > 0) {
var hintEnd = find(chr(10), source, hintStart);
var hintLen = (hintEnd > hintStart ? hintEnd - hintStart : len(source));
var hintLine = mid(source, hintStart, hintLen);
expect(reFindNoCase("\bupgrade\s+the\s+wheels\s+framework\b", hintLine) > 0).toBeFalse(
"upgrade() hint still promises to `upgrade the Wheels framework`. "
& "It's a scanner — phrase the hint as `Scan ...` or `Check ...`."
);
}This extracts exactly the hint line, the guard on hintStart > 0 is a real sentinel, and the negative assertion exercises the actual hint text.
Docs
The new commit's two release-channels.mdx fixes are correct and complete. No other v4 doc copies remain with the old wheels upgrade --to=<version> form (verified via grep across the guides tree). The upgrade.mdx command reference pages were already using the correct wheels upgrade check form prior to this PR.
Commits
fix(cli): align wheels upgrade help with the scanner-only reality (#2629)— valid type, scope, subject under 100 chars, not ALL-CAPS. Clean.docs(web/guides): fix wheels upgrade example to include required check subcommand— valid type, scope, subject under 100 chars, not ALL-CAPS. Clean.
Tests
The six non-broken specs (showHelp negative, showHelp scanner positive, check subcommand mention, brew upgrade pointer, --dry-run not-supported note, file-reachability) all provide meaningful protection. Only the 7th spec needs the fix described above.
Wheels Bot — Reviewer B (round 1)A's two bug findings are accurate and well-reasoned. The implementation in SycophancyNone detected. A did not approve despite the broken spec. False positivesNone detected. I re-verified both claims against the source: Bug 1 — line 104 guard always true. Confirmed. Bug 2 — lookahead fails on the expanded docblock. Confirmed. The new docblock is 14 lines with body lines like Combined, the 7th spec provides zero regression protection on the hint wording — exactly as A described. Missed issuesOne minor precision gap in A's suggested fix: No other missed issues. The docs commits ( Verdict alignmentA's "comment" (implementation shippable, spec needs one fix) is consistent with the findings. A single broken spec that passes vacuously warrants requesting the fix; calling it a "comment" rather than "request-changes" is a mild undersell, but the intent is clear and actionable. ConvergenceAligned. The implementation is correct and the spec needs the 7th |
- vendor/wheels/tests/specs/cli/UpgradeCommandHelpSpec.cfc: rewrite the 7th `it()` block so the hint-line assertion no longer passes vacuously. The previous version had two bugs both reviewers agreed on: (1) the lookahead `(?=\s*\*/...)` could not span the expanded docblock body (`\s` doesn't match `*`), and (2) `arrayLen(hintMatch.match) > 0` is permanently true because CFML returns `match: [""]` on no-match. The fix anchors on `public string function upgrade(` first, then walks forward through `hint:` occurrences to capture the most recent one before the function declaration — addressing B's caveat that a naive first-`hint:` search would target the wrong function. Uses 3-arg `mid()` and `find(chr(10), ...)` for cross-engine safety. Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Wheels Bot — Address Review (round 1)Applied consensus findings from Reviewer A and Reviewer B's convergence (round 1):
Both root-cause bugs are fixed:
Tests not re-run locally — this environment doesn't have the The new commit will trigger a fresh Reviewer A run on the updated SHA. Convergence loop continues until reviewers align on |
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: This PR aligns the wheels upgrade help surface with the command's actual read-only scanner behavior. Three commits address the original misleading summary, expand the usage block, fix the docs, and — as of the latest commit (d5215b259) — correct the two vacuous-spec bugs identified in previous review rounds. The implementation was correct from the start; the spec is now genuinely non-vacuous; all three commits carry DCO sign-offs and pass commitlint. Verdict: approve (submitted as comment — self-review not permitted by GitHub).
Correctness
Previous bugs (now fixed) in UpgradeCommandHelpSpec.cfc 7th it() block
Both bugs raised in the prior two review rounds are resolved by d5215b259:
Bug 1 — permanently-true guard: the old arrayLen(hintMatch.match) > 0 check was always true because CFML's reFindNoCase with returnSubExpressions=true always returns a one-element .match array on no-match. Replaced with hintStart > 0, which is a real sentinel (0 = not found). Verified.
Bug 2 — lookahead could not span the multi-line docblock: the old regex (?=\s*\*/...) used \s which cannot match the leading * on each comment line of the expanded docblock. Replaced with a findNoCase() forward-walk that iterates every hint: occurrence in the source and keeps the last one before public string function upgrade(. The extracted hintLine is then checked with the negative regex assertion.
Verified against the live file: hint: at line 2355 (upgrade's docblock) is correctly the last occurrence before the function declaration at line 2369. The extracted line is hint: Scan your app for breaking changes before upgrading Wheels (read-only), which does not match \bupgrade\s+the\s+wheels\s+framework\b — so the negative assertion passes for the right reason.
Tests
The six previously-correct specs (negative assertion for old summary, positive scanner phrasing, check subcommand mention, brew upgrade wheels pointer, --dry-run not supported note, file-reachability) remain intact.
The 7th spec now provides genuine protection: reverting the hint text to the old upgrade the Wheels framework wording would cause reFindNoCase to return a positive match, flipping the toBeFalse() assertion to a real failure.
Cross-engine correctness of the new spec code:
findNoCase()(2- and 3-arg forms) — cross-engine safefind(chr(10), source, start)— cross-engine safe- 3-arg
mid(source, start, len)— cross-engine safe (the 2-arg form would fail Lucee 7; this is the correct form per cross-engine compatibility guide) - No
struct.map(), noclientscope, noapplicationscope members, no bracket-notation calls
Conventions
No issues. The help-text-only change in Module.cfc does not touch model associations, validations, view helpers, or route declarations.
Docs
Both release-channels.mdx copies (v4-0-0 and v4-0-1-snapshot) are corrected from the old wheels upgrade --to=<version> example to the required wheels upgrade check --to=<version> form.
Commits
All three commits carry Signed-off-by: claude[bot] DCO trailers and pass commitlint:
fix(cli): align wheels upgrade help with the scanner-only reality (#2629)— valid type, subject under 100 chars, not ALL-CAPSdocs(web/guides): fix wheels upgrade example to include required check subcommand— valid type, subject under 100 charsfix(test): address Reviewer A/B consensus findings (round 1)— valid type, subject under 100 chars
Wheels Bot — Reviewer B (round 2)A's review on the updated SHA is accurate. All findings from round 1 were addressed correctly in SycophancyNone detected. A's approval is supported by concrete evidence: line-number verification of the hint and function positions (2355 and 2369), walkthrough of the forward-walk algorithm, confirmation that the negative assertion is no longer vacuous, and per-call cross-engine safety analysis. False positivesNone detected. I independently verified every claim A made:
Missed issuesNone. The round-1 B caveat (bare Verdict alignmentFully aligned. A's approve verdict is correct given the implementation quality and the now-robust spec. ConvergenceAll prior concerns from rounds 1 and 2 are resolved. The implementation is correct, the spec is no longer vacuous, cross-engine idioms are used throughout, and the docs are updated. Converging on approve. |
…es-to-and-dry-run-flag Bring in latest develop (5 commits including PR #2624's blog visual baseline refresh) so the visual regression check picks up the current baseline. The PR's branch was created before #2624 landed, leaving GitHub's pull/2642/merge ref combining stale PR-side baseline with old develop — the test diffed against the pre-Maturity-Gap-post baseline and failed with 37,668 pixels of drift on the blog index. CHANGELOG.md conflict resolved by keeping both sets of `Fixed` entries — develop's #2630, #2635, #2621 plus this PR's #2629 — and develop's new `Documentation` section for #2627. cli/lucli/Module.cfc auto-merged: PR #2629's upgrade() help-text changes are in a different region than #2624's --no-sqlite scaffolding logic, so both sets of edits coexist cleanly. Signed-off-by: Peter Amiri <peter@alurium.com>
Visual regression fix — merged developThe Visual regression check was failing with 37,668 pixels of drift on the blog index. Reviewers A and B had already converged on Root cause: PR #2624 (commit Fix: Merged latest
GitHub's new Why not just re-run the Visual regression workflow? GitHub Actions pins re-runs to the original commit SHA, which still pointed at the stale merge ref. Pushing was the only way to force a fresh merge ref against current develop. The broader auto-refresh-race fix lives on |
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: The new head commit (85549c3c2) is a mechanical merge of develop into the PR branch, performed to update the visual regression baseline for the Maturity Gap blog post. The merge conflict in CHANGELOG.md is resolved correctly, cli/lucli/Module.cfc auto-merged cleanly, and no PR-specific code has changed since Review 3's approval (d5215b259). Verdict: approve (submitted as comment — self-review not permitted by GitHub).
Correctness
The merge resolution is correct on all conflict-prone files:
CHANGELOG.md: The ### Fixed section now contains both develop's entries (#2630, #2635, #2621) and this PR's entry (#2629). The new ### Changed (#2632) and ### Documentation (#2627) sections from develop are present. No entry was dropped or duplicated.
cli/lucli/Module.cfc: The diff between d5215b259 and 85549c3c2 adds only the buildSQLiteDatasourcesBlock() helper and the datasourcesBlock context variable from PR #2621 (scaffolding region around lines 4155–4382). The upgrade() function (lines 2369–2416) and the showHelp() summary line (line 221) are byte-identical to the d5215b259 state.
UpgradeCommandHelpSpec.cfc: No changes in the merge commit. The spec remains the corrected version from d5215b259 — the 7th it() block correctly anchors on public string function upgrade( before walking hint: occurrences to find the last one before the function declaration, uses hintStart > 0 as a real sentinel (not the permanently-true arrayLen(hintMatch.match) > 0), extracts the hint line with 3-arg mid() (cross-engine safe), and the negative reFindNoCase("\bupgrade\s+the\s+wheels\s+framework\b", hintLine) assertion is genuinely protective.
Cross-engine
No new cross-engine concerns. The buildSQLiteDatasourcesBlock() helper merged from develop uses simple string concatenation with no struct member functions on CFC objects, no closure captures, and no bracket-notation calls. The spec's use of findNoCase(), find(chr(10), ...), 3-arg mid(), and reFindNoCase() are all cross-engine safe per .ai/wheels/cross-engine-compatibility.md.
Commits
All four commits carry Signed-off-by: DCO trailers:
fix(cli): align wheels upgrade help with the scanner-only reality (#2629)—Signed-off-by: claude[bot]✓docs(web/guides): fix wheels upgrade example to include required check subcommand—Signed-off-by: claude[bot]✓fix(test): address Reviewer A/B consensus findings (round 1)—Signed-off-by: claude[bot]✓- Merge commit —
Signed-off-by: Peter Amiri✓
All three bot commits pass commitlint (valid type, scope, subject ≤ 100 chars, not ALL-CAPS).
Wheels Bot — Reviewer B (round 1)A's review of the merge commit is substantively correct. The PR-specific code is intact, the verdict is justified, and I found no sycophancy or true false positives. One factual inaccuracy in A's scope characterization is noted below, but it does not change the conclusion. SycophancyNone detected. A's approval is supported by specific line references (line 221, lines 2369–2416), a walkthrough of the spec's forward-walk algorithm, per-call cross-engine safety analysis, and DCO verification for all four commits. False positivesNone detected. I independently verified A's key claims:
One inaccuracy worth noting: A states the merge commit "adds only the Missed issuesNone. The 17 develop-origin files introduced by the merge commit are not new code to this PR, and A correctly verified the only files that matter for this PR's regression protection. No cross-engine concerns in the merge content. Verdict alignmentApprove is consistent with A's findings. The PR-specific changes are intact, the spec is now genuinely protective, DCO is clean, and the docs are updated. A correctly focused on the merge commit's cleanliness rather than re-reviewing already-approved code. ConvergenceAligned. The factual inaccuracy about merge scope is a characterization error, not a code defect — the PR is correct and the approval verdict stands. Converging on approve. |
…es-to-and-dry-run-flag Pull in #2645 (wheels upgrade check: seven more 3.x → 4.x breakers) and #2637 (reloadPassword docs) which landed on develop after the previous merge (85549c3). CHANGELOG.md conflict resolved by keeping both Fixed entries adjacent — develop's #2628 entry alongside this PR's #2629 entry. cli/lucli/Module.cfc auto-merged cleanly: #2645 adds new check patterns around line 3679 (allowEnvironmentSwitchViaUrl, csrfEncryptionKey, viteStrictManifest, etc.); #2629's help-text changes sit at lines 224 and 2383-2399. Different regions, no overlap. Signed-off-by: Peter Amiri <peter@alurium.com>
Second develop catch-up — five more PRs landed on develop after the first merge (40d70f3): #2637, #2645, #2639, #2638, #2642. Re-resolves the same three documentation conflicts: - CHANGELOG.md: keep develop's #2628 and #2629 Fixed entries; move this PR's #2626 entry to the end of the Fixed list. - v4-0-0/upgrading/3x-to-4x.mdx: keep develop's new #2631 reloadPassword Common-issues bullet; this PR's #2626 static-asset bullet stays at the end. - v4-0-1-snapshot/upgrading/3x-to-4x.mdx: same resolution. cli/lucli/Module.cfc auto-merged again — no manual fixes needed. Signed-off-by: Peter Amiri <peter@alurium.com>
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: The new head commit (b0d3e835d) merges develop into the PR branch, pulling in #2645 (seven additional 3.x → 4.x breaker checks for wheels upgrade check) and #2637 (reloadPassword docs). All previously identified issues have been resolved. The #2645 implementation is correct, the new UpgradeCheckCoverageSpec.cfc spec is well-constructed, and the docs are accurate. Verdict: approve (submitted as comment — self-review not permitted by GitHub).
Correctness
Seven new check patterns (cli/lucli/Module.cfc lines 3655–3741)
All seven patterns are correct and well-targeted:
- CORS:
new\s+wheels\.middleware\.Cors\s*\(\s*\)correctly matches only the no-argument form that triggers deny-all in 4.0. Multi-line instantiations are a known false-negative; the comment acknowledges multi-line parsing is out of scope and the pattern correctly does what it claims. - RateLimiter: intentionally advisory (fires on any
new wheels.middleware.RateLimiter); the fix text makes this explicit. allowEnvironmentSwitchViaUrl\s*=\s*true: correct regex for the settings call.csrfEncryptionKeywithabsent: true: the inverted-check logic at lines 3829–3838 is correct — pass when nothing is scannable or when the pattern is found; issue only when files were scanned and no occurrence exists. Edge case: a commented-out// csrfEncryptionKeywould satisfy the check and avoid a false positive; acceptable for a best-effort static scan.wheels snippetswithscanTargets: the mixed file/directory target list (Makefile, package.json, .github/workflows/, *.sh) is handled correctly;fileExistsvsdirectoryExistsbranching is correct; the Adobe CF comment guarding against absentextensionskey viastructKeyExistsis the right fix.tests/specs/functionsdirectory check:pattern: ""is correct (never used in thecheckType: "directory"branch); the comment explaining why not to replace it with a benign regex is exactly right.- Vite:
viteScriptTag|viteStyleTag|vitePreloadTagalternation inapp/views/correctly flags every view that could be affected by the strict-manifest default flip.
absent: true logic (lines 3829–3838) — verified correct. The three-way branch (nothing-to-scan → pass; matches-found → pass; files-scanned-no-match → issue) aligns with the stated intent.
CHANGELOG.md conflict — both the #2628 and #2629 entries are present and adjacent under ### Fixed; the #2627 and #2637 documentation entries are present under ### Documentation. No entry was dropped or duplicated.
Module.cfc auto-merge — #2645's new patterns land at lines 3655–3741; #2629's help-text changes are at lines 221–224 and 2355–2416. The regions do not overlap and the merge is clean.
Cross-engine
The new code in cli/lucli/Module.cfc runs on LuCLI (Lucee-based), so engine compatibility concerns are limited to the spec.
UpgradeCheckCoverageSpec.cfc — all CFML used in the spec is cross-engine safe:
fileExists(),fileRead(),find(),len(),mid()(3-arg form — correct per cross-engine compat guide),findNoCase(),reFindNoCase(): all standard.- No
struct.map()on CFC objects, noclientscope, noapplicationscope members, no bracket-notation calls, no inline closures as constructor named args. - Arrow function syntax (
() => {}) is consistent with the existingUpgradeCommandHelpSpec.cfcthat already runs cleanly on the full engine matrix.
Tests
UpgradeCheckCoverageSpec.cfc (7 it-blocks): the block-extraction approach is well-designed — it slices from currentMajor <= 3 && targetMajor >= 4 (line 3629) to // Run checks (line 3743), capturing exactly the check-definition region without the execution loop. All seven pattern strings are present in that slice, so all seven assertions pass for genuine reasons.
The one mild robustness concern: if // Run checks is ever removed, endIdx becomes 0 and the slice extends to end-of-file — a less precise but still-correct extraction. Not a blocking issue.
The six previously-correct specs in UpgradeCommandHelpSpec.cfc are untouched; the 7th spec (corrected in round 3) remains correct.
Docs
Both v4-0-0 and v4-0-1-snapshot copies of upgrade.mdx now list all ten 3.x → 4.x checks accurately. Both copies of 3x-to-4x.mdx include the reloadPassword / set(reloadPassword = env(...)) guidance and the corresponding entry in the Common Issues table. No orphaned stale copy was found.
Commits
All commits carry DCO Signed-off-by: trailers:
fix(cli): align wheels upgrade help with the scanner-only reality (#2629)—claude[bot]✓docs(web/guides): fix wheels upgrade example to include required check subcommand—claude[bot]✓fix(test): address Reviewer A/B consensus findings (round 1)—claude[bot]✓- Merge
85549c3c2—Peter Amiri✓ fix(cli): scan seven more 3.x → 4.x breakers in wheels upgrade check (#2645)— on develop, merged in ✓- Merge
b0d3e835d—Peter Amiri✓
All bot commits pass commitlint (valid type, scope, subject ≤ 100 chars, not ALL-CAPS). Merge commits are exempt.
Wheels Bot — Reviewer B (round 1)A's review of the final merge commit is largely sound. The approval verdict for the #2629 changes is correct. One structural concern with A's review scope and one minor missed point are noted below, neither of which changes the outcome. SycophancyNone detected. A's approval is backed by specific line citations, cross-engine analysis, and a commit-level DCO check rather than a bare LGTM. False positivesNone detected. Every technical claim A makes is accurate for the code A examined. Missed issuesScope imbalance (informational, not blocking): A devoted the majority of the review body to seven new check patterns at
Verdict alignmentApprove is consistent with A's findings. The #2629 implementation is correct, the spec is non-vacuous (as established in prior rounds), and the docs are updated. The scope imbalance inflates apparent thoroughness without covering a defect, but does not make the verdict wrong. ConvergenceAligned. All prior round findings (Bug 1 and Bug 2 from round 1, B's caveat about |
Summary
wheels upgradeis a read-only scanner — it checks for breaking changes between Wheels versions and points users atbrew upgrade wheels(or the equivalent) for the actual install. The previous help surface advertised the command as an upgrader, implying--to=<version>and--dry-runflags that the runtime dispatcher never honored. Users hittingwheels upgrade --dry-runorwheels upgrade --to=4.0.0landed on a terseUsage: wheels upgrade check [...]line and were left guessing.This PR aligns every public-facing description with the scanner-only reality:
showHelp()summary line forupgradenow saysScan for breaking changes before upgrading Wheels (read-only).upgrade()docblock hint matches.checksubcommand, the supported--to=<version>flag, an explicit "--dry-runis not supported" note, and pointers tobrew upgrade wheels/scoop update wheelsfor the install step.--dry-runor--to=withoutcheck, the usage block also prints aDid you mean: wheels upgrade check ...nudge.A source-level regression at
vendor/wheels/tests/specs/cli/UpgradeCommandHelpSpec.cfc(TDD: failing → passing) asserts that the three description sites stay in sync.Related Issue
Fixes #2629
Type of Change
Feature Completeness Checklist
Signed-off-by:(usegit commit -s); see CONTRIBUTING.mdvendor/wheels/tests/specs/cli/UpgradeCommandHelpSpec.cfc(7 specs), demonstrated failing-then-passing locally.bot-update-docs.yml.bot-update-docs.yml.bot-update-docs.yml.[Unreleased].http://localhost:60007(Lucee 7 + SQLite):wheels.tests.specs.cli→ 12 pass, 0 fail, 0 error;wheels.tests.specs.dispatch→ 93 pass, 0 fail, 0 error.Test Plan
--dry-runnot-supported note).cli/lucli/Module.cfc.wheels upgrade --help,wheels upgrade --dry-run, andwheels upgrade --to=4.0.0and confirm the on-screen text matches the new copy.