[英]How can I provide JSON array as argument to cobra cli
I'm building a CLI using Go and Cobra library.我正在使用 Go 和 Cobra 库构建一个 CLI。 I've the following JSON that needs to be deserialized in the corresponding struct.
我有以下 JSON 需要在相应的结构中反序列化。 Argument as JSON array:
参数为 JSON 数组:
"[
(stringA, stringB),
stringC
]"
Struct结构
type MyStruct struct {
StringArray []string
}
I'm using Cobra's StringSicceVarP
as follows to我正在使用 Cobra 的
StringSicceVarP
如下
cmd.PersistentFlags().StringSliceVarP(&opts.StringParam, "paramname", "", nil, `this is the description`)
But cobra is reading the incoming json as one single string [(stringA, stringB), stringC]
whereas I want the array to be of length 2, such that StringArray[0]: (stringA, stringB)
and StringArray[1]: stringC
.但是 cobra 正在将传入的 json 作为单个字符串
[(stringA, stringB), stringC]
而我希望数组的长度为 2,这样 StringArray[0]: (stringA, stringB)
和 StringArray[1]: stringC
.
I can't use the StringSliceVarP
as it will split based on ,
which I don't want as my array string could itself has a ,
.我不能使用
StringSliceVarP
,因为它将基于 进行拆分,
我不希望这样做,因为我的数组字符串本身可能有,
。
How can I achieve this?我怎样才能做到这一点?
I personally advice you against this option.我个人建议您不要使用此选项。 Supplying formatted data is conventionally done through reading STDIN or from a file.
提供格式化数据通常是通过读取 STDIN 或从文件中完成的。 Such solution is usually more flexible by allowing you to add flags to specify the file's format (JSON, XML, etc.).
这种解决方案通常更灵活,允许您添加标志来指定文件的格式(JSON、XML 等)。
Supplying a filename instead of the raw JSON string in the arguments adds better interoperability with other software, and other benefits such as using the computer's disk for buffering data instead of the computer's memory/RAM.在 arguments 中提供文件名而不是原始 JSON 字符串可以增加与其他软件的更好互操作性,以及其他好处,例如使用计算机磁盘而不是计算机内存/RAM 来缓冲数据。
My personal recommendations is that:我个人的建议是:
However, if you insist on using a flag:但是,如果您坚持使用标志:
Cobra does not have built-in support for JSON structures. Cobra 没有对 JSON 结构的内置支持。 However, the pflag package (the flag library used by Cobra) allows you to define custom value types to be used as flags through the
pflag.(*FlagSet).Var()
method.但是, pflag package(Cobra 使用的标志库)允许您通过
pflag.(*FlagSet).Var()
方法定义要用作标志的自定义值类型。 You have to make a new type that implements the pflag.Value
interface:您必须创建一个实现
pflag.Value
接口的新类型:
type Value interface {
String() string
Set(string) error
Type() string
}
To make a custom JSON-parsing type, you could write the following to use the built-in encoding/json
package:要制作自定义 JSON 解析类型,您可以编写以下代码以使用内置
encoding/json
package:
import (
"encoding/json"
)
type JSONFlag struct {
Target interface{}
}
// String is used both by fmt.Print and by Cobra in help text
func (f *JSONFlag) String() string {
b, err := json.Marshal(f.Target)
if err != nil {
return "failed to marshal object"
}
return string(b)
}
// Set must have pointer receiver so it doesn't change the value of a copy
func (f *JSONFlag) Set(v string) error {
return json.Unmarshal([]byte(v), f.Target)
}
// Type is only used in help text
func (f *JSONFlag) Type() string {
return "json"
}
Then to use this new pflag.Value
-compatible type, you may write something like this:然后要使用这个新的
pflag.Value
兼容类型,你可以这样写:
import (
"fmt"
"github.com/spf13/cobra"
)
type MyStruct struct {
StringArray []string
}
func init() {
var flagMyStringArray []string
var myCmd = &cobra.Command{
Use: "mycmd",
Short: "A brief description of your command",
Run: func(cmd *cobra.Command, args []string) {
myStruct := MyStruct{StringArray: flagMyStringArray}
fmt.Printf("myStruct.StringArray contains %d elements:\n", len(myStruct.StringArray))
for i, s := range myStruct.StringArray {
fmt.Printf("idx=%d: %q", i, s)
}
},
}
rootCmd.AddCommand(myCmd)
myCmd.Flags().Var(&JSONFlag{&flagMyStringArray}, "paramname", `this is the description`)
}
Example usage:示例用法:
$ go run . mycmd --paramname 'hello'
Error: invalid argument "hello" for "--paramname" flag: invalid character 'h' looking for beginning of value
Usage:
test mycmd [flags]
Flags:
-h, --help help for mycmd
--paramname json this is the description
exit status 1
$ go run . mycmd --paramname '["(stringA, stringB)", "stringC"]'
myStruct.StringArray contains 2 elements:
idx=0: "(stringA, stringB)"
idx=1: "stringC"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.