Skip to content

LuCLI: release.yml drops codegen templates — all template-driven generators emit empty output in installed module #1944

Closed

Description

@bpamiri

Scope change

This issue originally tracked adding three stretch generators (api-resource, helper, snippets). All three are implemented in source (Module.cfc:190-205, CodeGen.cfc, Scaffold.cfc, + 12 snippet templates). However, e2e testing against an installed wheels binary surfaced a broader packaging bug that makes most generators unusable — reframing this issue to track the fix.

Bug

In a freshly installed Wheels project:

$ wheels generate model Post title:string body:text
  create  app/models/Post.cfc

$ cat app/models/Post.cfc
component extends="Model" {
    function config() {
        
        
        
        
    }
}

No validations. No relationships. Empty config(). Same stripped output for controller, view, scaffold, api-resource. helper fails loudly: Template not found: HelperContent.txt.

Only wheels generate snippets works end-to-end because its templates ship under cli/lucli/templates/snippets/.

Root cause

Templates.cfc::resolveTemplateDir() expects code-generation templates at moduleRoot/templates/codegen/ for installed modules. Per PLAN.md, the release workflow is supposed to copy cli/src/templates/ → cli/lucli/templates/codegen/ before tarring the module.

.github/workflows/release.yml:201 has no such copy step:

tar czf ... wheels-module-${{ env.WHEELS_VERSION }}.tar.gz -C cli/lucli .

Result: the distributed tar ships only admin/, app/, deploy/, migrations/, snippets/ under templates/ — no codegen/. All generateFromTemplate() calls targeting ModelContent.txt, ControllerContent.txt, ApiControllerContent.txt, ViewContent.txt, HelperContent.txt, CRUDContent.txt, ActionContent.txt, DBMigrate.txt, tests/*.txt, crud/*.txt, admin/*.txt silently fall through to the empty/error paths.

This is invisible in the monorepo because resolveTemplateDir() fallback #2 resolves cli/src/templates/ directly. The CI test suite also runs in monorepo mode — the bug only manifests against installed distributions.

Fix

Add a bundle step to release.yml (and snapshot.yml for pre-release builds) before the tar:

- name: Bundle codegen templates into module
  run: |
    mkdir -p cli/lucli/templates/codegen
    cp -R cli/src/templates/* cli/lucli/templates/codegen/

Verification (e2e smoke test)

Must pass on the just-built tar, not the monorepo source:

# Install the built tar
mkdir -p ~/.wheels/modules/wheels
tar xzf wheels-module-*.tar.gz -C ~/.wheels/modules/wheels

# Scaffold + run each generator
cd /tmp && wheels new smoke && cd smoke

wheels generate model User name:string email:string active:boolean
grep -q "validatesPresenceOf" app/models/User.cfc          # must pass

wheels generate controller Users index show
grep -q "function index" app/controllers/Users.cfc         # must pass

wheels generate api-resource Product name price:decimal sku:string
grep -q "renderWith" app/controllers/Products.cfc          # must pass

wheels generate helper formatting truncateText formatCurrency
test -s app/helpers/FormattingHelper.cfc                   # must pass

wheels generate scaffold Post title:string body:text
test -s app/views/posts/index.cfm                          # must pass

wheels generate snippets auth
test -f app/controllers/Sessions.cfc                       # must pass

Consider wiring this as a post-build GitHub Actions step so future releases cannot regress the packaging.

Out of scope for this issue

  • The broader gap that CI never exercises the distributed tar (separate follow-up).
  • Parameter-binding correctness of each generator — covered by existing specs once templates are reachable.

Activity

  1. bpamiri commented on Mar 16, 2026

    @bpamiri
    CollaboratorAuthor

    Analysis

    Synopsis

    Add three stretch generators to LuCLI beyond the eight already implemented: generate api-resource (API-only controller + model, no views), generate helper (app helper in app/global/), and generate snippets (copy snippet templates to app/snippets/).

    Merit Assessment

    Recommendation: Proceed

    • All three are low-complexity additions that build on the existing CodeGen and Scaffold services without requiring new infrastructure.
    • api-resource is the highest-value of the three — it's a common pattern for modern Wheels apps and the scaffold service already supports api=true (Scaffold.cfc line 30, CodeGen.cfc line 97). This is mostly a wiring exercise.
    • helper and snippets are simple file-copy operations. Low effort, good for completeness.

    Implementation Plan

    1. generate api-resource (medium priority)

    • Add a case in Module.cfc generate() function (around line 44) for "api-resource" or "api"
    • Delegate to Scaffold.generateScaffold() with api=true — this already skips view generation and uses ApiControllerContent.txt template
    • Template cli/src/templates/ApiControllerContent.txt already exists
    • Output: model CFC + API controller CFC + migration + tests + route (no views)
    • Estimated: ~30 minutes

    2. generate helper (low priority)

    • Add case in generate() for "helper"
    • Create file at app/global/{Name}.cfm with a basic function skeleton
    • No existing template — create inline or add HelperContent.txt to cli/src/templates/
    • Convention: helpers are .cfm files with plain functions (no component wrapper)
    • Estimated: ~20 minutes

    3. generate snippets (low priority)

    • Add case in generate() for "snippets"
    • Copy all files from cli/src/templates/ to app/snippets/ in the project
    • The Templates service (Templates.cfc line 177) already checks app/snippets/ as an override directory, so once copied, users can customize templates
    • Add --force flag to overwrite existing snippets
    • Estimated: ~20 minutes

    4. Update help text in generate() (line 48) to list the new generator types.

    Dependencies & Risks

    • Depends on: LuCLI Phase 2: Service layer, generators, and MCP annotations #1941 (merged) — CodeGen and Scaffold services exist
    • No blocking relationship — these are additive and can ship independently
    • Risk: Minimal. All three generators produce new files only; no modification of existing code. The api-resource generator reuses the proven scaffold pipeline.
    • Related: The ApiControllerContent.txt template should be verified to produce correct output with the LuCLI template processing (pipe-delimited |ObjectName| placeholders vs. {{variable}} style). Templates.cfc handles both styles (lines 62-146).

    Automated analysis by @claude — review and adjust as needed.

  2. added this to the v3.2 milestone on Mar 17, 2026
  3. changed the title [-]LuCLI: stretch generators (api-resource, helper, snippets)[/-] [+]LuCLI: stretch generators (api-resource, helper, snippets) Issue #1944[/+] on Apr 1, 2026
  4. changed the title [-]LuCLI: stretch generators (api-resource, helper, snippets) Issue #1944[/-] [+]LuCLI: release.yml drops codegen templates — all template-driven generators emit empty output in installed module[/+] on Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions