Skip to content

Commit d520cda

Browse files
committed
tons of updates
1 parent a3e0bba commit d520cda

File tree

16 files changed

+1060
-34
lines changed

16 files changed

+1060
-34
lines changed

changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Added
1313

14+
- BoxLang is now the default engine for new apps
15+
- Updated all new templates from repos
16+
- New create app argument for modern or boxlang skeletons: `vite` to create a Vite enabled app: `coldbox create app name="myApp" --vite`
17+
- New create app argument for modern or boxlang skeletons: `rest` to create a REST enabled app: `coldbox create app name="myApp" --rest`
18+
- - New create app argument for modern or boxlang skeletons: `docker` to create a Docker enabled app: `coldbox create app name="myApp" --docker`
19+
- New create app argument for modern or boxlang skeletons: `migrations` to create a Migrations enabled app: `coldbox create app name="myApp" --migrations`
1420
- BoxLang template skeleton rename
1521
- Updated docs for BoxLang detection
1622

commands/coldbox/create/app-wizard.cfc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ component extends="app" aliases="" {
55

66
/**
77
* @name The name of the app you want to create
8-
* @skeleton The application skeleton you want to use (AdvancedScript, rest, rest-hmvc, Simple, SuperSimple)
8+
* @skeleton The application skeleton you want to use
99
* @init Init this as a package
1010
* @boxlang Is this a BoxLang project?
1111
**/

commands/coldbox/create/app.cfc

Lines changed: 212 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
/**
22
* Create a blank ColdBox app from one of our app skeletons or a skeleton using a valid Endpoint ID which can come from .
3-
* ForgeBox, HTTP/S, git, github, etc.
3+
* FORGEBOX, HTTP/S, git, github, etc.
44
* By default it will create the application in your current directory.
55
* .
66
* {code:bash}
77
* coldbox create app myApp
88
* {code}
99
* .
10-
* Here are the basic skeletons that are available for you that come from ForgeBox
11-
* - BoxLang
12-
* - Default (default)
13-
* - Elixir
14-
* - Modern
15-
* - rest
16-
* - rest-hmvc
17-
* - SuperSimple
18-
* - Vite
10+
* Here are the basic skeletons that are available for you that come from FORGEBOX
11+
*
12+
* - BoxLang (Default)
13+
* - Modern (CFML + BoxLang Default)
14+
* - flat (CFML + BoxLang Flat)
15+
* - rest (CFML + BoxLang RESTful API)
16+
* - rest-hmvc (HMVC + REST)
17+
* - supersimple (bare bones)
18+
* - vite (flat + vite)
1919
* .
2020
* {code:bash}
21-
* coldbox create app skeleton=rest
21+
* coldbox create app skeleton=modern
2222
* {code}
2323
* .
2424
* The skeleton parameter can also be any valid FORGEBOX Endpoint ID, which includes a Git repo or HTTP URL pointing to a package.
2525
* .
2626
* {code:bash}
2727
* coldbox create app skeleton=http://site.com/myCustomAppTemplate.zip
28-
* coldbox create app skeleton=coldbox-templates/modern
28+
* coldbox create app skeleton=coldbox-templates/rest
2929
* {code}
3030
*
3131
**/
@@ -40,22 +40,24 @@ component extends="coldbox-cli.models.BaseCommand" {
4040
function init(){
4141
// Map these shortcut names to the actual ForgeBox slugs
4242
variables.templateMap = {
43-
"Default" : "cbtemplate-advanced-script",
44-
"BoxLang" : "cbtemplate-boxlang",
45-
"Elixir" : "cbtemplate-elixir",
43+
"flat" : "cbtemplate-flat",
44+
"boxlang" : "cbtemplate-boxlang",
4645
"modern" : "cbtemplate-modern",
4746
"rest" : "cbtemplate-rest",
4847
"rest-hmvc" : "cbtemplate-rest-hmvc",
49-
"Vite" : "cbtemplate-vite",
50-
"SuperSimple" : "cbtemplate-supersimple"
48+
"vite" : "cbtemplate-vite",
49+
"supersimple" : "cbtemplate-supersimple"
5150
};
5251

5352
variables.defaultAppName = "My ColdBox App";
53+
variables.defaultSkeleton = "boxlang";
5454

5555
return this;
5656
}
5757

5858
/**
59+
* Create a new ColdBox application
60+
*
5961
* @name The name of the app you want to create
6062
* @skeleton The name of the app skeleton to generate (or an endpoint ID like a forgebox slug)
6163
* @skeleton.optionsUDF skeletonComplete
@@ -66,41 +68,45 @@ component extends="coldbox-cli.models.BaseCommand" {
6668
* @verbose Verbose output
6769
* @migrations Run migration init after creation
6870
* @boxlang Set the language to BoxLang
71+
* @docker Include Docker files and setup Docker configuration
72+
* @vite Setup Vite for frontend asset building (For modern/boxlang apps only)
73+
* @rest Is this a REST API project? (For modern/boxlang apps only)
6974
**/
7075
function run(
7176
name = defaultAppName,
72-
skeleton = "default",
77+
skeleton = variables.defaultSkeleton,
7378
directory = getCWD(),
7479
boolean init = true,
7580
boolean wizard = false,
7681
boolean initWizard = false,
7782
boolean verbose = false,
7883
boolean migrations = false,
79-
boolean boxlang = isBoxLangProject( getCWD() )
84+
boolean boxlang = isBoxLangProject( getCWD() ),
85+
boolean docker = true,
86+
boolean vite = false,
87+
boolean rest = false
8088
){
8189
// Check for wizard argument
8290
if ( arguments.wizard ) {
8391
command( "coldbox create app-wizard" ).params( verbose = arguments.verbose ).run();
8492
return;
8593
}
8694

87-
job.start( "Creating App [#arguments.name#]" );
88-
95+
job.start( "🧑‍🍳 Creating & Prepping Your App [#arguments.name#]" );
8996
if ( arguments.verbose ) {
9097
job.setDumpLog( arguments.verbose );
9198
}
9299

93100
// This will make the directory canonical and absolute
94101
arguments.directory = resolvePath( arguments.directory );
95-
96102
// Validate directory, if it doesn't exist, create it.
97103
if ( !directoryExists( arguments.directory ) ) {
98104
directoryCreate( arguments.directory );
99105
}
100106

101107
// If the skeleton = default and this is a boxlang project, then switch the skeleton to BoxLang
102108
if ( arguments.skeleton == "default" && arguments.boxlang ) {
103-
arguments.skeleton = "BoxLang";
109+
arguments.skeleton = variables.defaultSkeleton;
104110
}
105111

106112
// If the skeleton is one of our "shortcut" names
@@ -109,7 +115,7 @@ component extends="coldbox-cli.models.BaseCommand" {
109115
arguments.skeleton = variables.templateMap[ arguments.skeleton ];
110116
}
111117

112-
// Install the skeleton
118+
// Install the skeleton from ForgeBox or other endpoint
113119
packageService.installPackage(
114120
ID : arguments.skeleton,
115121
directory : arguments.directory,
@@ -119,8 +125,6 @@ component extends="coldbox-cli.models.BaseCommand" {
119125
currentWorkingDirectory: arguments.directory
120126
);
121127

122-
job.start( "Preparing box.json" );
123-
124128
// Init, if not a package as a Box Package
125129
if ( arguments.init && !packageService.isPackage( arguments.directory ) ) {
126130
var originalPath = getCWD();
@@ -138,7 +142,11 @@ component extends="coldbox-cli.models.BaseCommand" {
138142

139143
// Prepare language
140144
if ( arguments.boxlang ) {
145+
printInfo( "Setting language to BoxLang" );
141146
command( "package set" ).params( language: "BoxLang" ).run();
147+
} else {
148+
printInfo( "Setting language to CFML" );
149+
command( "package set" ).params( language: "CFML" ).run();
142150
}
143151

144152
// Prepare defaults on box.json so we remove template based ones
@@ -147,27 +155,198 @@ component extends="coldbox-cli.models.BaseCommand" {
147155
name : arguments.name,
148156
slug : variables.formatterUtil.slugify( arguments.name ),
149157
version : "1.0.0",
150-
location: "forgeboxStorage"
158+
location: "forgeboxStorage",
159+
ignore : []
151160
)
152161
.run();
153162

154-
job.complete();
155-
156163
// set the server name if the user provided one
164+
printInfo( "🤖 Preparing server" );
157165
if ( arguments.name != defaultAppName ) {
158-
job.start( "Preparing server.json" );
159166
command( "server set" ).params( name = arguments.name ).run();
160-
job.complete();
161167
}
162168

163-
// Finalize Create app Job
164-
job.complete();
169+
// ENV File
170+
var envFile = arguments.directory & ".env";
171+
if ( !fileExists( envFile ) ) {
172+
printInfo( "🌿 Creating .env file" );
173+
if( fileExists( arguments.directory & ".env.example" ) ){
174+
fileCopy( arguments.directory & ".env.example", envFile );
175+
} else {
176+
fileCopy( variables.settings.templatesPath & ".env.example", envFile );
177+
}
178+
} else {
179+
printInfo( "⏭️ .env file already exists, skipping creation." )
180+
}
181+
182+
// Copilot instructions
183+
printInfo( "🤖 Preparing GitHub Copilot configuration" );
184+
var githubDir = arguments.directory & ".github";
185+
var copilotFile = githubDir & "/copilot-instructions.md";
186+
if( !directoryExists( githubDir ) ){
187+
directoryCreate( githubDir, true )
188+
}
189+
if( !fileExists( copilotFile ) ){
190+
printInfo( "🥊 Creating copilot file" )
191+
// If the template has a copilot-instructions.md, use it, otherwise use the default one
192+
if( fileExists( arguments.directory & "resources/copilot-instructions.md" ) ){
193+
fileCopy( arguments.directory & "resources/copilot-instructions.md", copilotFile );
194+
} else {
195+
if( arguments.skeleton == "modern" ){
196+
fileCopy( variables.settings.templatesPath & "modern-copilot-instructions.md", copilotFile );
197+
}
198+
else {
199+
fileCopy( variables.settings.templatesPath & "flat-copilot-instructions.md", copilotFile );
200+
}
201+
}
202+
} else{
203+
printInfo( "⏭️ copilot-instructions.md file already exists, skipping creation." )
204+
}
165205

166206
// Run migrations init
167207
if ( arguments.migrations ) {
208+
printInfo( "🚀 Initializing Migrations" );
168209
variables.utility.ensureMigrationsModule();
169210
command( "migrate init" ).run();
211+
variables.print
212+
.line( "👉 You can run `migrate help` to see all available migration commands." )
213+
.toConsole();
214+
}
215+
216+
if( arguments.docker ){
217+
printInfo( "🥊 Setting up Docker for containerization" )
218+
if( directoryExists( arguments.directory & "docker" ) ){
219+
printInfo( "⏭️ Docker directory already exists, skipping creation." )
220+
} else {
221+
directoryCreate( arguments.directory & "docker", true )
222+
fileCopy(
223+
"#variables.settings.templatesPath#/docker/Dockerfile",
224+
arguments.directory & "docker/Dockerfile"
225+
)
226+
fileCopy(
227+
"#variables.settings.templatesPath#/docker/docker-compose.yml",
228+
arguments.directory & "docker/docker-compose.yml"
229+
)
230+
fileCopy(
231+
"#variables.settings.templatesPath#/docker/.dockerignore",
232+
arguments.directory & "docker/.dockerignore"
233+
)
234+
variables.print
235+
.line( "✅ Docker setup complete!" )
236+
.line( "👉 You can run 'box run-script docker:build' to build your Docker image." )
237+
.line( "👉 You can run 'box run-script docker:run' to run your Docker container." )
238+
.line( "👉 You can run 'box run-script docker:bash' to go into the container shell." )
239+
.line( "👉 You can run 'box run-script docker:stack' to startup the Docker Compose Stack" )
240+
.toConsole();
241+
}
242+
}
243+
244+
// VITE Setup
245+
if( arguments.vite ){
246+
if( arguments.skeleton != "modern" && arguments.skeleton != "boxlang" ){
247+
printWarn( "⚠️ Vite setup is only supported for 'modern' or 'boxlang' skeletons. Skipping Vite setup." )
248+
} else {
249+
printInfo( "🥊 Setting up Vite for your frontend build system" )
250+
fileCopy( "#variables.settings.templatesPath#/vite/.babelrc", arguments.directory & ".babelrc" )
251+
fileCopy( "#variables.settings.templatesPath#/vite/package.json", arguments.directory & "package.json" )
252+
fileCopy( "#variables.settings.templatesPath#/vite/vite.config.mjs", arguments.directory & "vite.config.mjs" )
253+
fileDelete( arguments.directory & "app/layouts/Main.bxm" )
254+
fileCopy( "#variables.settings.templatesPath#/vite/layouts/Main.bxm", arguments.directory & "app/layouts/Main.bxm" )
255+
fileCopy( "#variables.settings.templatesPath#/vite/assets", arguments.directory & "resources/assets" )
256+
257+
printInfo( "🥊 Installing ColdBox Vite Helpers" )
258+
command( "install" )
259+
.params( "vite-helpers" )
260+
.run();
261+
262+
variables.print
263+
.line( "✅ Vite setup complete!" )
264+
.line( "👉 You can run 'npm install' to install the dependencies" )
265+
.line( "👉 You can run 'npm run dev' to start the development server" )
266+
.line( "👉 You can run 'npm run build' to build the production assets" )
267+
.toConsole();
268+
}
269+
}
270+
271+
// REST Setup
272+
if( arguments.rest ){
273+
if( arguments.skeleton != "modern" && arguments.skeleton != "boxlang" ){
274+
printWarn( "⚠️ REST setup is only supported for 'modern' or 'boxlang' skeletons. Skipping REST setup." )
275+
} else {
276+
printInfo( "🥊 Setting up a REST API only ColdBox application" )
277+
printInfo( "👉 You can always add views and layouts later if you change your mind" )
278+
279+
// Router
280+
fileDelete( arguments.directory & "app/config/Router.bx" )
281+
fileCopy( "#variables.settings.templatesPath#/rest/Router.bx", arguments.directory & "app/config/Router.bx" )
282+
// Tests
283+
directoryDelete( arguments.directory & "tests/specs", true )
284+
directoryCopy(
285+
source: "#variables.settings.templatesPath#/rest/specs",
286+
destination: arguments.directory & "tests/specs",
287+
recurse: true,
288+
createPath: true
289+
)
290+
// Configuration
291+
directoryCopy(
292+
source: "#variables.settings.templatesPath#/rest/config/modules",
293+
destination: arguments.directory & "app/config/modules",
294+
recurse: false,
295+
createPath: true
296+
)
297+
// Models
298+
directoryDelete( arguments.directory & "app/models", true )
299+
directoryCopy(
300+
source: "#variables.settings.templatesPath#/rest/models",
301+
destination: arguments.directory & "app/models",
302+
recurse: false,
303+
createPath: true
304+
)
305+
// Handlers
306+
directoryDelete( arguments.directory & "app/handlers", true )
307+
directoryCopy(
308+
source: "#variables.settings.templatesPath#/rest/handlers",
309+
destination: arguments.directory & "app/handlers",
310+
recurse: false,
311+
createPath: true
312+
)
313+
// Api Docs
314+
directoryCopy(
315+
source: "#variables.settings.templatesPath#/rest/apidocs",
316+
destination: arguments.directory & "resources/apidocs",
317+
recurse: true,
318+
createPath: true
319+
)
320+
var newConfig = fileRead( arguments.directory & "app/config/Coldbox.bx" )
321+
.replace( "Main.index", "Echo.index" )
322+
.replace( "Main.onException", "Echo.onError" );
323+
fileWrite( "app/config/Coldbox.bx", newConfig );
324+
325+
// Install CommandBox Modules
326+
printInfo( "🥊 Installing ColdBox API Production Modules: Security, Mementifier, Validation" )
327+
command( "install" )
328+
.params( "cbsecurity,mementifier,cbvalidation" )
329+
.run();
330+
331+
printInfo( "🥊 Installing ColdBox API Development Modules: route-visualizer,relax" )
332+
command( "install" )
333+
.params( "cbsecurity,mementifier,cbvalidation", "--saveDev" )
334+
.run();
335+
336+
printInfo( "✅ REST API only setup complete!" )
337+
}
170338
}
339+
340+
// Finalize Create app Job
341+
job.complete();
342+
343+
variables.print
344+
.line( "🥊 Your ColdBox BoxLang application is ready to roll!" )
345+
.line( "👉 Run 'box server start' to launch the development server." )
346+
.line( "👉 Run 'box coldbox help' to see a list of available commands from the ColdBox CLI" )
347+
.line( "ℹ️. You can remove the [Setup.bx] file from your project now or keep it for future reference." )
348+
.line( "🗳️ Happy coding!" )
349+
.toConsole();
171350
}
172351

173352
/**

0 commit comments

Comments
 (0)