zoukankan      html  css  js  c++  java
  • go cobra实例讲解

    概述

    cobra 库是 golang 的一个开源第三方库,能够快速便捷的建立命令行应用程序。

    优势:cobra 可以快速建立CLI程序,使我们更专注于命令需要处理的具体的业务逻辑。

    举两个例子:

    hugo server --port=1313
    git clone URL --bare
    

    都是命令行程序。

    基本概念

    cobra由三部分构成:commandsargumentsflags

    commands:表示要执行的动作。每一个 command 表示应用程序的一个动作。每个命令可以包含子命令。

    arguments:给动作传入的参数。

    flags:表示动作的行为。可以设置执行动作的行为。flags 包括两种:对某个命令生效和对所有命令生效。

    安装方法

    go get -u github.com/spf13/cobra/cobra
    

    github地址:https://github.com/spf13/cobra

    使用方法

    1.创建cobra命令行应用程序

    cobra init code.byted.org/dfic/demo
    

    $GOPATH/src/code.byted.org.dfic/ 目录下创建一个名为 democobra 命令行应用程序

    main.go 文件,完成初始化 cobra 功能。

    第一次初始化可能会出现这个问题 Error: required flag(s) "pkg-name" not set 解决办法

    package main
     
    import "code.byted.org/dfic/demo/cmd"
     
    func main() {  
        cmd.Execute()
    }
    

    2.添加命令

    2.1.基本用法

    cobra add version

    cmd 文件夹下生成一个新的文件 version.go,定义这个新的命令的动作。

    文件内容如下:

    import (  
        "fmt"
     
        "github.com/spf13/cobra"
    )
     
    // versionCmd represents the version command
    var versionCmd = &cobra.Command{  
        Use:   "version",
        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("version called")
        },
    }
     
    func init() {  
        rootCmd.AddCommand(versionCmd)
     
        // Here you will define your flags and configuration settings.
     
        // Cobra supports Persistent Flags which will work for this command
        // and all subcommands, e.g.:
        // versionCmd.PersistentFlags().String("foo", "", "A help for foo")
     
        // Cobra supports local flags which will only run when this command
        // is called directly, e.g.:
        // versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
    }
    

    编译运行

    > go build -o demo
     
    > ./demo -h
     
    Usage:  
      demo [command]
     
    Available Commands:  
      help        Help about any command
      version     A brief description of your command
     
    Flags:  
          --config string   config file (default is $HOME/.demo.yaml)
      -h, --help            help for demo
      -t, --toggle          Help message for toggle
     
    执行新添加的命令
    > ./demo version
    输出:version called
    

    2.2.修改命令行为

    将命令的行为添加到命令结构Run参数对应的方法中

    var versionCmd = &cobra.Command{  
        Use:   "version",
        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("version called")
        },
    }
    

    3.添加flag

    3.1.添加局部flag

    在 version.go 文件的 init 函数中添加 局部flag

    func init() {  
        rootCmd.AddCommand(versionCmd)
        versionCmd.Flags().BoolP("test", "t", false, "test")
    }
    

    执行命令

    > ./demo version -h
     
    Usage:  
      demo version [flags]
     
    Flags:  
      -h, --help   help for version
      -t, --test   test
     
    Global Flags:  
          --config string   config file (default is $HOME/.demo.yaml)
    

    4. flag赋值

    如果需要使用 全局flag 或者 局部flag,需要在合适的作用域内定义变量存储 flag 值,以便 flag 可在特定作用域内生效。

    4.1.使用全局flag

    让一个 flag 对所有命令生效,需要在 root.go 文件中创建一个变量存储 flag 值。

    如需要定义一个全局flag name:

    1.在root.go 文件中添加一个变量name
     
    var name string
     
    2.在init函数中添加全局flag,将flag值存储到变量name中
     
    rootCmd.PersistentFlags().StringVar(&name, "name", "", "set name")
     
     
    3.在子命令version的Run方法中输出name  
    Run: func(cmd *cobra.Command, args []string) {  
        fmt.Println("name is: ", name)
    }
     
     
    4.执行命令  
    ./demo version --name wfl
    输出:
    name is:  wfl  
    

    4.2.使用局部flag

    让一个 flag 对某个命令生效,需要在该命令文件中创建一个变量存储 flag 值。

    如需要给version命令定义一个局部flag name:

    1.定义变量sunsine  
    var sunshine string
     
     
    2.在version.go的init函数中添加flag  
    versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", false, "you are my sunshine")
     
     
    3.在子命令version.go的Run方法中输出  
    Run: func(cmd *cobra.Command, args []string) {  
        fmt.Println("name is: ", name)
        fmt.Println("sunshine is: ", sunshine)
    }
     
     
    4.执行命令  
    ./demo version --name wfl --sunshine wfl
    输出:
    name is:  wfl  
    sunshine is:  wfl  
    

    问题:

    flags 存储到本地变量当中,那么其他命令是不是也可以用某个命令的 局部flag 呢?

    答:不可以。局部flag虽然是定义在某个命令文件中作为局部变量,cmd 文件夹下的其他文件可以访问这个变量,但是其他命令如果没有定义自己的 局部flag 获取相同 flag 值的话,获取到的值是该局部变量的零值。

    1.添加一个新命令helloworld  
    > cobra add helloworld
     
     
    2.输出sunshine值  
    Run: func(cmd *cobra.Command, args []string) {  
        fmt.Println("sunshine is: ", sunshine)
    }
     
     
    3.执行命令  
    > ./demo helloworld --sunshine wfl
    Error: unknown flag: --sunshine  
    输出错误未知flag。
    原因就是该命令并未定义局部flagsunshine
    

    4.3.必填flag

    默认情况下,flag是optional(选填),若flag为必填,则需要做如下设置

    如将version命令下的sunshine flag设置为必填

    1.init文件中增加flag定义  
    versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", "", "you are my sunshine")  
    versionCmd.MarkFlagRequired("sunshine")
     
    2.执行  
    > ./demo version
     
    3.输出  
    Error: required flag(s) "sunshine" not set  
    说明必须要设置flag sunshine
     
    4.传入sunshineflag  
    > ./demo version --sunshine wfl
    输出: sunshine is:  wfl
    

    5. 嵌套子命令

    cobra 的命令行工具可以创建嵌套子命令。使用 cobra add -p "父命令Cmd"。

    比如

    1.给version命令添加一个子命令show  
    > cobra add show -p "versionCmd"
     
     
    2.在cobra生成的show.go文件的init方法中,自动将showCmd添加到versionCmd下作为子命令  
    func init() {  
        versionCmd.AddCommand(showCmd)
    }
     
     
    3.执行嵌套子命令  
    > ./demo version show
    show called  
    

    6. 获取命令行参数值

    cobra 常用的参数配置校验器如下:

    MinimumNArgs(int) 当参数数目低于配置的最小参数个数时报错  
    MaximumNArgs(int) 当参数数目大于配置的最大参数个数时报错  
    ExactArgs(int)    如果参数数目不是配置的参数个数时报错  
    NoArgs            没有参数则报错  
    

    类似 git clone URL 这种类型的命令行,URL 为传给 clone 命令的参数

    获取URL的值,可以从 args 参数中直接取出

    举例:

    1.添加一个命令path  
    > cobra add path
     
    2.设置该命令需要且仅需要一个参数,并在Run方法中取出参数  
    var pathCmd = &cobra.Command{  
        Use:   "path [path]",
        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.`,  
        Args: cobra.ExactArgs(1),
        Run: func(cmd *cobra.Command, args []string) {
            fmt.Println("path called")
            fmt.Println("path:", args[0])
        },
    }
     
    3. 执行命令并输出  
    > ./demo path /home
    path: /home  
    
  • 相关阅读:
    HDU 3277 Marriage Match III(最大流+二分+并查集)
    HDU 3032 Nim or not Nim?(博弈,打表找规律)
    2013南京邀请赛小结——ACM两年总结
    HDU 2829 Lawrence (斜率DP)
    HDU 3530 Subsequence(单调队列)
    HDU 1525 Euclid's Game(博弈)
    C Count The Carries(2013南京邀请赛C题)
    A Play the Dice (2013南京邀请赛A题)
    POJ 3017 Cut the Sequence(单调队列+set)
    Jquery TreeView
  • 原文地址:https://www.cnblogs.com/niuben/p/13886555.html
Copyright © 2011-2022 走看看