ZhangZhihui's Blog  

 root.go:

复制代码
func init() {
    rootCmd.PersistentFlags().BoolVarP(&enableLogging, "log", "l", true, "Logging information")
    fmt.Println("*************************", enableLogging)
}

func Execute() {
    err := rootCmd.Execute()
    fmt.Println("@@@@@@@@@@@@@@@@@@@@@@@@@", enableLogging)
    if err != nil {
        os.Exit(1)
    }
}
复制代码

 

zzh@ZZHPC:/zdata/Github/mastering-go-expertise/stats_cli$ go run main.go insert -f d4.txt --log=false
************************* true
time=2024-06-23T23:27:37.700+08:00 level=ERROR msg="Invalid value a in line 0 strconv.ParseFloat: parsing \"a\": invalid syntax\n"
time=2024-06-23T23:27:37.700+08:00 level=ERROR msg="Invalid value b in line 1 strconv.ParseFloat: parsing \"b\": invalid syntax\n"
time=2024-06-23T23:27:37.700+08:00 level=ERROR msg="Invalid value c in line 2 strconv.ParseFloat: parsing \"c\": invalid syntax\n"
time=2024-06-23T23:27:37.700+08:00 level=ERROR msg="Invalid value d in line 3 strconv.ParseFloat: parsing \"d\": invalid syntax\n"
failed to read at least one value
@@@@@@@@@@@@@@@@@@@@@@@@@ false

 

rootCmd.Execute() runs below functions in order:

复制代码
    // The *Run functions are executed in the following order:
    //   * PersistentPreRun()
    //   * PreRun()
    //   * Run()
    //   * PostRun()
    //   * PersistentPostRun()
    // All functions get the same args, the arguments after the command name.
    // The *PreRun and *PostRun functions will only be executed if the Run function of the current
    // command has been declared.
    //
    // PersistentPreRun: children of this command will inherit and execute.
    PersistentPreRun func(cmd *Command, args []string)
    // PersistentPreRunE: PersistentPreRun but returns an error.
    PersistentPreRunE func(cmd *Command, args []string) error
    // PreRun: children of this command will not inherit.
    PreRun func(cmd *Command, args []string)
    // PreRunE: PreRun but returns an error.
    PreRunE func(cmd *Command, args []string) error
    // Run: Typically the actual work function. Most commands will only implement this.
    Run func(cmd *Command, args []string)
    // RunE: Run but returns an error.
    RunE func(cmd *Command, args []string) error
    // PostRun: run after the Run command.
    PostRun func(cmd *Command, args []string)
    // PostRunE: PostRun but returns an error.
    PostRunE func(cmd *Command, args []string) error
    // PersistentPostRun: children of this command will inherit and execute after PostRun.
    PersistentPostRun func(cmd *Command, args []string)
    // PersistentPostRunE: PersistentPostRun but returns an error.
    PersistentPostRunE func(cmd *Command, args []string) error
复制代码

 

To be precise, flags have been parsed before running the above functions:

root.go:

复制代码
var rootCmd = &cobra.Command{
    Use:   "stats",
    Short: "Statistics application",
    Long:  `The statistics application`,
    PersistentPreRun: func(cmd *cobra.Command, args []string) {
        fmt.Println("Starting rootCmd.PersistentPreRun")
        fmt.Println("#########################", enableLogging)
        setDefaultLogger()
    },
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Starting rootCmd.Run")
        fmt.Println("$$$$$$$$$$$$$$$$$$$$$$$$$", enableLogging)
    },
}

func init() {
    fmt.Println("Starting root.init()")
    rootCmd.PersistentFlags().BoolVarP(&enableLogging, "log", "l", true, "Logging information")
    fmt.Println("*************************", enableLogging)
}

func setDefaultLogger() {
    logger = slog.New(slog.NewTextHandler(os.Stderr, nil))
    if !enableLogging {
        logger = slog.New(slog.NewTextHandler(io.Discard, nil))
    }
    slog.SetDefault(logger)
}

func Execute() {
    fmt.Println("Starting rootCmd.Execute()")
    err := rootCmd.Execute()
    fmt.Println("@@@@@@@@@@@@@@@@@@@@@@@@@", enableLogging)
    if err != nil {
        os.Exit(1)
    }
}
复制代码

 

insert.go:

复制代码
var insertCmd = &cobra.Command{
    Use:   "insert",
    Short: "insert command",
    Long:  `A longer description of the insert command.`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Starting insertCmd.Run")
        insertRun()
    },
}

func init() {
    fmt.Println("Starting insert.init()")
}
复制代码

 

复制代码
zzh@ZZHPC:/zdata/Github/mastering-go-expertise/stats_cli$ go run main.go insert -f d4.txt
Starting insert.init()
Starting root.init()
************************* true
Starting rootCmd.Execute()
Starting rootCmd.PersistentPreRun
######################### true
Starting insertCmd.Run
time=2024-06-24T11:18:25.280+08:00 level=ERROR msg="Invalid value a in line 0 strconv.ParseFloat: parsing \"a\": invalid syntax\n"
time=2024-06-24T11:18:25.280+08:00 level=ERROR msg="Invalid value b in line 1 strconv.ParseFloat: parsing \"b\": invalid syntax\n"
time=2024-06-24T11:18:25.280+08:00 level=ERROR msg="Invalid value c in line 2 strconv.ParseFloat: parsing \"c\": invalid syntax\n"
time=2024-06-24T11:18:25.280+08:00 level=ERROR msg="Invalid value d in line 3 strconv.ParseFloat: parsing \"d\": invalid syntax\n"
failed to read at least one value
@@@@@@@@@@@@@@@@@@@@@@@@@ true
zzh@ZZHPC:/zdata/Github/mastering-go-expertise/stats_cli$ go run main.go insert -f d4.txt --log=false Starting insert.init() Starting root.init() ************************* true Starting rootCmd.Execute() Starting rootCmd.PersistentPreRun ######################### false Starting insertCmd.Run failed to read at least one value @@@@@@@@@@@@@@@@@@@@@@@@@ false
复制代码

 

Function setDefaultLogger assign different values to a global variable logger according to the value of persistent flag enableLogging. The right place to call it is the PersistentPreRun field of rootCmd.

The function in the Run field of rootCmd does not run when executing a specific command.

posted on   ZhangZhihuiAAA  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
 
点击右上角即可分享
微信分享提示