97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package appcli
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"gitea.auvem.com/go-toolkit/app"
|
|
"github.com/urfave/cli/v3"
|
|
)
|
|
|
|
// DepFn is a function type that returns a slice of dependencies.
|
|
type DepFn func(*app.Lifecycle, *cli.Command) ([]*app.Module, error)
|
|
|
|
// DepList is a convenience function that returns a DepFn that uses a
|
|
// predefined list of dependecies.
|
|
func DepList(deps ...*app.Module) DepFn {
|
|
return func(_ *app.Lifecycle, _ *cli.Command) ([]*app.Module, error) {
|
|
if len(deps) == 0 {
|
|
return nil, errors.New("no dependencies provided")
|
|
}
|
|
return deps, nil
|
|
}
|
|
}
|
|
|
|
// NewCommand creates a new CLI command with the specified configuration and
|
|
// and dependencies. Returns a standard *cli.Command that can be used directly
|
|
// with urfave/cli/v3 types. If any dependencies are provided, the Before method
|
|
// is overriden to ensure that all dependencies are satisfied before the command
|
|
// is executed. Requires an app.Lifecycle to be present in the context when the
|
|
// command is executed.
|
|
func NewCommand(cmdcfg *cli.Command, depfn ...DepFn) *cli.Command {
|
|
if len(depfn) == 0 {
|
|
return cmdcfg
|
|
}
|
|
|
|
// Override the Before method to handle dependencies
|
|
originalBefore := cmdcfg.Before
|
|
cmdcfg.Before = func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
|
|
if originalBefore != nil {
|
|
var err error
|
|
ctx, err = originalBefore(ctx, cmd)
|
|
if err != nil {
|
|
return ctx, err
|
|
}
|
|
}
|
|
|
|
lifecycle := app.LifecycleFromContext(ctx)
|
|
if lifecycle == nil {
|
|
return ctx, errors.New("lifecycle not found in context, cannot run command with dependencies")
|
|
}
|
|
|
|
deps := make([]*app.Module, 0)
|
|
for _, fn := range depfn {
|
|
if fn == nil {
|
|
continue
|
|
}
|
|
|
|
modules, err := fn(lifecycle, cmd)
|
|
if err != nil {
|
|
return ctx, err
|
|
}
|
|
deps = append(deps, modules...)
|
|
}
|
|
|
|
if len(deps) > 0 {
|
|
if err := lifecycle.Require(deps...); err != nil {
|
|
return ctx, err
|
|
}
|
|
}
|
|
|
|
return ctx, nil
|
|
}
|
|
|
|
return cmdcfg
|
|
}
|
|
|
|
// NewRootCommand creates a new root CLI command with the specified configuration.
|
|
// Adds verbose flag and override Before and After methods to handle dependencies.
|
|
// See NewCommand for more details.
|
|
func NewRootCommand(cmdcfg *cli.Command, depfn ...DepFn) *cli.Command {
|
|
cmdcfg.Flags = append(cmdcfg.Flags, &cli.BoolFlag{
|
|
Name: "verbose",
|
|
Aliases: []string{"v"},
|
|
Usage: "Enable verbose output",
|
|
})
|
|
return NewCommand(cmdcfg, depfn...)
|
|
}
|
|
|
|
// VerboseFromCommand checks if the verbose flag is set in the command context.
|
|
func VerboseFromCommand(cmd *cli.Command) bool {
|
|
if cmd == nil {
|
|
return false
|
|
}
|
|
|
|
return cmd.Bool("verbose")
|
|
}
|