imap-notes/cmd/utils.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
}