2.1. YAML 语言指南#

YAML 是一种让计算机和人都能读懂的文件格式。这部分指南主要针对编写 CWL 描述和输入参数文件,介绍 YAML 的特性。

备注

如果你已经能够得心应手地运用 YAML, 这一部分可以跳过。

2.1.1. 目录#

2.1.2. 键值对#

根本而言,YAML 格式的文件是一组形如 key: value(即“键: 值”)的_键值对_ (key-value pair). 这里,冒号 : 后的空白字符是不可少的。CWL 文件中的键名不得包含空白字符——CWL 规约中有特殊含义的词组键名写为 camelCase(“驼峰”大小写),无特殊含义者用下划线 (_) 分隔键名中的词。例如:

first_name: Bilbo
last_name:  Baggins
age_years:  111
home:       Bag End, Hobbiton

上面这一段 YAML 包含4个键——first_name, last_name, age_years, 以及 home——及其对应的值。值可以是字符串,数值(整数,浮点数,或者科学记数法),布尔值(真值 true 或非真值 false),或者更复杂的嵌套类型(见下)。

值可以用括号包围起来,但要当心这样做可能改变其理解:"1234" 会被当作字符串,而 1234 为整数。有的时候,这之间的区别会很重要,例如描述命令的参数时:CWL 语言中,baseCommand 的所有部分都必须为字符串;因此,如果你打算给命令传递一个数值常数作为参数值,那就必须将该数值用括号包围起来:baseCommand: [echo, "42"].

2.1.3. 注释#

在 CWL 和参数文件中,可以用 # 符号引入注释。每行中 # 之后的全部字符都会被 YAML 解释程序忽略。例如:

first_name: Bilbo
last_name:  Baggins
age_years:  111
# this line will be ignored by the interpreter
home:       Bag End, Hobbiton # this is ignored too

如果在某行里,注释之前有任何内容,记得 # 前需要至少一个空白字符!

2.1.4. 映射#

用 CWL 描述工具或工作流时,通常需要构造更加复杂、多级嵌套的表示。这样的层级结构称为“映射”;用 YAML 表示映射,是用一组键值对作为某个键的值。这样(作为值)的键值对有时称为“子”键值对,写为其所属键(“母”键)下另起的新行,且应该用两个空格字符增加一级缩进(制表符⇥不允许用作此目的)。例如:

cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
inputs: # this key has an object value
  example_flag: # so does this one
    type: boolean
    inputBinding: # and this one too
      position: 1
      prefix: -f

上面的 YAML 样本展示了快速构建复杂嵌套对象描述的办法。inputs 这个映射包含单独一个键 example_flag, 而后者本身又包含两个键 typeinputBinding; 其中,inputBinding 这个子键又包含另外两个键值对 (positionprefix). 如果要为某一个键提供多个单值或子键值对值,请参见后面的数组部分。这里,我们用如下图形表示它所描述的 inputs 这个对象,以供与上面的 YAML 对照。

graph TD inputs --> example_flag example_flag --> type type --- bool((boolean)) example_flag --> inputBinding inputBinding --> position inputBinding --> prefix position --- posval((1)) prefix --- prefval(('-f'))

2.1.5. 数组#

有些情况下,我们需要为某个键提供多个值或对象。如前面的映射部分所述,一个键下可以映射多个键值对。不过,我们还可以为某个键指定多个值,同时无需为每个值都添加一个独特的子键。这可以通过“数组”实现;数组中的每个元素值出现在 -(短线)符号后的新行上。例如:

touchfiles:
  - foo.txt
  - bar.dat
  - baz.txt

以及将映射与数组结合的一个较复杂例子:

exclusive_parameters:
  type:
    - type: record
      name: itemC
      fields:
        itemC:
          type: string
          inputBinding:
            prefix: -C
    - type: record
      name: itemD
      fields:
        itemD:
          type: string
          inputBinding:
            prefix: -D

2.1.6. JSON 样式#

YAML 的基础是 JavaScript Object Notation (JSON). YAML 映射与数组都可以用 JSON 原生的语法表达。例如:

touchfiles: [foo.txt, bar.dat, baz.txt] # equivalent to first Arrays example

以及:

# equivalent to the `inputs` example in "Maps" above
inputs: {example_flag: {type: boolean, inputBinding: {position: 1, prefix: -f}}}

原生 JSON 可以用于表达某字段值有意为空(如使用 [] 代表空数组),以及多个值适合出现在同一行内的情况(如为 shell 命令行提供选项和参数值的时候)。不过,如上第二个例子所示,这种格式可能让 YAML 文件的可读性大打折扣,因此应慎用。

2.1.7. 参考资料#

Learn YAML in Y Minutes 作为参考资料在我们写作本《指南》的过程中起到了很大的帮助,不过其中介绍的部分语言特性不适用于 CWL.