5

I looked for some similar problems but I couldn't find anything except this: https://github.com/spf13/cobra/issues/1025

My problem is about inserting some string which contains a dash at the beginning like the following example,

go run myapp exampleCmd set "-Dexample"

Cobra seems to take the input -Dexample as internal parameter because returns this output:

Error: unknown shorthand flag: 'D' in -Dexample
Usage:
  myapp exampleCmd set [flags]

Flags:
  -h, --help   help for set

Global Flags:
  -s, --set string       Set exampleCmd parameters. (default "default_param")

my init() function contains these two lines:

func init() {
    ...
    exampleCmd.PersistentFlags().StringP("set", "s", defaultArgument, "Set parameters.")
    exampleCmd.AddCommand(setCmd)
    ...
}

var exampleCmd = &cobra.Command{
    Use:   "set",
    Short: "set parameter",
    Long:  `set parameter`,
    RunE: func(cmd *cobra.Command, args []string) error {
        if len(args) != 1 && len(args) != 0 {
            color.Red("Wrong usage, insert just a parameter")
        } else if len(args) == 0 {
            color.Yellow("Setting default parameter: " + defaultArgument)
            internal.SetParams(defaultArgument)
        } else {
            internal.SetParams(args[0])
        }
        return nil
    },
}

How can I accept parameters with dashes at beginning with cobra, if exists any solution?

Fulvio
  • 87
  • 7

4 Answers4

6

As with virtual all Unix-style command line utilities and flag parsing libraries, Cobra separates flags from arguments with a --, after which no more arguments will be parsed as flags, even if they start with a -.

go run myapp exampleCmd set -- "-Dexample"

This is no different than how you interact with other CLI utilities. For example, rm -i sets the interactive flag, while rm -- -i removes a file named -i.

You definitely do not want to arbitrarily disable flags for certain commands or subcommands which is inconsistent (both within your own app and across all other apps), unnecessary, and breaks basic user expectations: Sometimes, -h will do what the user expects, but for some commands, for reasons the user cannot predict, -h will be treated as an argument and produce unexpected behavior.

Unix has solved this problem for more than 50 years. Let the user decide whether a argument is a flag via --.

user229044
  • 232,980
  • 40
  • 330
  • 338
  • what if the app runs on windows? The app I'm working on is cross platform – Fulvio Nov 28 '21 at 19:51
  • 1
    Then I assume my advice still applies, and either `--` or some other user-supplied input will tell Cobra that no further flag parsing is required. The point is that you don't solve this in code where you're going to produce unpredictable, inconsistent and occasionally just plain **wrong** results. You allow the user to choose. – user229044 Nov 28 '21 at 19:54
-1

Solved using this workaround (if it is)

I added to the end of the &cobra.Command{} this element:

DisableFlagParsing: true,

found here: https://github.com/spf13/cobra/issues/683

Fulvio
  • 87
  • 7
  • 1
    This is a bad solution. It means your subcommand cannot have *any* flags passed to it, which is unexpected for users and completely unnecessary. The real answer is already available in your linked Github issue. Like every other flag parsing library, Cobra uses `--` to indicate you're done with command line flags, as with every other unix CLI utility. For example, if you have a file named `-foo` or `--foo`, you delete it by running `rm -- -foo`, not through editing the `rm` source code to provide for this special case. – user229044 Nov 28 '21 at 19:45
  • I thought it was a bruteforce workaround because the user has to add that two dashes, instead I preferred the DisableFlagParsing because the user does not need to do anything different from other commands, anyway thank you, I will add the double dash to the code documentation and will handle the eventual error – Fulvio Nov 28 '21 at 19:48
  • 1
    Yes, the user is *supposed* to add two dashes. The **user** is supposed to choose how something starting with `-` is interpreted, not you. Now your app is broken, and doesn't work the way all other apps do. Plus, now *no* flags work with your sub command. What if you want to have a flag? What if your user wants to type `myapp xampleCmd set -h`? Suddenly that behaves differently than every other way the user can execute your application. – user229044 Nov 28 '21 at 19:51
  • ok, I understood why it's a bad practice the DisableFlagParsing but now I have a doubt I described in a comment – Fulvio Nov 28 '21 at 19:52
-1

I don't think it is possible to pass an argument beginning with a dash symbol while using an utility like cobra. The dash is a flag indicator and it doesn't matter if it is enclosed in quotes, single dash is read as a shorthand flag, so the first letter of your input is getting interpreted as a flag and unrecognized, thus the program fails (and calls cmd.Help()).

You've set set as both command and a flag (--set -s), so it appears in your --help output.

I would consider using a different character for your command argument or adding it in another way internally.

happyRip
  • 1
  • 1
  • 1
    This answer is wrong. If it were impossible to pass arguments starting with `-`, it would be impossible to `rm` a file called `-foo` under Unix. – user229044 Nov 28 '21 at 20:58
-1

I found the solution in the flagset interspersed option: https://github.com/spf13/cobra/issues/1307#issue-777308697

This says to cobra that other flags after the first are also flags.

Fulvio
  • 87
  • 7