57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
|
package cmd
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
"git.iamthefij.com/iamthefij/slog"
|
||
|
"github.com/spf13/cobra"
|
||
|
"github.com/spf13/viper"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
ErrMissingArgument = errors.New("missing positional argument")
|
||
|
ErrTooManyRequiredArgs = errors.New("more args specified as required than provided")
|
||
|
)
|
||
|
|
||
|
func bindFlag(flagname string) {
|
||
|
slog.OnErrFatalf(
|
||
|
viper.BindPFlag(flagname, rootCmd.PersistentFlags().Lookup(flagname)),
|
||
|
"failed binding flag: "+flagname,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
func WrapPositionalArgs(cmd *cobra.Command, positionalArgs []string, numRequired int) *cobra.Command {
|
||
|
// TODO: Find a better place for this validation
|
||
|
if numRequired > len(positionalArgs) {
|
||
|
panic(ErrTooManyRequiredArgs)
|
||
|
}
|
||
|
|
||
|
// Add required args to Use
|
||
|
if numRequired > 0 {
|
||
|
cmd.Use = fmt.Sprintf("%s <%s>", cmd.Use, strings.Join(positionalArgs[0:numRequired], "> <"))
|
||
|
}
|
||
|
// Add optional args to Use
|
||
|
optionalArgs := positionalArgs[numRequired:]
|
||
|
if len(optionalArgs) > 0 {
|
||
|
cmd.Use = fmt.Sprintf("%s [%s]", cmd.Use, strings.Join(optionalArgs, "] ["))
|
||
|
}
|
||
|
|
||
|
oldArgs := cmd.Args
|
||
|
cmd.Args = func(cmd *cobra.Command, args []string) error {
|
||
|
lastArgPos := len(args)
|
||
|
if lastArgPos < numRequired {
|
||
|
return fmt.Errorf("missing argument `%s` in position %d: %w", positionalArgs[lastArgPos], lastArgPos, ErrMissingArgument)
|
||
|
}
|
||
|
|
||
|
if oldArgs != nil {
|
||
|
return oldArgs(cmd, args)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return cmd
|
||
|
}
|