f64f7fa04e
Clone commands before wrapping Before hooks, export ErrLifecycleNotInContext and ErrNoDependencies, add Run helper, split command.go and deps.go. Co-authored-by: Cursor <cursoragent@cursor.com>
50 lines
1.4 KiB
Markdown
50 lines
1.4 KiB
Markdown
# appcli
|
|
|
|
Bridge between [urfave/cli/v3](https://github.com/urfave/cli/v3) and [app](https://gitea.auvem.com/go-toolkit/app) lifecycles.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
go get gitea.auvem.com/go-toolkit/appcli
|
|
```
|
|
|
|
## Example
|
|
|
|
```go
|
|
func main() {
|
|
lc := app.NewLifecycle()
|
|
defer lc.Teardown()
|
|
|
|
root := appcli.NewRootCommand(&cli.Command{
|
|
Name: "myapp",
|
|
Usage: "My application",
|
|
Commands: []*cli.Command{
|
|
appcli.NewCommand(&cli.Command{
|
|
Name: "serve",
|
|
Usage: "Run the server",
|
|
Action: func(ctx context.Context, c *cli.Command) error {
|
|
// modules already loaded via DepFn
|
|
return nil
|
|
},
|
|
}, func(l *app.Lifecycle, c *cli.Command) ([]*app.Module, error) {
|
|
return []*app.Module{myModule}, nil
|
|
}),
|
|
},
|
|
})
|
|
|
|
if err := appcli.Run(context.Background(), lc, root, os.Args); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
```
|
|
|
|
## NewRootCommand vs NewCommand
|
|
|
|
- `NewRootCommand` adds global `--verbose` / `-v` (unless already defined)
|
|
- Both wrap `Before` to call `lifecycle.Require` with modules from `DepFn`
|
|
- Wrapped commands are copied; the original `*cli.Command` is not mutated
|
|
|
|
## DepFn
|
|
|
|
The `*cli.Command` argument is the command whose `Before` hook is running. For nested commands, parent hooks receive the parent command; use `VerboseFromCommand` to read root flags from subcommands.
|