fix(cli): strip {{enums}} placeholder in legacy CommandBox generator template - #3191
Conversation
…template
The legacy CommandBox-module generator (cli/src/models/TemplateService.cfc)
substituted {{belongsToRelationships}}, {{hasManyRelationships}},
{{hasOneRelationships}}, and {{validations}} but had no branch for the
{{enums}} placeholder carried by its model template. box wheels generate
model therefore leaked a literal {{enums}} into the generated config() body
as invalid CFML. This legacy path has no enum codegen (unlike the LuCLI
generator at cli/lucli/services/CodeGen.cfc), so the placeholder is now
stripped unconditionally, mirroring the no-validations fallback.
Adds a regression spec under cli/lucli/tests/specs/services/ that exercises
the legacy TemplateService.processTemplate via makePublic and asserts the
{{enums}} placeholder never survives into generated output.
Refs #3180
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Wheels Bot — No doc updatesReviewed this PR's diff and found no docs that need updating (purely internal bug fix to the legacy CommandBox-module generator's template processing — no existing guide page covers this path, no |
There was a problem hiding this comment.
Wheels Bot — Reviewer
TL;DR: This PR fixes the legacy CommandBox-module generator (cli/src/models/TemplateService.cfc) leaking a literal {{enums}} placeholder into generated model config() bodies (box wheels generate model, refs #3180), by stripping the placeholder unconditionally — mirroring the existing no-validations fallback. The diff is small, correct, and well-tested; I verified every load-bearing assumption in the new spec against the actual code. Verdict: comment (no blocking findings; final confidence on the new spec's green run is delegated to CI per the PR's own disclosure that the sandbox could not execute it locally).
Verification notes (all checks passed)
Correctness
- The defect is real:
cli/src/templates/ModelContent.txt:9carries{{enums}}, and pre-fixprocessTemplatehad branches only forbelongsToRelationships/hasManyRelationships/hasOneRelationships/validations(TemplateService.cfc:90-132) — nothing consumed{{enums}}, and the generic{{key}}loop (lines 52-67) only substitutes keys present in the context. - The unconditional strip at
cli/src/models/TemplateService.cfc:139is placed after the generic loop, so a hypothetical futurecontext.enumssimple value would still substitute first and the strip becomes a no-op — no regression path. reReplacewith\{\{enums\}\}is case-sensitive and matches the template's lowercase placeholder exactly, consistent with the sibling branches.
Tests
cli/lucli/tests/specs/services/LegacyTemplateServiceEnumsSpec.cfcis correctly wired:wheels.wheelstest.system.BaseSpecis the established base for CLI service specs (22 prior uses in that directory);makePublicexists (vendor/wheels/wheelstest/system/BaseSpec.cfc:1570) with prior art inServerDetectionSpec.cfc:45; the dot-pathnew cli.src.models.TemplateService()resolves from the repo-root webroot exactly as the runner'sdirectory = "cli.lucli.tests.specs"does (cli/lucli/tests/runner.cfm:5).- Instantiation with an empty context is safe:
TemplateService.cfchas noinit(), and every access to the WireBox-injectedvariables.helpersis guarded by astructKeyExistscheck on context keys the spec never sets (lines 70-80, 221-228). - The failing-then-passing TDD claim holds by inspection: pre-fix, no code path removed
{{enums}}, soexpect(result).notToInclude("{{enums}}")would fail. Non-blocking note: per the PR body the spec was traced, not executed, in the bot sandbox — the CLI test workflow on this PR is the authoritative confirmation; please ensure it is green before merge. - Placing the spec in the LuCLI suite (not the cross-engine core suite) is the right call — the core suite's
directory="wheels.tests.specs"would eagerly compile the legacycli.src.*CFC on every engine.
Docs
- Changelog fragment
changelog.d/3180-cli-legacy-template-enums-leak.fixed.mduses a valid type and the fragment system correctly (no directCHANGELOG.mdedit).
Commits
- Single commit
2d5037aconforms to commitlint (fix(cli):, subject ≤ 100 chars, not ALL-CAPS) and carries a DCO sign-off matching the author email. Theissue ##3180doubled-hash in the new code comment matches existing repo style (vendor/wheels/Global.cfc:4285), so no change needed there.
No Correctness, Cross-engine, or Security findings. The Refs (not Fixes) linkage to keep the broader ForgeBox-distribution decision open on #3180 matches the triage scope.
|
Superseded by #3197 (merged): a propose-fix draft that raced the ForgeBox path-repair campaign for the same issue; the campaign PR landed first and closed the underlying issue. Closing the duplicate. |
Summary
The legacy CommandBox-module generator (
cli/src/models/TemplateService.cfc)substituted
{{belongsToRelationships}},{{hasManyRelationships}},{{hasOneRelationships}}, and{{validations}}but had no branch for the{{enums}}placeholder that ships in its own model template(
cli/src/templates/ModelContent.txt). As a resultbox wheels generate model(the ForgeBox-installed
wheels-cli) leaked a literal{{enums}}into thegenerated
config()body — invalid CFML. This path has no enum codegen at all(unlike the LuCLI generator at
cli/lucli/services/CodeGen.cfc, which rendersenums), so the minimal, safe fix is to strip the placeholder unconditionally,
mirroring the existing no-validations fallback.
Related Issue
Refs #3180
This PR ships only the standalone
{{enums}}leak. The broader maintainerdecision the issue also raises — whether to keep publishing the legacy
CommandBox-module CLI to ForgeBox vs. point users at the LuCLI distribution —
is explicitly out of scope per triage, so this uses
Refs(notFixes) toavoid auto-closing the tracking issue.
Type of Change
Feature Completeness Checklist
Signed-off-by:(git commit -s)bot-update-docs.ymlbot-update-docs.ymlbot-update-docs.ymlchangelog.d/3180-cli-legacy-template-enums-leak.fixed.mdTest Plan
Spec:
cli/lucli/tests/specs/services/LegacyTemplateServiceEnumsSpec.cfc(placed in the LuCLI suite because it runs only on the bundled Lucee, where
instantiating the legacy
cli.src.*CFC is safe — the cross-engine coresuite must not compile/instantiate the CommandBox-module generator).
The spec instantiates
cli.src.models.TemplateService, exposes the privateprocessTemplateviamakePublic, and feeds it the model-template body with anempty context:
{{validations}},{{belongsToRelationships}}) is stripped by its existingelsebranch, but{{enums}}survives, soexpect(result).notToInclude("{{enums}}")fails —isolating exactly the reported defect.
Run with
bash tools/test-cli-local.sh.