前言git
Cobra既是用於建立強大的現代CLI應用程序的庫,也是用於生成應用程序和命令文件的程序。許多使用最普遍的Go項目都是使用Cobra構建的,其中包括:
kubernetes
docker
openshift
...github
1、安裝Cobra
在咱們安裝Cobra以前,咱們先解決大陸網絡沒法訪問的問題(你懂得),不然是沒法完成全部工具的安裝。這裏咱們使用Gopm來實現,gopm是Go Package Manager 的縮寫。是Golang上的包管理工具,十分好用。golang
1.1 gopm 安裝docker
go get -u github.com/gpmgo/gopm
這樣就將gopm完成了,在對應的$GOPATH/bin目錄下便可看到;express
1.2 安裝Cobraapache
go get -g github.com/spf13/cobra/cobra go build github.com/spf13/cobra/cobra
提示:在執行go install的時候,須要依賴golang.org/x/相關軟件包,請到該處下載便可。下載以後,將該包解壓到本身的$GOPATH/src目錄便可;網絡
2、Cobra相關使用app
2.1 使用Cobra生產應用程序less
假設如今咱們要開發一個基於CLI的命令程序,名字爲demo。首先打開CMD,切換到GOPATH的bin目錄下,執行以下指令:工具
cobra init demo
在src目錄下會生成一個demo的文件夾,以下:
tree src/demo
src/demo
├── LICENSE
├── cmd
│ └── root.go
└── main.go
測試cobra效果:
demo go run main.go demo 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.
當初次建立完項目以後,便可使用項目(這裏是"demo")來查看效果;
2.2 添加子命令(這裏以51reboot培訓內容爲例)
demo cobra add unbuf unbuf created at /Users/yangsheng/go/src/demo/cmd/unbuf.go demo tree . ├── LICENSE ├── cmd │ ├── root.go │ └── unbuf.go └── main.go
此時目錄結構變動爲如上所示。如今咱們來執行一下這個子命令:
go run main.go unbuf unbuf called
2.3 完善子命令功能
建立unbuf代碼程序
mkdir unbuf
在該目錄下面新建文件unbuf.go文件,具體內容以下:
package unbuf import ( "fmt" "math/rand" "sync" "time" ) func init() { rand.Seed(time.Now().UnixNano()) } //Player xxx type Player struct { User1 string User2 string } // NewPlayer create a instance, Player is object func NewPlayer(user1, user2 string) *Player { return &Player{ User1: user1, User2: user2, } } func (p *Player) GoPlayer() { var wg sync.WaitGroup ch := make(chan int) wg.Add(2) go player(p.User1, ch, &wg) go player(p.User2, ch, &wg) ch <- 1 wg.Wait() } //player two players func player(name string, ch chan int, wg *sync.WaitGroup) { defer wg.Done() for { ball, ok := <-ch if !ok { fmt.Printf("%s won!!!\n", name) break } n := rand.Intn(100) if n%15 == 0 { fmt.Printf("%s miss,the rand number is %d\n", name, n) close(ch) break } fmt.Printf("Player %s hit the ball %d,the rand number is %d\n", name, ball, n) ball++ ch <- ball } } func Runner() { var wg sync.WaitGroup ch := make(chan int) wg.Add(1) go run(ch, &wg) ch <- 1 wg.Wait() } func run(ch chan int, wg *sync.WaitGroup) { var newRunner int runner := <-ch fmt.Printf("runner %d running with Baton\n", runner) if runner != 4 { newRunner = runner + 1 fmt.Printf("runner %d to the line\n", runner) go run(ch, wg) } // rand sleep time n := rand.Intn(100) time.Sleep(time.Duration(n) * time.Millisecond) if runner == 4 { fmt.Printf("runner %d finish,Race over\n", runner) wg.Done() return } fmt.Printf("runner %d exchange with runner %d\n", runner, newRunner) ch <- newRunner }
對子命令進行完善,具體代碼以下:
// 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" "github.com/51reboot/golang-03-homework/lesson8/jkak/unbuf" "github.com/spf13/cobra" ) // unbufCmd represents the unbuf command var unbufCmd = &cobra.Command{ Use: "unbuf", 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("unbuf called") // TODO: work your own magic here obj := unbuf.NewPlayer("chen", "song") obj.GoPlayer() fmt.Println("\n-- start running --\n") unbuf.Runner() }, } func init() { rootCmd.AddCommand(unbufCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // unbufCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command // is called directly, e.g.: // unbufCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
到此一個簡單demo功能就已經實現,咱們運行一下看看實際效果:
go run main.go unbuf unbuf called Player song hit the ball 1,the rand number is 12 Player chen hit the ball 2,the rand number is 69 Player song hit the ball 3,the rand number is 58 Player chen hit the ball 4,the rand number is 77 Player song hit the ball 5,the rand number is 83 Player chen hit the ball 6,the rand number is 31 Player song hit the ball 7,the rand number is 16 Player chen hit the ball 8,the rand number is 67 Player song hit the ball 9,the rand number is 78 chen miss,the rand number is 15 song won!!! -- start running -- runner 1 running with Baton runner 1 to the line runner 1 exchange with runner 2 runner 2 running with Baton runner 2 to the line runner 2 exchange with runner 3 runner 3 running with Baton runner 3 to the line runner 3 exchange with runner 4 runner 4 running with Baton runner 4 finish,Race over
Cobra的使用就介紹到這裏,更新細節可去github詳細研究一下。這裏只是一個簡單的使用入門介紹,若是有錯誤之處,敬請指出,謝謝~
最後文中用到的代碼,若有侵權,請與我聯繫;