Home > Software engineering >  Is it possible to reuse flags in Go?
Is it possible to reuse flags in Go?

Time:05-06

I'm working on a project and I'm wondering if there is a way to reuse flags while running the command in Go.

Flag should be optional argument for every plugin name as seen below.

command plugin1 --version=1.0 plugin2 --version=1.2 plugin3 plugin4 --version=3.7

Is there a way to implement such behavior? If so, what's the best practice to do it?

CodePudding user response:

Your basic problem is that such command driven CLIs are built hierarchically. For example, docker container rm, container is a subcommand of docker and rm is a subcommand of container. If you project that to your use case, you should quickly see the problem. In your case plugin1 would be a subcommand of command, plugin2 a subcommand of plugin1, plugin3 a subcommand of plugin2 and so on. However, I think you would like to make all these commands subcommands of command directly.

Since you didn't give any details on what you are using to build the CLI, be it the standard library or something like Cobra. So I can't give exact implementation details here, but what you could do is to choose a more appropriate and plugin specific flag instead of the generic name version. Then you could share the version directly to this flag.

So for example:

command --plugin1=1.0 --plugin2=1.2 --plugin3 --plugin4=3.7

The problem is, of course, that the plugin itself is no longer a command, so it's hard to specify other plugin-specific flags. Whether this works for your case, only you can know.

CodePudding user response:

You can manually parse the os.Args slice, something like this:

//plugin1 --version=1.0 plugin2 --version=1.2 plugin3 plugin4 --version=3.7
plugins := make(map[string]string)
lastPlugins := make([]string, 0)

if len(os.Args) > 0 {
    for i := 1; i < len(os.Args); i   {
        if strings.HasPrefix(os.Args[i], "--version=") {
            if len(lastPlugins) == 0 {
                log.Fatal("No plugin provided for "   os.Args[i])
            }
            version := strings.TrimPrefix(os.Args[i], "--version=")
            for _, p := range lastPlugins {
                plugins[p] = version
            }
            lastPlugins = make([]string, 0)
        } else {
            lastPlugins = append(lastPlugins, os.Args[i])
        }
    }
}
if len(lastPlugins) > 0 {
    log.Fatal("No version provided for plugins "   strings.Join(lastPlugins, ", "))
}
fmt.Println(plugins) //map[plugin1:1.0 plugin2:1.2 plugin3:3.7 plugin4:3.7]
  • Related