Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide usefull errors when using invalid sub command #1716

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mandelsoft
Copy link

If the TraverseChildren mode is active, the Traverse function returns the last accepted command along the requested sub command chain. This command is then used to parse the arguments. This will for sure fail, if the traversing was aborted because an invalid sub command was given. As a result, cobra complains about invalid flags instead of an invalid sub command.

This behaviour might be useful, if the intermediate command is Runnable(), but it for sure makes no sense, if it isn't.

This PR fixes this by providing a legacyArgs() error in case of not runnable intermediate commands.


Remark: It solves the obvious problematic behaviour, but basically the general scenario is more complex.
If the intermediate command is Runnable() in addition to providing additional sub commands, then it should be possible to forward the control about the error message to the command to be a able to distinguish between these two cases according to its needs. This is basically already possible by declaring a FlagErrorFunc(). But unfortunately it only gets the command and error as arguments, but not the actual set of arguments. Therefore it has no chance to detect the actual problem and provide appropriate error feedback.

Solving this is more invasive, because it would require, either to change the interface, or add another more general error handler option.

@github-actions github-actions bot added the size/XS Denotes a PR that changes 0-9 lines label Jun 2, 2022
@CLAassistant
Copy link

CLAassistant commented Jun 2, 2022

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions bot added size/S Denotes a PR that chanes 10-24 lines and removed size/XS Denotes a PR that changes 0-9 lines labels Aug 7, 2022
@Skarlso
Copy link

Skarlso commented Aug 29, 2022

Hello @marckhouzam :)

Sorry for the ping, just raising visibility. Is there any chance for anyone to review this change? Pretty please? :)

The code is concise and contains a small, but effective fix for a relative obscure behaviour but leaves a really nice error for the user.

@marckhouzam
Copy link
Collaborator

Thanks @mandelsoft. To make the review easier, could you provide a simple test program and the steps to reproduce the problem? Ideally you would open an issue with that information and refer this PR to that issue.

Thank you.

@Skarlso
Copy link

Skarlso commented Sep 9, 2022

Thank you, Marc!

@mandelsoft
Copy link
Author

mandelsoft commented Sep 9, 2022

Hello @marckhouzam, sorry, for the delay. I could open an issue, also, if you want.

The problem can be reproduced with the following program:

package main

import (
	"fmt"

	"github.com/spf13/cobra"
)

var opt string

func main() {
	cmd := &cobra.Command{
		Use:                   "test",
		Short:                 "test program",
		Version:               "v1",
		TraverseChildren:      true,
		SilenceUsage:          true,
		DisableFlagsInUseLine: true,
		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
			return nil
		},
	}

	sub := &cobra.Command{
		Use:                   "sub",
		Short:                 "sub command",
		TraverseChildren:      true,
		SilenceUsage:          true,
		DisableFlagsInUseLine: true,
		RunE: func(cmd *cobra.Command, args []string) error {
			fmt.Printf("option is %q\n", opt)
			return nil
		},
	}
	flagset := sub.Flags()
	flagset.StringVarP(&opt, "opt", "", "", "some option")

	cmd.AddCommand(sub)
	cmd.InitDefaultHelpCmd()
	cmd.Execute()
}

It uses a sub command subwith the option --opt. If run with

$ cmd sub --opt test

It prints the option value.

If called with a misspelled sub command

$ cmd subb --opt test

It provides the following error message:

Error: unknown flag: --opt

This is not directly wrong, but misleading, the problem is not the option, but the misspelled sub command and the main command does not provide a runner (meaning it cannot be executed without a sub command).

With the provided fix, the error output correctly is

Error: unknown command "subb" for "test"

Did you mean this?
        sub

Run 'test --help' for usage.

@Skarlso
Copy link

Skarlso commented Nov 7, 2022

@marckhouzam Hello. :) 👋

Are you happy with the added information? :)

Thanks! 🙏

@Skarlso
Copy link

Skarlso commented Dec 8, 2022

@marckhouzam Hello. :) 👋

Are you happy with the added information? :)

Thanks! 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/S Denotes a PR that chanes 10-24 lines
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants