將cobra下載到 $GOPATH,用命令:git
go get -v github.com/spf13/cobra/cobra
而後使用 go install github.com/spf13/cobra/cobra
, 安裝後在 $GOBIN
下出現了cobra 可執行程序。若是你沒有配置 $GOBIN
,那麼能夠在$GOPATH/bin
下找到 cobra的可執行軟件。github
cobra程序只能在GOPATH之下使用,因此首先你須要進入到GOPATH的src目錄之下,在該目錄下,輸入:express
cobra init demo
在你的當前目錄下,應該已經生成了一個demo文件夾:apache
demo
├── cmd
│ └── root.go
├── LICENSE
└── main.go
上述即是該文件夾的結構,咱們能夠進去該文件夾,運行:app
go run main.go
應該會打印以下結果:less
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.
至此,咱們的cobra項目便已經生成完畢。函數
若是你並不想運行cobra的可執行命令生成示例代碼,只想在項目使用其庫代碼,則上面的內容能夠忽略。測試
附 demo 文件夾的內容:ui
cmd/root.go:this
// Copyright © 2018 NAME HERE <EMAIL ADDRESS> // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( "fmt" "os" homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" ) var cfgFile string // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "demo", 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() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } func init() { cobra.OnInitialize(initConfig) // 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/.demo.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") } // initConfig reads in config file and ENV variables if set. func initConfig() { if cfgFile != "" { // Use config file from the flag. viper.SetConfigFile(cfgFile) } else { // Find home directory. home, err := homedir.Dir() if err != nil { fmt.Println(err) os.Exit(1) } // Search config in home directory with name ".demo" (without extension). viper.AddConfigPath(home) viper.SetConfigName(".demo") } viper.AutomaticEnv() // read in environment variables that match // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { fmt.Println("Using config file:", viper.ConfigFileUsed()) } }
main.go:
// Copyright © 2018 NAME HERE <EMAIL ADDRESS> // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import "demo/cmd" func main() { cmd.Execute() }
實際操做其實cobra都能幫你完成,假設咱們如今須要添加一個test參數,在項目文件夾下命令行輸入:
cobra add test
執行完成後,如今咱們的demo結構應該是:
.
├── cmd
│ ├── root.go
│ └── test.go
├── LICENSE
└── main.go
能夠看到,在cmd目錄下,已經生成了一個與咱們命令同名的go文件,你也許已經猜想到,與該命令有關的操做也正是在此處實現。如今執行這個子命令:
go run main.go test
命令行將會打印輸出test called
那麼如今又有一個問題,若是咱們想添加子命令下的子命令呢?
如今讓咱們打開test.go,你應該看到以下的文件內容:
// Copyright © 2017 NAME HERE <EMAIL ADDRESS> // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( "fmt" "github.com/spf13/cobra" ) // testCmd represents the test command var testCmd = &cobra.Command{ Use: "test", 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("test called") }, } func init() { rootCmd.AddCommand(testCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // testCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command // is called directly, e.g.: // testCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
你會發現,在init中有一句 rootCmd.AddCommand(testCmd)
這個rootCmd是什麼?打開root.go,你會發現rootCmd其實就是咱們的根命令。我相信機智的同窗已經猜出來咱們添加子命令的子命令的方法了。如今讓咱們在cmd目錄下新建testson.go文件,項目文件結構爲:
.
├── cmd
│ ├── root.go
│ └── test.go
│ └── testson.go
├── LICENSE
└── main.go
把test.go的內容複製進去,並testson.go文件修改成以下內容:
cmd/testson.go:
// Copyright © 2017 NAME HERE <EMAIL ADDRESS> // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cmd import ( "fmt" "github.com/spf13/cobra" ) // testCmd represents the test command var testsonCmd = &cobra.Command{ Use: "testson", 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("testson called") }, } func init() { testCmd.AddCommand(testsonCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // testCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command // is called directly, e.g.: // testCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
如今在命令行運行:
go run main.go test testson
當你看到testson called
,恭喜你,子命令添加成功!不然你應當檢查你的代碼是否有誤。
我相信從init函數中的註釋中,你已經獲得了足夠多的信息來本身操做添加flag,但我仍是想要囉嗦兩句。首先是persistent參數,當你的參數做爲persistent flag存在時,如註釋所言,在其全部的子命令之下該參數都是可見的。而local flag則只能在該命令調用時執行。能夠作一個簡單的測試,在test.go的init函數中,添加以下內容:
testCmd.PersistentFlags().String("foo", "", "A help for foo") testCmd.Flags().String("foolocal", "", "A help for foo")
如今在命令行 go run main.go test -h
獲得以下結果:
$ go run main.go test -h 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. Usage: demo test [flags] demo test [command] Available Commands: testson A brief description of your command Flags: --foo string A help for foo --foolocal string A help for foo -h, --help help for test Global Flags: --config string config file (default is $HOME/.demo.yaml) Use "demo test [command] --help" for more information about a command.
接着讓咱們再運行 go run main.go test testson -h
$ go run main.go test testson -h 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. Usage: demo test testson [flags] Flags: -h, --help help for testson Global Flags: --config string config file (default is $HOME/.demo.yaml) --foo string A help for foo
能夠發如今Gloabal Flags的變化。test做爲root的子命令,仍然可使用root的persistent flag-> config(能夠查看root.go),而testson做爲test的子命令,不只可使用test的persistent flag-> fool, 也可使用test父命令的persistent flag。從而咱們能夠直觀的看出persistent的做用範圍是該命令以後的全部子命令。接下來你可能會問,那flag支持什麼類型參數?答案是,請查看官方文檔
請注意,cmd.Flags().String()與 cmd.Flags().StringP()是不同的。假如咱們在test.go的init下增長以下兩行:
testCmd.Flags().String("f", "", "test") testCmd.Flags().StringP("aaa", "a", "", "test")
前者調用須要以下形式:
go run main.go test --f
後者有以下兩種形式調用:
go run main.go test --aaa
go run main.go test -a
另外能夠額外告知你如何使用slice做爲參數,如[]string:
testCmd.Flags().StringSliceP("arr","r", nil, "test arr")
調用該參數的方法爲:
go run main.go test -r "a,b,c"
請不要鍵入多餘空格(除非確實須要鍵入),也不要使用空格替代逗號做爲分割符。
在知道了如何設置參數後,咱們的下一步固然即是須要在運行時獲取該參數的值。如今讓咱們把注意力放到test.go的此部分:
var testCmd = &cobra.Command{ Use: "test", 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("test called") }, }
讓咱們把注意力從新放到上面的代碼上。咱們也很容易能夠猜想到Use,Short,Long三個參數的做用,這裏便不作闡述(你能夠參照添加子命令的子命令的部分的輸出)。顯而易見,咱們應該在Run
這裏來獲取參數並執行咱們的命令功能。獲取參數其實也並不複雜。以testCmd.Flags().StringP("aaa", "a", "", "test")
此爲例,咱們能夠在Run函數裏添加:
str := testCmd.Flags().GetString("aaa")
這樣即可以獲取到該參數的值了,其他類型參數獲取也是同理。如 testCmd.Flags().GetStringSlice("arr")
,規律並不難見。