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

**Terrible CLI Library** Both v2/v3 have serious bugs #2066

Open
System233 opened this issue Feb 27, 2025 · 5 comments
Open

**Terrible CLI Library** Both v2/v3 have serious bugs #2066

System233 opened this issue Feb 27, 2025 · 5 comments
Assignees
Labels
area/v2 relates to / is being considered for v2 area/v3 relates to / is being considered for v3 kind/question someone asking a question status/triage maintainers still need to look into this

Comments

@System233
Copy link

The v3 version fails to properly recognize the -- terminator, making it completely unusable in my use case.
Related: #1114 (unresolved) ,#1562 (useless, insane patch) ...

The v2 version can handle the terminator correctly, but it cannot disable the comma-splitting behavior of StringSliceFlag, and cli.separatorSpec is not exported, making all features related to separatorSpec (like WithSeparatorSpec) unavailable.
Related: #1856 ,#1552 (should never happen) , #1878, #1541 ...

The above issues are just what I found, there are definitely more than these

These are all known issues, but they were closed without being fixed.

Additionally, there are weird functions like cli.Args().Slice(), Args().Tail(), etc., and I can only guess their functionality based on their output.

Since I couldn't resolve these issues, I switched to Cobra. I'm just posting this to vent.
Simply changing the command parsing part from urfave/cli to cobra, my binary size dropped from 12MB to 5MB, which is incredible.
Although Cobra’s API isn’t as pleasant to write as urfave/cli, at least it doesn’t have serious bugs and can handle basic command parsing.

Sorry for raising this issue, please feel free to close

@System233 System233 added area/v2 relates to / is being considered for v2 kind/question someone asking a question status/triage maintainers still need to look into this labels Feb 27, 2025
@dearchap dearchap added the area/v3 relates to / is being considered for v3 label Feb 27, 2025
@dearchap dearchap self-assigned this Feb 27, 2025
@dereknola
Copy link

dereknola commented Feb 28, 2025

This is a very real problem and something that is holding my company from moving off urfavecli/v1. We need to be able to handle custom separators for StringSliceFlag We pass a flag like --extra-stuff="a,b c,d" and want it to parse the values as ["a,b", "c,d"].

@dearchap
Copy link
Contributor

dearchap commented Mar 1, 2025

@System233 @dereknola Thank you for your feedback. Here is a sample code I whipped up with the publicly released version of v3

package main

import (
	"context"
	"log"
	"os"

	"github.com/urfave/cli/v3"
)

func main() {
	cmd := &cli.Command{
		Name: "foo",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "jel",
			},
		},
		Commands: []*cli.Command{
			{
				Name:               "bar",
				SliceFlagSeparator: " ",
				Flags: []cli.Flag{
					&cli.StringSliceFlag{
						Name: "tt",
					},
				},
				Action: func(ctx context.Context, c *cli.Command) error {
					ss := c.StringSlice("tt")
					log.Printf("%d %+v", len(ss), ss)
					return nil
				},
			},
			{
				Name:            "tar",
				SkipFlagParsing: true,
				Action: func(ctx context.Context, c *cli.Command) error {
					log.Printf("%d %v", c.NArg(), c.Args())
					return nil
				},
			},
		},
	}

	_ = cmd.Run(context.Background(), os.Args)
}

Here are some outputs.

This first one is for slice flag separation

$ go run . bar --tt "hello,edd dd,ff" --tt "d,x" --tt "a b"
2025/02/28 19:05:33 5 [hello,edd dd,ff d,x a b]

This is for skipping flag parsing.

$ go run . tar -- hello 0ff 
2025/02/28 19:07:54 3 &{[-- hello 0ff]}
$ go run . tar junk -- hello 0ff 
2025/02/28 19:11:38 4 &{[junk -- hello 0ff]}

@System233
Copy link
Author

@System233 @dereknola Thank you for your feedback. Here is a sample code I whipped up with the publicly released version of v3

code
package main

import (
	"context"
	"log"
	"os"

	"github.com/urfave/cli/v3"
)

func main() {
	cmd := &cli.Command{
		Name: "foo",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name: "jel",
			},
		},
		Commands: []*cli.Command{
			{
				Name:               "bar",
				SliceFlagSeparator: " ",
				Flags: []cli.Flag{
					&cli.StringSliceFlag{
						Name: "tt",
					},
				},
				Action: func(ctx context.Context, c *cli.Command) error {
					ss := c.StringSlice("tt")
					log.Printf("%d %+v", len(ss), ss)
					return nil
				},
			},
			{
				Name:            "tar",
 				SkipFlagParsing: true,
				Action: func(ctx context.Context, c *cli.Command) error {
					log.Printf("%d %v", c.NArg(), c.Args())
					return nil
				},
			},
		},
	}

	_ = cmd.Run(context.Background(), os.Args)
}

Here are some outputs.

This first one is for slice flag separation

$ go run . bar --tt "hello,edd dd,ff" --tt "d,x" --tt "a b"
2025/02/28 19:05:33 5 [hello,edd dd,ff d,x a b]

This is for skipping flag parsing.

$ go run . tar -- hello 0ff 
2025/02/28 19:07:54 3 &{[-- hello 0ff]}
$ go run . tar junk -- hello 0ff 
2025/02/28 19:11:38 4 &{[junk -- hello 0ff]}

SkipFlagParsing is completely useless. The CLI should stop parsing when encountering "--", not ignore all arguments entirely.

$ go run . tar -e --should-fail -- fawf
2025/03/01 08:34:01 4 &{[-e --should-fail -- fawf]}

Removed SkipFlagParsing and added c.Args().Slice(), c.Args().Tail():

	{
		Name: "tar",
		// SkipFlagParsing: true,
		Action: func(ctx context.Context, c *cli.Command) error {
			log.Println(c.NArg(), c.Args(), c.Args().Slice(), c.Args().Tail())
			return nil
		},
	},

In v2, I could correctly retrieve the arguments after "--" using c.Args().Tail(). However, in v3, using c.Args().Tail() to get arguments is an absolute disaster.

$ go run . tar   -- fawf jhu
2025/03/01 08:34:58 3 &{[-- fawf jhu]} [-- fawf jhu] [fawf jhu]
$ go run . tar  fawf jhu
2025/03/01 08:35:02 2 &{[fawf jhu]} [fawf jhu] [jhu]
$ go run . tar  fawf -- jhu
2025/03/01 08:35:14 3 &{[fawf -- jhu]} [fawf -- jhu] [-- jhu]

@System233
Copy link
Author

This is a very real problem and something that is holding my company from moving off urfavecli/v1. We need to be able to handle custom separators for StringSliceFlag We pass a flag like --extra-stuff="a,b c,d" and want it to parse the values as ["a,b", "c,d"].

The documentation states that v1 should no longer be used for any new development, so I switched to v2. When I encountered bugs in v2, I looked for patches in the issues and pull requests, only to discover that bug fixes for v2 were treated as new features. Since v2 is in maintenance-only mode, patches for v2 were rejected, with comments recommending v3 for development instead.

However, v3 is still in alpha and hasn’t even had a proper release. On top of that, it introduces new bugs. This is incredibly frustrating—going back and forth like this is a complete waste of time, and that’s why I’m so angry.

I can't manually remove "--" from the arguments in my own code because I have no idea when this issue will be fixed. If it ever gets fixed, my workaround would turn into a new bug. I don’t want to write this kind of Schrödinger’s code.

@dearchap
Copy link
Contributor

dearchap commented Mar 1, 2025

@System233 The SkipFlagParsing skips parsing any arguments for the entire command whether it has a "--" or not. yes it would be desirable to have the parser stop at "--" but if you have looked at all the issues in v2, you can see we made multiple attempts but we have no appetite to change the entire parser thus the SkipFlagParsing was added as a workaround. We were amenable to changing this in v3 with the addition of a new parser but that went nowhere(the people who were working on it ran into some other issues) so we stuck to the golang flag parser. For the most part we are trying to maintain backward compatibility where possible or where user expectations might have to change dramatically. I can sympathize with your anger however we have limited resources, where one or two people contribute somewhat regularly. We can take your comments and improve this library more. In the meantime I'm sorry this library isnt working for you. I;m going to keep this issue open to remind the maintainers of the work ahead of us. Thanks for your time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/v2 relates to / is being considered for v2 area/v3 relates to / is being considered for v3 kind/question someone asking a question status/triage maintainers still need to look into this
Projects
None yet
Development

No branches or pull requests

3 participants