Building from What is the difference between go-Cobra PersistentFlags and Flags?:
Assume we have a top-level prog
command, and two start
and stop
subcommands in it.
Assume the prog
command has a persistent flag called database
.
How can we make this flag required in the start
command only? Note that the stop
command should have the flag but it should be optional.
progCmd.MarkPersistentFlagRequired("database")
does not work as intended, as it would make the flag required in both start
and stop
.
startCmd.MarkPersistentFlagRequired("database")
does not work either:
no such flag -database
Here is minimal example that functions as you describe.
TLDR:
You may have attached PersistentFlags
to the root command prog
with start
and stop
being sub commands, and thus persists by definition.
A flag can be ‘persistent’ meaning that this flag will be available to the command it’s assigned to as well as every command under that command. For global flags, assign a flag as a persistent flag on the root.
In the example below, set PersistenFlags()
or Flags()
to each start
and stop
sub command and apply MarkPersistentFlagRequired()
or MarkFlagRequired()
respectively for each required flag.
Example File Layout
├── cmd
│ ├── root.go
│ ├── start.go
│ └── stop.go
├── go.mod
├── go.sum
├── main.go
main.go
package main
import (
"stackoverflow/78807651/prog/cmd"
)
func main() {
cmd.Execute()
}
cmd/root.go
package cmd
import (
"github.com/spf13/cobra"
)
var RootCmd = &cobra.Command{
Use: "prog",
}
func Execute() {
RootCmd.Execute()
}
cmd/start.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var startCmd = &cobra.Command{
Use: "start",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("starting...")
},
}
func init() {
RootCmd.AddCommand(startCmd)
// startCmd.Flags().StringP("database", "d", "", "testdb")
// startCmd.MarkFlagRequired("database")
startCmd.PersistentFlags().StringP("database", "d", "", "testdb")
startCmd.MarkPersistentFlagRequired("database")
}
cmd/stop.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var stopCmd = &cobra.Command{
Use: "stop",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("stopped...")
},
}
func init() {
RootCmd.AddCommand(stopCmd)
// stopCmd.Flags().StringP("database", "d", "", "testdb")
// stopCmd.MarkFlagRequired("database")
stopCmd.PersistentFlags().StringP("database", "d", "", "testdb")
// stopCmd.MarkPersistentFlagRequired("database")
}