Auto-detect app layout and generate files in correct path (flat vs modern)#51
Auto-detect app layout and generate files in correct path (flat vs modern)#51lmajano merged 3 commits intodevelopmentfrom
Conversation
Agent-Logs-Url: https://github.com/ColdBox/coldbox-cli/sessions/04af5f58-9949-47ba-a2d6-e374e82d64f8 Co-authored-by: lmajano <137111+lmajano@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ColdBox/coldbox-cli/sessions/04af5f58-9949-47ba-a2d6-e374e82d64f8 Co-authored-by: lmajano <137111+lmajano@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR improves the ColdBox CLI generators to automatically target the correct app source directory based on whether the project uses a modern (/app + /public) or flat layout, reducing the need for manual directory= overrides.
Changes:
- Added
BaseCommand.getAppPrefix(cwd)to map detected layout →app/prefix or no prefix. - Updated
coldbox create *generators to default output directories togetAppPrefix(getCWD()) & "<dir>"for handlers/models/views/layouts/interceptors (and related CRUD/resource params). - Documented the new behavior in
README.mdand noted it inchangelog.md.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents modern vs flat layout detection and where generators will output files. |
| changelog.md | Adds an Unreleased note about automatic layout detection for generators. |
| models/BaseCommand.cfc | Introduces getAppPrefix(cwd) helper based on Utility.detectTemplateType(). |
| commands/coldbox/create/handler.cfc | Defaults directory and viewsDirectory to respect detected layout. |
| commands/coldbox/create/interceptor.cfc | Defaults directory to respect detected layout. |
| commands/coldbox/create/layout.cfc | Defaults directory to respect detected layout. |
| commands/coldbox/create/model.cfc | Defaults directory to respect detected layout. |
| commands/coldbox/create/service.cfc | Defaults directory to respect detected layout. |
| commands/coldbox/create/view.cfc | Defaults directory to respect detected layout. |
| commands/coldbox/create/resource.cfc | Defaults handlersDirectory/viewsDirectory/modelsDirectory to respect detected layout. |
| commands/coldbox/create/orm-crud.cfc | Defaults handlersDirectory/viewsDirectory to respect detected layout. |
| commands/coldbox/create/orm-entity.cfc | Defaults directory to respect detected layout. |
| commands/coldbox/create/orm-service.cfc | Defaults directory to respect detected layout. |
| commands/coldbox/create/orm-virtual-service.cfc | Defaults directory to respect detected layout. |
| | Layout | Detection | App Code Location | Tests Location | | ||
| | ------ | --------- | ----------------- | -------------- | | ||
| | **Modern** | Both `app/` and `public/` directories exist | `/app/models`, `/app/handlers`, etc. | `/tests/` | | ||
| | **Flat** | Default (no `app/` + `public/`) | `/models`, `/handlers`, etc. | `/tests/` | |
There was a problem hiding this comment.
The Flat layout detection description is slightly inaccurate. The code treats a project as "flat" whenever both app/ and public/ are not present (i.e., either folder missing), not only when neither exists. Update the table wording to match the actual detection behavior.
| | **Flat** | Default (no `app/` + `public/`) | `/models`, `/handlers`, etc. | `/tests/` | | |
| | **Flat** | Default (when either `app/` or `public/` is missing) | `/models`, `/handlers`, etc. | `/tests/` | |
| * @return string "app/" for modern layout, "" for flat layout | ||
| */ | ||
| function getAppPrefix( required cwd ){ | ||
| return variables.utility.detectTemplateType( cwd ) == "modern" ? "app/" : ""; |
There was a problem hiding this comment.
Use arguments.cwd when calling detectTemplateType() to match the explicit argument scoping used elsewhere in this component (and avoid any potential name collisions with variables in other scopes).
| return variables.utility.detectTemplateType( cwd ) == "modern" ? "app/" : ""; | |
| return variables.utility.detectTemplateType( arguments.cwd ) == "modern" ? "app/" : ""; |
| boolean tests = true, | ||
| testsDirectory = "tests/specs/unit", | ||
| directory = "models", | ||
| directory = getAppPrefix( getCWD() ) & "models", | ||
| description = "I am a new service", |
There was a problem hiding this comment.
The command help/docs above still state the default output directory is /models, but the default now depends on layout detection (models vs app/models). Update the description/param docs so the displayed CLI help matches the new behavior.
| actions = "", | ||
| boolean views = true, | ||
| viewsDirectory = "views", | ||
| viewsDirectory = getAppPrefix( getCWD() ) & "views", | ||
| boolean integrationTests = true, | ||
| appMapping = "/", | ||
| testsDirectory = "tests/specs/integration", | ||
| directory = "handlers", | ||
| directory = getAppPrefix( getCWD() ) & "handlers", | ||
| description = "I am a new handler", |
There was a problem hiding this comment.
The command documentation currently says the handler default directory is /handlers (and the @directory param says it defaults to handlers), but the default now depends on layout detection (handlers vs app/handlers, and similarly for viewsDirectory). Update the help text/param docs so the CLI help matches the new behavior.
| required name, | ||
| boolean helper = false, | ||
| directory = "views", | ||
| directory = getAppPrefix( getCWD() ) & "views", | ||
| boolean open = false, |
There was a problem hiding this comment.
The command docs above still state the default view directory is /views, but the default now depends on layout detection (views vs app/views). Update the description/param docs so the CLI help matches the new behavior.
| required name, | ||
| boolean helper = false, | ||
| directory = "layouts", | ||
| directory = getAppPrefix( getCWD() ) & "layouts", | ||
| boolean open = false, |
There was a problem hiding this comment.
The command docs above still state the default layout directory is /layouts, but the default now depends on layout detection (layouts vs app/layouts). Update the description/param docs so the CLI help matches the new behavior.
| description = "I am a new interceptor", | ||
| boolean tests = true, | ||
| testsDirectory = "tests/specs/interceptors", | ||
| directory = "interceptors", | ||
| directory = getAppPrefix( getCWD() ) & "interceptors", | ||
| boolean open = false, |
There was a problem hiding this comment.
The command docs above still state the default interceptor directory is /interceptors, but the default now depends on layout detection (interceptors vs app/interceptors). Update the description/param docs so the CLI help matches the new behavior.
| boolean tests = true, | ||
| testsDirectory = "tests/specs/unit", | ||
| directory = "models", | ||
| directory = getAppPrefix( getCWD() ) & "models", | ||
| description = "I am a new Model Object", |
There was a problem hiding this comment.
The command docs above still state the default model directory is /models, but the default now depends on layout detection (models vs app/models). Update the description/param docs so the CLI help matches the new behavior.
| required entity, | ||
| pluralName = "", | ||
| handlersDirectory = "handlers", | ||
| viewsDirectory = "views", | ||
| handlersDirectory = getAppPrefix( getCWD() ) & "handlers", | ||
| viewsDirectory = getAppPrefix( getCWD() ) & "views", | ||
| boolean tests = true, |
There was a problem hiding this comment.
The @handlersDirectory / @viewsDirectory parameter docs still say the defaults are handlers and views, but the defaults now depend on layout detection (handlers vs app/handlers, views vs app/views). Update the help text so the CLI help matches the new behavior.
| properties = "", | ||
| modulesDirectory = "modules_app", | ||
| handlersDirectory = "handlers", | ||
| viewsDirectory = "views", | ||
| modelsDirectory = "models", | ||
| handlersDirectory = getAppPrefix( getCWD() ) & "handlers", | ||
| viewsDirectory = getAppPrefix( getCWD() ) & "views", | ||
| modelsDirectory = getAppPrefix( getCWD() ) & "models", | ||
| boolean tests = true, |
There was a problem hiding this comment.
The @handlersDirectory / @viewsDirectory / @modelsDirectory parameter docs still say the defaults are handlers, views, and models, but the defaults now depend on layout detection (* vs app/*). Update the help text so the CLI help matches the new behavior.
Modern ColdBox templates (
boxlang,modern) place app source under/app/, but allcoldbox create *commands hardcoded paths likehandlers,models,views— requiring developers tocd appor manually passdirectory=app/modelsevery time.Changes
models/BaseCommand.cfcgetAppPrefix(cwd)— returns"app/"if both/appand/publicdirectories exist (modern layout),""otherwise. Delegates detection to the existingUtility.detectTemplateType().All 13
coldbox createcommands — default directory params now usegetAppPrefix(getCWD()) & "<dir>":handlerdirectory,viewsDirectorymodel,service,orm-entity,orm-service,orm-virtual-servicedirectoryview,layout,interceptordirectoryresourcehandlersDirectory,viewsDirectory,modelsDirectoryorm-crudhandlersDirectory,viewsDirectorytests/,modules/, andresources/paths are intentionally unchanged — those remain at the project root in both layouts.Behavior