end f64f7fa04e fix: copy-on-wrap commands and typed errors
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>
2026-06-29 18:04:07 -07:00
2026-01-27 15:07:49 -08:00

appcli

Bridge between urfave/cli/v3 and app lifecycles.

Install

go get gitea.auvem.com/go-toolkit/appcli

Example

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.

S
Description
appcli provides boilerplate dependency handling for command line apps based on urfave/cli.
Readme BSD-3-Clause 36 KiB
Languages
Go 100%