@@ -22,15 +22,28 @@ import (
2222)
2323
2424func main () {
25- app := forge.New (
26- forge.WithAppName ( " my-app " ),
27- forge.WithAppVersion ( " 1.0.0 " ),
28- )
29-
30- cli. RunApp (app )
25+ cli. RunApp ( func (ctx cli. CommandContext ) ( forge.App , error ) {
26+ return forge.New (
27+ forge.WithAppName ( " my-app " ),
28+ forge. WithAppVersion ( " 1.0.0 " ),
29+ ), nil
30+ } )
3131}
3232```
3333
34+ ` RunApp ` takes a setup closure instead of a pre-built app. The closure receives a ` CommandContext ` with access to parsed CLI flags, so you can use flag values to configure your app:
35+
36+ ``` go
37+ cli.RunApp (func (ctx cli .CommandContext ) (forge .App , error ) {
38+ return forge.New (
39+ forge.WithAppName (" my-app" ),
40+ forge.WithHTTPAddress (" :" +ctx.String (" port" )),
41+ ), nil
42+ },
43+ cli.WithGlobalFlags (cli.NewStringFlag (" port" , " p" , " HTTP port" , " 8080" )),
44+ )
45+ ```
46+
3447This gives you a fully functional CLI:
3548
3649``` bash
@@ -76,15 +89,33 @@ Configure `RunApp` behavior with functional options:
7689Runs pending migrations before the HTTP server starts listening (during ` PhaseBeforeRun ` ). Migrations run after all extensions are initialized but before the app accepts requests.
7790
7891``` go
79- cli.RunApp (app, cli.WithAutoMigrate ())
92+ cli.RunApp (appSetup, cli.WithAutoMigrate ())
93+ ```
94+
95+ ### WithGlobalFlags
96+
97+ Add flags available to all commands and the setup closure. These flags are parsed before the setup closure runs, so you can use ` ctx.String("flag") ` , ` ctx.Int("flag") ` , etc. inside it:
98+
99+ ``` go
100+ cli.RunApp (func (ctx cli .CommandContext ) (forge .App , error ) {
101+ return forge.New (
102+ forge.WithAppName (" my-app" ),
103+ forge.WithHTTPAddress (" :" +ctx.String (" port" )),
104+ ), nil
105+ },
106+ cli.WithGlobalFlags (
107+ cli.NewStringFlag (" port" , " p" , " HTTP port" , " 8080" ),
108+ cli.NewStringFlag (" env" , " e" , " Environment" , " development" ),
109+ ),
110+ )
80111```
81112
82113### WithExtraCommands
83114
84115Add custom commands alongside the built-in ones:
85116
86117``` go
87- cli.RunApp (app ,
118+ cli.RunApp (appSetup ,
88119 cli.WithExtraCommands (
89120 cli.NewCommand (" seed" , " Seed the database" , handleSeed),
90121 cli.NewCommand (" reindex" , " Rebuild search index" , handleReindex),
@@ -97,23 +128,23 @@ cli.RunApp(app,
97128Disable auto-registration of ` migrate ` commands even when ` MigratableExtension ` extensions are present:
98129
99130``` go
100- cli.RunApp (app , cli.WithDisableMigrationCommands ())
131+ cli.RunApp (appSetup , cli.WithDisableMigrationCommands ())
101132```
102133
103134### WithDisableServeCommand
104135
105136Disable the built-in ` serve ` command (useful for CLI-only tools):
106137
107138``` go
108- cli.RunApp (app , cli.WithDisableServeCommand ())
139+ cli.RunApp (appSetup , cli.WithDisableServeCommand ())
109140```
110141
111142### WithCLIName / WithCLIVersion / WithCLIDescription
112143
113144Override the CLI metadata (defaults to the Forge app's name and version):
114145
115146``` go
116- cli.RunApp (app ,
147+ cli.RunApp (appSetup ,
117148 cli.WithCLIName (" myctl" ),
118149 cli.WithCLIVersion (" 2.0.0" ),
119150 cli.WithCLIDescription (" MyApp management CLI" ),
@@ -131,13 +162,14 @@ When `WithAutoMigrate()` is enabled, the serve command registers a `PhaseBeforeR
131162
132163``` go
133164func main () {
134- app := forge.New (
135- forge.WithAppName (" my-app" ),
136- forge.WithExtensions (groveExt),
165+ cli.RunApp (func (ctx cli.CommandContext ) (forge.App , error ) {
166+ return forge.New (
167+ forge.WithAppName (" my-app" ),
168+ forge.WithExtensions (groveExt),
169+ ), nil
170+ },
171+ cli.WithAutoMigrate (),
137172 )
138-
139- // Migrations run automatically before HTTP server starts
140- cli.RunApp (app, cli.WithAutoMigrate ())
141173}
142174```
143175
@@ -213,6 +245,44 @@ grove Migrations (grove v0.12.0):
213245 └────────────────┴──────────────────┴─────────┴──────────────────────┘
214246```
215247
248+ ## Builder Pattern: NewAppRunner
249+
250+ For more complex setups, use ` NewAppRunner ` with method chaining:
251+
252+ ``` go
253+ func main () {
254+ cli.NewAppRunner (func (ctx cli.CommandContext ) (forge.App , error ) {
255+ return forge.New (
256+ forge.WithAppName (" my-app" ),
257+ forge.WithHTTPAddress (" :" +ctx.String (" port" )),
258+ ), nil
259+ }).
260+ Name (" my-app" ).
261+ Version (" 1.0.0" ).
262+ AutoMigrate ().
263+ WithGlobalFlags (cli.NewStringFlag (" port" , " p" , " HTTP port" , " 8080" )).
264+ WithExtraCommands (
265+ cli.NewCommand (" seed" , " Seed test data" , handleSeed),
266+ ).
267+ Run ()
268+ }
269+ ```
270+
271+ ` NewAppRunner ` returns an ` *AppRunner ` with the following methods:
272+
273+ | Method | Description |
274+ | --------| -------------|
275+ | ` Name(string) ` | Set CLI application name |
276+ | ` Version(string) ` | Set CLI application version |
277+ | ` Description(string) ` | Set CLI application description |
278+ | ` AutoMigrate() ` | Run migrations before serve |
279+ | ` WithGlobalFlags(...Flag) ` | Add flags available to all commands |
280+ | ` WithExtraCommands(...Command) ` | Add custom commands |
281+ | ` DisableMigrationCommands() ` | Hide migrate commands |
282+ | ` DisableServeCommand() ` | Hide serve command |
283+ | ` Run() ` | Build and execute the CLI (exits process) |
284+ | ` Execute() ` | Build and execute, returning errors (useful for testing) |
285+
216286## Complete Example
217287
218288``` go
@@ -230,19 +300,22 @@ import (
230300)
231301
232302func main () {
233- grove := groveext. New (
234- groveext.WithDSN ( " postgres://localhost:5432/myapp " ),
235- groveext.WithMigrations (core. Migrations , billing. Migrations ),
236- )
237-
238- app := forge. New (
239- forge.WithAppName ( " myapp " ),
240- forge.WithAppVersion ( " 1.0.0 " ),
241- forge.WithExtensions (grove ),
242- )
243-
244- cli. RunApp (app ,
303+ cli. RunApp ( func (ctx cli. CommandContext ) (forge. App , error ) {
304+ grove := groveext.New (
305+ groveext.WithDSN (ctx. String ( " dsn " ) ),
306+ groveext. WithMigrations (core. Migrations , billing. Migrations ),
307+ )
308+
309+ return forge.New (
310+ forge.WithAppName ( " myapp " ),
311+ forge.WithAppVersion ( " 1.0.0 " ),
312+ forge. WithExtensions (grove),
313+ ), nil
314+ } ,
245315 cli.WithAutoMigrate (),
316+ cli.WithGlobalFlags (
317+ cli.NewStringFlag (" dsn" , " d" , " Database connection string" , " postgres://localhost:5432/myapp" ),
318+ ),
246319 cli.WithExtraCommands (
247320 cli.NewCommand (" seed" , " Seed test data" , handleSeed),
248321 ),
0 commit comments