ZhangZhihui's Blog  

 

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
复制代码

 

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