zzh@ZZHPC:/zdata/Github/mastering-go-expertise$ cd go-cobra/ zzh@ZZHPC:/zdata/Github/mastering-go-expertise/go-cobra$ cobra-cli init Error: invalid character '{' after top-level value
(go-cobra is not a module)
This is an issue that is still open. See https://github.com/spf13/cobra-cli/issues/26. There's a workaround:
Removing all projects from the workspace except the one I want to cobra-cli init
does let things work, and that's good enough to unblock me.
zzh@ZZHPC:/zdata/Github/go-cobra$ go mod init go-cobra go: creating new go.mod: module go-cobra
go.work:
go 1.22.2 use ( ./go-cobra )
zzh@ZZHPC:/zdata/Github/go-cobra$ cobra-cli init Your Cobra application is ready at /zdata/Github/go-cobra zzh@ZZHPC:/zdata/Github/go-cobra$ tree . ├── cmd │ └── root.go ├── go.mod ├── go.sum ├── LICENSE └── main.go 1 directory, 5 files zzh@ZZHPC:/zdata/Github/go-cobra$ go mod tidy zzh@ZZHPC:/zdata/Github/go-cobra$ go run main.go A longer description that spans multiple lines and likely contains examples and usage of using your application. For example: Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.
A utility with three commands
Use the "cobra-cli add" command to add new commands to an existing cobra project. The names of the commands are one, two, and three:
zzh@ZZHPC:/zdata/Github/go-cobra$ cobra-cli add one one created at /zdata/Github/go-cobra zzh@ZZHPC:/zdata/Github/go-cobra$ cobra-cli add two two created at /zdata/Github/go-cobra zzh@ZZHPC:/zdata/Github/go-cobra$ cobra-cli add three three created at /zdata/Github/go-cobra
The previous commands create three new files in the cmd folder, named one.go, two.go, and three.go, which are the initial naïve implementations of the three commands. The first thing you should usually do is delete any unwanted code from root.go and change the messages of the utility and each command, as described in the Short and Long fields. However, if you want, you can leave the source files unchanged.
root.go
/* Copyright © 2024 NAME HERE <EMAIL ADDRESS> */ package cmd import ( "os" "github.com/spf13/cobra" ) // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "go-cobra", Short: "A brief description of your application", Long: `A longer description that spans multiple lines and likely contains examples and usage of using your application. For example: Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, } // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { err := rootCmd.Execute() if err != nil { os.Exit(1) } } func init() { // Here you will define your flags and configuration settings. // Cobra supports persistent flags, which, if defined here, // will be global for your application. // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.go-cobra.yaml)") // Cobra also supports local flags, which will only run // when this action is called directly. rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
two.go
/* Copyright © 2024 NAME HERE <EMAIL ADDRESS> */ package cmd import ( "fmt" "github.com/spf13/cobra" ) // twoCmd represents the two command var twoCmd = &cobra.Command{ Use: "two", Short: "A brief description of your command", Long: `A longer description that spans multiple lines and likely contains examples and usage of using your command. For example: Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.`, Run: func(cmd *cobra.Command, args []string) { fmt.Println("two called") }, } func init() { rootCmd.AddCommand(twoCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // twoCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command // is called directly, e.g.: // twoCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
Adding command line flags
We are going to create two global command line flags and one command line flag that is attached to a given command (two) and not supported by the other two commands. Global command line flags are defined in the ./cmd/root.go file. We are going to define two global flags, named directory, which is a string, and depth, which is an unsigned integer. Both global flags are defined in the init() function of ./cmd/root.go:
package cmd import ( "github.com/spf13/cobra" "github.com/spf13/viper" ) // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "go-cobra", Short: "A sample Cobra project", Long: `A sample Cobra project for Mastering Go`, } // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { cobra.CheckErr(rootCmd.Execute()) } func init() { rootCmd.PersistentFlags().StringP("directory", "d", "/tmp", "Path") rootCmd.PersistentFlags().Uint("depth", 2, "Depth of search") viper.BindPFlag("directory", rootCmd.PersistentFlags().Lookup("directory")) viper.BindPFlag("depth", rootCmd.PersistentFlags().Lookup("depth")) }
We use rootCmd.PersistentFlags() to define global flags, followed by the data type of the flag. The name of the first flag is directory and its shortcut is d, whereas the name of the second flag is depth and has no shortcut—if you want to add a shortcut to it, you should use the UintP() method, as the depth parameter is an unsigned integer. After defining the two flags, we pass their control to viper by calling viper.BindPFlag(). The first flag is a string, whereas the second one is a uint value. As both of them are available in the cobra project, we call viper.GetString("directory") to get the value of the directory flag and viper.GetUint("depth") to get the value of the depth flag. This is not the only way to read the value of a flag and use it.
Last, we add a command line flag that is only available to the two command by adding the next line to the init() function of the ./cmd/two.go file:
package cmd import ( "fmt" "github.com/spf13/cobra" ) // twoCmd represents the two command var twoCmd = &cobra.Command{ Use: "two", Aliases: []string{"cmd2"}, Short: "Command two", Long: `A longer description for command two.`, Run: func(cmd *cobra.Command, args []string) { username, err := cmd.Flags().GetString("username") if err != nil { fmt.Println("Error reading username:", err) } else { fmt.Println("Username:", username) } }, } func init() { rootCmd.AddCommand(twoCmd) twoCmd.Flags().StringP("username", "u", "Frank", "Username") }
The name of the flag is username, and its shortcut is u. As this is a local flag available to the two command only, we can get its value by calling cmd.Flags().GetString("username") inside the ./cmd/two.go file only.
Creating command aliases
See above code.
Creating subcommands
This subsection illustrates how to create two subcommands for the command named three. The names of the two subcommands will be list and delete. The way to create them using the cobra utility is as follows:
zzh@ZZHPC:/zdata/Github/go-cobra$ cobra-cli add list -p 'threeCmd' list created at /zdata/Github/go-cobra zzh@ZZHPC:/zdata/Github/go-cobra$ cobra-cli add delete -p 'threeCmd' delete created at /zdata/Github/go-cobra zzh@ZZHPC:/zdata/Github/go-cobra$ go run main.go three list list called zzh@ZZHPC:/zdata/Github/go-cobra$ go run main.go three delete delete called zzh@ZZHPC:/zdata/Github/go-cobra$ tree . ├── cmd │ ├── delete.go │ ├── list.go │ ├── one.go │ ├── root.go │ ├── three.go │ └── two.go ├── go.mod ├── go.sum ├── LICENSE └── main.go 1 directory, 10 files
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律