将 Bitrise YAML 键/值列表解析为 Go 结构

问题描述

我目前正在处理 Bitrise 工作流程步骤,并且我正在尝试允许该步骤为用户提供一种方法来为特定步骤输入提供可选的 YAML 键/值对列表,目前正在尝试实施如:

my_step@1:
    inputs:
        - uri_actions:
            - button_text: Some text
              uri: www.google.com
            - button_text: Some text 2
              uri: www.google2.com
            - button_text: Some text 3
              uri: www.google3.com

然后尝试在 Go 中解析为结构体:

type config struct {
    UriActionList []UriAction `env:"uri_actions"`
}

type UriAction struct {
    ButtonText string `env:"button_text"`
    Uri        string `env:"uri"`
}

并且还尝试将 config 结构映射为

的变体
type config struct {
    UriActionList map[UriAction]string `env:"uri_actions"`
}

Bitrise 步骤使用 stepconf 自动解析用户的工作流并将 YAML 映射到声明的 structs

func main() {
  var cfg config
  if err := stepconf.Parse(&cfg); err != nil {
      fmt.Fprintf(os.Stderr,"Error: %s\n",err)
      os.Exit(1)
  }
  stepconf.Print(cfg)
}
 

但两者都打得不好..

这是我第一次尝试 Go 并开发我自己的 Bitrise 步骤,那么我做错了什么?或者有没有更文明的方式来实现这一目标?

解决方法

编辑:根据评论中的讨论,此问题与用于解析 yaml 的 go-steputils/stepconf 库有关。但是该库根本不对 yaml 文件进行操作,只是使用一些糖来解析环境来处理集合(请参阅库用法 exampletest)。我的猜测是某处有一些管道可以将 yaml 转换为 env 变量。

如果您打算在没有管道的情况下从文件中读取 yaml,我建议您为此目的使用记录良好的库 - go-yaml 如下例所示:

type config struct {
    Inputs []Inputs `yaml:"inputs"`
}

type Inputs struct {
    UriActionList []UriAction `yaml:"uri_actions"`
}

type UriAction struct {
    ButtonText string `yaml:"button_text"`
    Uri        string `yaml:"uri"`
}

func main() {
    cfg := config{}

    err := yaml.Unmarshal([]byte(data),&cfg)
    if err != nil {
        log.Fatalf("error: %v",err)
    }
    fmt.Printf("---\n%v\n",cfg)
}

查看带有工作代码 here

的游乐场 ,

步骤输入只能是字符串/文本,因为它们作为环境变量传递给步骤,而环境变量只能是文本。你当然可以在字符串中包含一个 yml 结构,但它仍然必须是一个字符串。

所以,而不是你原来的

my_step@1:
    inputs:
        - uri_actions:
            - button_text: Some text
              uri: www.google.com
            - button_text: Some text 2
              uri: www.google2.com
            - button_text: Some text 3
              uri: www.google3.com

uri_actions 的值设为字符串(通过 |):

my_step@1:
  inputs:
    - uri_actions: |
        - button_text: Some text
          uri: www.google.com
        - button_text: Some text 2
          uri: www.google2.com
        - button_text: Some text 3
          uri: www.google3.com

然后在您的步骤中,您可以读取保存值(作为字符串)的环境变量 uri_actions

- button_text: Some text
  uri: www.google.com
- button_text: Some text 2
  uri: www.google2.com
- button_text: Some text 3
  uri: www.google3.com

如果您想将其解析为 YML,您可以按照@blami 提到的方式进行:

uriActionsUserInput := os.Getenv("uri_actions")
cfg := []UriAction{}
err := yaml.Unmarshal([]byte(uriActionsUserInput),&cfg)

在此处查看完整示例:https://play.golang.org/p/qst3oVnjK0X

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...