permit exception handling and help fuckery
This commit is contained in:
parent
087a978a8c
commit
424ae202cd
@ -27,9 +27,7 @@ func newCobraRoot(root *command.Command) *cobra.Command {
|
||||
SilenceErrors: true,
|
||||
ValidArgs: []string{""},
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
err := cobra.OnlyValidArgs(cmd, args)
|
||||
if err != nil {
|
||||
|
||||
if err := cobra.OnlyValidArgs(cmd, args); err != nil {
|
||||
suggestions := []string{}
|
||||
bold := color.New(color.Bold)
|
||||
for _, l := range cmd.SuggestionsFor(args[len(args)-1]) {
|
||||
|
@ -20,6 +20,8 @@ import (
|
||||
// ContextKeyRuntimeIndex is the string key used to store context in a cobra Command.
|
||||
const ContextKeyRuntimeIndex = "x-chinampa-runtime-index"
|
||||
|
||||
var ErrorHandler = errors.HandleCobraExit
|
||||
|
||||
var log = logrus.WithField("chinampa", "registry")
|
||||
|
||||
var registry = &CommandRegistry{
|
||||
@ -66,7 +68,6 @@ func Execute(version string) error {
|
||||
ccRoot.Annotations["version"] = version
|
||||
ccRoot.CompletionOptions.HiddenDefaultCmd = true
|
||||
ccRoot.PersistentFlags().AddFlagSet(cmdRoot.FlagSet())
|
||||
ccRoot.SetHelpCommand(commands.Help)
|
||||
ccRoot.AddCommand(commands.Version)
|
||||
ccRoot.AddCommand(commands.GenerateCompletions)
|
||||
|
||||
@ -91,6 +92,11 @@ func Execute(version string) error {
|
||||
|
||||
query := []string{cp}
|
||||
found := false
|
||||
if len(query) == 1 && query[0] == "help" {
|
||||
container = commands.Help
|
||||
continue
|
||||
}
|
||||
|
||||
for _, sub := range container.Commands() {
|
||||
if sub.Name() == cp {
|
||||
container = sub
|
||||
@ -132,6 +138,9 @@ func Execute(version string) error {
|
||||
ValidArgs: []string{""},
|
||||
RunE: func(cc *cobra.Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
if cc.Name() == "help" {
|
||||
return cc.Help()
|
||||
}
|
||||
return errors.NotFound{Msg: "No subcommand provided", Group: []string{}}
|
||||
}
|
||||
os.Exit(statuscode.NotFound)
|
||||
@ -157,6 +166,7 @@ func Execute(version string) error {
|
||||
cmd.Path = append(cmdRoot.Path, cmd.Path...)
|
||||
}
|
||||
cmdRoot.SetCobra(ccRoot)
|
||||
ccRoot.SetHelpCommand(commands.Help)
|
||||
|
||||
current, remaining, err := ccRoot.Find(os.Args[1:])
|
||||
if err != nil {
|
||||
@ -169,11 +179,6 @@ func Execute(version string) error {
|
||||
current = sub
|
||||
}
|
||||
log.Debugf("exec: calling %s", current.CommandPath())
|
||||
err = current.Execute()
|
||||
if err != nil {
|
||||
log.Debugf("exec: error calling %s, %s", current.CommandPath(), err)
|
||||
errors.HandleCobraExit(current, err)
|
||||
}
|
||||
|
||||
return err
|
||||
return ErrorHandler(current, current.Execute())
|
||||
}
|
||||
|
5
main.go
5
main.go
@ -6,6 +6,7 @@ import (
|
||||
"git.rob.mx/nidito/chinampa/internal/registry"
|
||||
"git.rob.mx/nidito/chinampa/pkg/command"
|
||||
"git.rob.mx/nidito/chinampa/pkg/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func Register(cmds ...*command.Command) {
|
||||
@ -21,6 +22,10 @@ type Config struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
func SetErrorHandler(handlerFunc func(cmd *cobra.Command, err error) error) {
|
||||
registry.ErrorHandler = handlerFunc
|
||||
}
|
||||
|
||||
func Execute(config Config) error {
|
||||
runtime.Executable = config.Name
|
||||
command.Root.Summary = config.Summary
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.rob.mx/nidito/chinampa/pkg/errors"
|
||||
"git.rob.mx/nidito/chinampa/pkg/runtime"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
@ -145,11 +144,7 @@ func (cmd *Command) Run(cc *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err := cmd.Action(cmd)
|
||||
if err != nil {
|
||||
errors.HandleCobraExit(cmd.Cobra, err)
|
||||
}
|
||||
return err
|
||||
return cmd.Action(cmd)
|
||||
}
|
||||
|
||||
func (cmd *Command) SetCobra(cc *cobra.Command) {
|
||||
|
@ -122,7 +122,6 @@ func (vs *ValueSource) Resolve(currentValue string) (values []string, flag cobra
|
||||
err = ctx.Err()
|
||||
return
|
||||
}
|
||||
|
||||
case vs.Command != nil:
|
||||
if vs.command == nil {
|
||||
return nil, cobra.ShellCompDirectiveError, fmt.Errorf("bug: command is nil")
|
||||
@ -168,7 +167,7 @@ func (vs *ValueSource) Resolve(currentValue string) (values []string, flag cobra
|
||||
return nil, flag, err
|
||||
}
|
||||
default:
|
||||
return nil, flag, fmt.Errorf("Empty value source")
|
||||
return nil, flag, fmt.Errorf("empty value source")
|
||||
}
|
||||
|
||||
vs.computed = &values
|
||||
@ -242,7 +241,6 @@ func (vs *ValueSource) UnmarshalYAML(node *yaml.Node) error {
|
||||
}
|
||||
|
||||
if t, ok := intermediate["timeout"]; ok {
|
||||
|
||||
if err := t.Decode(&vs.Timeout); err != nil {
|
||||
logrus.Errorf("could not decode timeout: %s", err)
|
||||
return err
|
||||
|
1
pkg/env/env.go
vendored
1
pkg/env/env.go
vendored
@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
package env
|
||||
|
||||
// Environment Variables.
|
||||
var HelpUnstyled = "HELP_STYLE_PLAIN"
|
||||
var HelpStyle = "HELP_STYLE"
|
||||
var Verbose = "VERBOSE"
|
||||
|
@ -2,8 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
package errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type NotFound struct {
|
||||
Msg string
|
||||
Group []string
|
||||
@ -13,24 +11,6 @@ type BadArguments struct {
|
||||
Msg string
|
||||
}
|
||||
|
||||
type NotExecutable struct {
|
||||
Msg string
|
||||
}
|
||||
|
||||
type ConfigError struct {
|
||||
Err error
|
||||
Config string
|
||||
}
|
||||
|
||||
type EnvironmentError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
type SubCommandExit struct {
|
||||
Err error
|
||||
ExitCode int
|
||||
}
|
||||
|
||||
func (err NotFound) Error() string {
|
||||
return err.Msg
|
||||
}
|
||||
@ -38,23 +18,3 @@ func (err NotFound) Error() string {
|
||||
func (err BadArguments) Error() string {
|
||||
return err.Msg
|
||||
}
|
||||
|
||||
func (err NotExecutable) Error() string {
|
||||
return err.Msg
|
||||
}
|
||||
|
||||
func (err SubCommandExit) Error() string {
|
||||
if err.Err != nil {
|
||||
return err.Err.Error()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (err ConfigError) Error() string {
|
||||
return fmt.Sprintf("Invalid configuration %s: %v", err.Config, err.Err)
|
||||
}
|
||||
|
||||
func (err EnvironmentError) Error() string {
|
||||
return fmt.Sprintf("Invalid MILPA_ environment: %v", err.Err)
|
||||
}
|
||||
|
@ -22,20 +22,17 @@ func showHelp(cmd *cobra.Command) {
|
||||
}
|
||||
}
|
||||
|
||||
func HandleCobraExit(cmd *cobra.Command, err error) {
|
||||
func HandleCobraExit(cmd *cobra.Command, err error) error {
|
||||
if err == nil {
|
||||
ok, err := cmd.Flags().GetBool(_c.HelpCommandName)
|
||||
ok, err := cmd.PersistentFlags().GetBool(_c.HelpCommandName)
|
||||
if cmd.Name() == _c.HelpCommandName || err == nil && ok {
|
||||
os.Exit(statuscode.RenderHelp)
|
||||
}
|
||||
|
||||
os.Exit(42)
|
||||
os.Exit(statuscode.Ok)
|
||||
}
|
||||
|
||||
switch tErr := err.(type) {
|
||||
case SubCommandExit:
|
||||
logrus.Debugf("Sub-command failed with: %s", err.Error())
|
||||
os.Exit(tErr.ExitCode)
|
||||
switch err.(type) {
|
||||
case BadArguments:
|
||||
showHelp(cmd)
|
||||
logrus.Error(err)
|
||||
@ -44,13 +41,6 @@ func HandleCobraExit(cmd *cobra.Command, err error) {
|
||||
showHelp(cmd)
|
||||
logrus.Error(err)
|
||||
os.Exit(statuscode.NotFound)
|
||||
case ConfigError:
|
||||
showHelp(cmd)
|
||||
logrus.Error(err)
|
||||
os.Exit(statuscode.ConfigError)
|
||||
case EnvironmentError:
|
||||
logrus.Error(err)
|
||||
os.Exit(statuscode.ConfigError)
|
||||
default:
|
||||
if strings.HasPrefix(err.Error(), "unknown command") {
|
||||
showHelp(cmd)
|
||||
@ -64,4 +54,5 @@ func HandleCobraExit(cmd *cobra.Command, err error) {
|
||||
|
||||
logrus.Errorf("Unknown error: %s", err)
|
||||
os.Exit(2)
|
||||
return err
|
||||
}
|
||||
|
@ -132,7 +132,6 @@ func TestSilent(t *testing.T) {
|
||||
t.Fail()
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestEnvironmentMapEnabled(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user