kong icon indicating copy to clipboard operation
kong copied to clipboard

Multiple commands sharing the same positional arguments

Open ylacancellera opened this issue 1 year ago • 3 comments

Hi

Asking because my workaround now brings me too many issues

I currently have

var  CLI struct {
    CommonOption bool

    Cmd1 cmd1 `cmd`
    Cmd2 cmd2 `cmd`
}

type Cmd1 struct {
    Paths []string `arg`
    SpecificOption bool
}

type Cmd2 struct {
    Paths []string `arg`
    OtherSpecificOption bool
}

"Paths" is a required arguments shared by almost all subcommands

Commands:
  list <paths> ...

  ctx <paths> ...

  regex-list

  conflicts <paths> ...

I have tried but never succeeded in putting Paths under "CLI", instead of duplicating it on every subcommand. It would always give panic: can't mix positional arguments and branching arguments on *struct

Is there a solution to put "Paths" under CLI somehow, so that I don't have to do CLI.List.Paths or CLI.Ctx.Path, but instead do something more generic like CLI.Paths ?

Maybe the only subcommands not using Paths could be a blocker ?

Any pointer would be greatly appreciated! Excellent library btw, simple and effective

ylacancellera avatar Jan 24 '24 19:01 ylacancellera

No that's not possible. What would that look like in practice?

alecthomas avatar Jan 24 '24 20:01 alecthomas

Here is the actual code That's the main: https://github.com/percona/percona-toolkit/blob/v3.5.7/src/go/pt-galera-log-explainer/main.go That's a subcommand: https://github.com/percona/percona-toolkit/blob/v3.5.7/src/go/pt-galera-log-explainer/list.go Other subcommand will have "Paths" as well

And in usage it look like pt-galera-log-explainer list --all *.log, pt-galera-log-explainer list --all $(find . -name *.log) or pt-galera-log-explainer conflicts *.log, where --all is only an option for list subcommand, with paths acting as a variadic argument to accept any number of files (that's the goal of this tool)

I guess that's pretty specific, so I understand I can't just do a simple CLI.Paths, but I wonder if there could be a trick by putting "Paths" in its own structure and somehow sharing it between subcommand I just want to avoid a switch on commands to handle every possible paths from every subcommands

That's what I would avoid if possible

	var paths []string
	switch kongcli.Command() {
	case "list":
		paths = CLI.List.Paths
	case "ctx":
		paths = CLI.Ctx.Paths
	case "conflicts":
		paths = CLI.Conflicts.Paths
	}
        // use paths for a common tasks before subcommand execute

ylacancellera avatar Jan 25 '24 09:01 ylacancellera

For the record: not sure if that's a better solution, though it's possible to use

	for _, path := range kongcli.Path {
		if path.Positional != nil && path.Positional.Name == "paths" {
			paths, ok := path.Positional.Target.Interface().([]string)
                        ....
                }
        }

ylacancellera avatar Feb 09 '24 10:02 ylacancellera