在 cobra 中只检索一次持久标志。

huangapple go评论69阅读模式
英文:

Retrieve persistent flags only once in cobra

问题

我有以下的cobra设置:

var rootCmd = &cobra.Command{
	Use:   "basic",
	Short: "This is the basic command",
	PreRunE: func(cmd *cobra.Command, args []string) error {
		if err := viper.BindPFlags(cmd.Flags()); err != nil {
			return err
		}
		return nil
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Hello")
		author := viper.GetString("author")
		fmt.Println(author)
	},
}

var subCmd1 = &cobra.Command{
	Use:   "subcommand1",
	Short: "This is test subcommand 1",
	PreRunE: func(cmd *cobra.Command, args []string) error {
		if err := viper.BindPFlags(cmd.Flags()); err != nil {
			return err
		}
		return nil
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Executing subcommand 1")
		author := viper.GetString("author")
		location := viper.GetString("location")
		fmt.Println(author)
		fmt.Println(location)
	},
}

var subCmd2 = &cobra.Command{
	Use:   "subcommand2",
	Short: "This is test subcommand 2",
	PreRunE: func(cmd *cobra.Command, args []string) error {
		if err := viper.BindPFlags(cmd.Flags()); err != nil {
			return err
		}
		return nil
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Executing subcommand 2")
		author := viper.GetString("author")
		duration := viper.GetInt("duration")
		fmt.Println(author)
		fmt.Printf("%d\n", duration)
	},
}

func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func init() {
	rootCmd.PersistentFlags().StringP("author", "a", "Pantelis Karamolegkos", "author name for copyright attribution")
	subCmd1.Flags().StringP("location", "l", "Athens", "location of the command execution")
	subCmd2.Flags().IntP("duration", "d", 10, "duration of the event in minutes")
	rootCmd.AddCommand(subCmd1)
	rootCmd.AddCommand(subCmd2)
}

我使用author作为PersistentFlag,以便在所有子命令中都可以使用。

我正在尝试找到一种方法来避免在每个子命令中重复使用

author := viper.GetString("author")

尽管这个片段并不复杂,但在我的真实代码中,我有几个PerstitentFlags和几个需要它们的子命令,因此代码库很快就会变得非常重复。

有没有办法解决这个问题?可以在父命令中只获取一次持久标志,并传递给子命令吗?
这里没有找到建议。

谢谢。

英文:

I have the following cobra setup

var rootCmd = &cobra.Command{
	Use:   "basic",
	Short: "This is the basic command",
	PreRunE: func(cmd *cobra.Command, args []string) error {
		if err := viper.BindPFlags(cmd.Flags()); err != nil {
			return err
		}
		return nil
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Hello")
		author := viper.GetString("author")
		fmt.Println(author)
	},
}

var subCmd1 = &cobra.Command{
	Use:   "subcommand1",
	Short: "This is test subcommand 1",
	PreRunE: func(cmd *cobra.Command, args []string) error {
		if err := viper.BindPFlags(cmd.Flags()); err != nil {
			return err
		}
		return nil
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Executing subcommand 1")
		author := viper.GetString("author")
		location := viper.GetString("location")
		fmt.Println(author)
		fmt.Println(location)
	},
}

var subCmd2 = &cobra.Command{
	Use:   "subcommand2",
	Short: "This is test subcommand 2",
	PreRunE: func(cmd *cobra.Command, args []string) error {
		if err := viper.BindPFlags(cmd.Flags()); err != nil {
			return err
		}
		return nil
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Executing subcommand 2")
		author := viper.GetString("author")
		duration := viper.GetInt("duration")
		fmt.Println(author)
		fmt.Printf("%d\n", duration)
	},
}

func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func init() {
	rootCmd.PersistentFlags().StringP("author", "a", "Pantelis Karamolegkos", "author name for copyright attribution")
	subCmd1.Flags().StringP("location", "l", "Athens", "location of the command execution")
	subCmd2.Flags().IntP("duration", "d", 10, "duration of the event in minutes")
	rootCmd.AddCommand(subCmd1)
	rootCmd.AddCommand(subCmd2)
}

I use author as a PersistentFlag so that it is available in all subcommands.

I am trying to find a way to skip the repetition of

author := viper.GetString("author")

in each subcommand (I of course want it to be available in all subcommands)

Although this snippet is not that convoluted, in my real code I have a few PerstitentFlags and and several subcommands requiring them, therefore the codebase can become very repetitive very quickly.

Is there any way around this? Can the persistent flags be retrieved only once in the parent command and get passed on to the subcommands?
Could not find a suggestion here.

Thanks.

答案1

得分: 1

一种处理这个问题的方法是使用“标志结构体”:

type Cmd1Flags struct {
  Author string
  ... // cmd1 的其他持久标志
}

func GetCmd1Flags() Cmd1Flags {
   ret := Cmd1Flags{}
   ret.Author = viper.GetString("author")
   ... // 初始化其他标志
   return ret
}

然后,在所有的子命令中使用 GetCmd1Flags()

英文:

One way to deal with this is to use "flag structs":

type Cmd1Flags struct {
Author string
... // Other persistent flags for cmd1
}
func GetCmd1Flags() Cmd1Flags {
ret:=Cmd1Flags{}
ret.Author=viper.GetString("author")
... // Initialize other flags
return ret
}

Then, use GetCmd1Flags() in all the subcommands.

huangapple
  • 本文由 发表于 2022年7月25日 22:26:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/73110888.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定