Skip to content

Commit 2d5037a

Browse files
fix(cli): strip {{enums}} placeholder in legacy CommandBox generator 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>
1 parent c94be05 commit 2d5037a

3 files changed

Lines changed: 59 additions & 1 deletion

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- CLI: 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 model template, so `box wheels generate model` leaked a literal `{{enums}}` into the generated `config()` body as invalid CFML. This legacy path has no enum codegen (unlike the LuCLI generator), so the placeholder is now stripped unconditionally, matching the no-validations fallback (#3180)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Regression spec for the legacy CommandBox-module generator (`cli/src/`).
3+
*
4+
* The legacy model template (`cli/src/templates/ModelContent.txt`) carries a
5+
* `{{enums}}` placeholder, but `cli/src/models/TemplateService.cfc::processTemplate`
6+
* historically substituted only `{{belongsToRelationships}}`, `{{hasManyRelationships}}`,
7+
* `{{hasOneRelationships}}`, and `{{validations}}` — there was no `{{enums}}` branch, so
8+
* the literal placeholder leaked into the generated `config()` body as invalid CFML.
9+
*
10+
* The legacy path has no enum codegen, so the safe fix is to STRIP the placeholder
11+
* (matching the no-validations fallback). This spec pins that behavior.
12+
*
13+
* See https://github.com/wheels-dev/wheels/issues/3180.
14+
*/
15+
component extends="wheels.wheelstest.system.BaseSpec" {
16+
17+
function run() {
18+
19+
describe("Legacy TemplateService — {{enums}} placeholder", () => {
20+
21+
it("strips the {{enums}} placeholder so it never leaks into generated CFML", () => {
22+
// Instantiate the legacy generator directly (resolves from the test webroot).
23+
var svc = new cli.src.models.TemplateService();
24+
makePublic(svc, "processTemplate");
25+
26+
// Mirror the model template body that ships with the legacy module.
27+
var template = 'component extends="Model" {' & chr(10) &
28+
chr(9) & "function config() {" & chr(10) &
29+
chr(9) & chr(9) & "{{belongsToRelationships}}" & chr(10) &
30+
chr(9) & chr(9) & "{{hasManyRelationships}}" & chr(10) &
31+
chr(9) & chr(9) & "{{hasOneRelationships}}" & chr(10) &
32+
chr(9) & chr(9) & "{{validations}}" & chr(10) &
33+
chr(9) & chr(9) & "{{enums}}" & chr(10) &
34+
chr(9) & "}" & chr(10) &
35+
"}";
36+
37+
var result = svc.processTemplate(template, {});
38+
39+
// The placeholder must be gone — a leaked {{enums}} is invalid CFML.
40+
expect(result).notToInclude("{{enums}}");
41+
// Sanity: the sibling placeholders are still being handled (already stripped).
42+
expect(result).notToInclude("{{validations}}");
43+
expect(result).notToInclude("{{belongsToRelationships}}");
44+
});
45+
46+
});
47+
48+
}
49+
50+
}

cli/src/models/TemplateService.cfc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,14 @@ component {
130130
} else {
131131
processed = reReplace(processed, "\{\{validations\}\}", "", "all");
132132
}
133-
133+
134+
// Process enums — this legacy CommandBox-module generator has no enum codegen
135+
// (unlike the LuCLI generator at cli/lucli/services/CodeGen.cfc). The model
136+
// template still carries an {{enums}} placeholder, so strip it unconditionally;
137+
// otherwise the literal {{enums}} leaks into the generated config() body as
138+
// invalid CFML (issue ##3180).
139+
processed = reReplace(processed, "\{\{enums\}\}", "", "all");
140+
134141
// Process actions for controllers
135142
if (structKeyExists(arguments.context, "actions") && isArray(arguments.context.actions)) {
136143
var actionsCode = generateActionsCode(arguments.context.actions);

0 commit comments

Comments
 (0)