yamlのanchorで継承(extend)して繰り返し書いている部分を減らすメモ

JSばっかやってて.yml書くことはあまりないのだけど、CircleCIのコンフィグとかはyaml記述なので書いていく必要がある。

それで、CircleCIのコンフィグを書いていると、pathとか、複数のjobでそれぞれ同じようなことばかり書いている部分があってDRYじゃないな〜つらいな〜という気持ちで書いていた。

重い腰を上げてググってたところ、JSONと違ってYAMLは継承ができるっぽいので、これを使うとちょいいい感じにできるっぽい。

anchor

&を使うのをanchorと呼んでいるらしい

foo: &foo
  a: 1
  b: 2
  c: 3

これでfooオブジェクトが参照元になる

JSON変換するとこうなる

{
  "foo": {
    "a": 1, 
    "c": 3, 
    "b": 2
  }
}

extend

<<はextendの意味らしい

anchorを継承したいときは<<: *アンカー名のようにする。

foo: &foo
  a: 1
  b: 2
  c: 3

bar:
  <<: *foo
  c: "changed"
  d: 4

なお後述した重複プロパティは上書きされる。この例ではcプロパティを上書きしている。

JSON変換するとこうなる

{
  "foo": {
    "a": 1, 
    "c": 3, 
    "b": 2
  }, 
  "bar": {
    "a": 1, 
    "c": "changed", 
    "b": 2, 
    "d": 4
  }
}

extend inline

オブジェクトの中の単一のプロパティだけ継承元にしたいときは

<<: &アンカー名とする。

こうするとネストしたプロパティのみにアンカーされる。

baz:
  <<: &awesome
    awesome: "cat"
  great: "god"
  bad: "human"

status:
  <<: *awesome
  work: true

JSON変換するとこうなる

{
  "status": {
    "awesome": "cat", 
    "work": true
  }, 
  "baz": {
    "great": "god", 
    "awesome": "cat", 
    "bad": "human"
  }
}

上記一例をオンライン上でみる

YAML Online parser上で見るなら以下です


以下はめっちゃ雑な例

なんか適当に手元でガチャガチャやった例です

データに意味合いはないけど、どういう挙動をしているのか確認したいなら参考になる(かも)

refs:
  <<: &dir
    dir:  /foo/bar
  <<: &favs
    favs: 
      - web
      - music
      - bath
  task: &task
    1: kaimono
    2: souji
    3: renraku
  friends: &friends
    mika: true
    ryo: true,
    yuna: invite
    mike: false
    
im: summer
you:  &you who
he: *you

robot-talking:
  <<: *dir
  she: *you
  name: awesome-robot
  <<: *favs
  task: *task
  <<: *friends

同じくYAML Online parser上で見るなら以下です

参考情報


ひとつ学びになってよかった。書かないと忘れるので書いた。