我是 Go 初學者,我正在嘗試使用Cobra創建一個 CLI 。為了引導專案,我使用了Cobra Generator,生成了一個命令、一個子命令,一切正常。
我現在有這種型別的布局:
cli
├── cmd
│ ├── command.go
│ ├── root.go
│ ├── subcommand.go
├── go.mod
├── go.sum
└── main.go
這不適合我,假設我的專案打算有很多命令,或者很多命令命名空間,每個都由不同的團隊擁有,它會變得非常混亂且難以維護。我更喜歡這樣的布局:
cli
├── cmd
│ ├── command
│ │ ├── command.go
│ │ └── subcommand.go
│ └── root.go
├── go.mod
├── go.sum
└── main.go
現在,我對 Go 中的包和匯入方式缺乏一些了解(即使在閱讀了這里和那里的檔案之后),但據我了解,只要它們屬于,就可以跨多個 go 源檔案訪問一個資源同一個包。但正如檔案中所說,“一個實作可能需要一個包的所有源檔案位于同一個目錄中。”,所以要實作我想要的布局,我需要有多個包,即每個命令一個包命名空間,我認為這很好(或者至少,我不明白這樣做會有什么問題)。所以這就是我嘗試過的:
- 在其中創建一個
command目錄cmd - 將
command.go檔案移動到command目錄中 - 將檔案中的
package子句更改為command.gocommand - 做同樣的事情
subcommand.go
這構建得很好,但是找不到命令(Error: unknown command "command" for "cli")。我以為是因為我從來沒有匯入過那個新command包,所以我在main.go檔案中匯入了它,cmd包被匯入的地方。
undefined: rootCmd構建失敗,在command.go檔案中告訴我。我猜這個command包無法看到其中的資源cmd,所以我cmd在檔案中匯入了包command.go,并替換rootCmd為cmd.rootCmd(rootCmd作為檔案中創建的變數cli/cmd/root.go,Cobra Generator 提供的檔案的一部分)。這次我真的有希望,但結果還是一樣(undefined: cmd.rootCmd),現在我迷路了。
我是否正在嘗試做 Cobra 無法做到的事情?
我是否正在嘗試使用 Cobra 做一些可能的事情,但不使用 Cobra Generator?
我是否正在嘗試做一些根本不應該做的事情(比如 Go 試圖保護我的糟糕設計)?
如果沒有,我應該如何進行?
uj5u.com熱心網友回復:
您無法使用cobra-cli命令獲得所需的布局,但您當然可以手動設定。讓我們從cobra-cli布局開始:
$ go mod init example
$ cobra-cli init
并添加幾個命令:
$ cobra-cli add foo
$ cobra-cli add bar
這讓我們:
.
├── cmd
│ ├── bar.go
│ ├── foo.go
│ └── root.go
├── go.mod
├── go.sum
├── LICENSE
└── main.go
讓我們首先將命令移動到子目錄中,以便我們擁有所需的布局。這讓我們:
.
├── cmd
│ ├── bar
│ │ └── bar.go
│ ├── foo
│ │ └── foo.go
│ └── root.go
├── go.mod
├── go.sum
├── LICENSE
└── main.go
現在我們需要對我們的代碼進行一些更改以使其正常作業。
因為我們的子命令現在位于單獨的包中,所以我們需要重命名
rootCmd以使其可匯出。find cmd -name '*.go' -print | xargs sed -i 's/rootCmd/RootCmd/g'我們需要每個子命令都在其自己的包中,因此我們將替換
package cmd頂部的cmd/foo/foo.gowithpackage foo和 withpackage barincmd/bar/bar.go。我們需要子命令來匯入根命令,以便它們可以呼叫
RootCmd.AddCommand. 這意味著我們需要添加cmd/foo/foo.go到我們的部分(回想一下,我們通過命令命名了我們的頂級包)。這意味著每個檔案都將以:cmd/bar/bar.goexample/cmdimportexamplego mod initpackage foo import ( "fmt" "example/cmd" "github.com/spf13/cobra" )作為此更改的一部分,我們還需要更新參考以
AddCommand使用明確的包名稱:func init() { cmd.RootCmd.AddCommand(fooCmd) }最后,我們需要在某處匯入子命令。現在我們從不匯入
fooorbar包,所以代碼實際上是不可見的(嘗試在其中一個檔案中引入一個嚴重的語法錯誤——你會看到這go build會成功,因為這些檔案在任何地方都沒有被參考)。我們可以在頂級
main.go檔案中執行此操作:package main import ( "example/cmd" _ "example/cmd/bar" _ "example/cmd/foo" ) func main() { cmd.Execute() }
現在,如果我們構建并運行代碼,我們會看到我們的foo和bar命令可用:
$ go build
$ ./example
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.
Usage:
example [command]
Available Commands:
bar A brief description of your command
completion Generate the autocompletion script for the specified shell
foo A brief description of your command
help Help about any command
Flags:
-h, --help help for example
-t, --toggle Help message for toggle
Use "example [command] --help" for more information about a command.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/512015.html
標籤:去眼镜蛇
