kdnakt blog

hello there.

yamlの値でコロン(:)をエスケープする

地味に困ったのでメモ。

[困ったこと]

target.ymlの中に含まれているfooというキーの値をtrueからfalseに変更するため、パイプラインで以下のような処理を書いていた。

script:
  - echo build start
  - sed -e "s/foo: true/foo: false/g" target.yml
  - echo build end 

しかし、YAMLlintなどでチェックすると、画像のようにNested mappings are not allowed in compact mappings at line 4, column 20と言われてバリデーションエラーとなってしまう。

[複数行テキストとシングルクオート]

yamlの中のfoo: trueのコロンのあたりでエラーになっているのがわかったので、エスケープ方法を検索すると、次のStackOverflowにたどり着いた。

stackoverflow.com

解決策としては2つ提示されている。

  • 複数行テキスト(>-)を利用する
  • コマンド全体をシングルクオートで囲う

個人的には手癖でyamlの複数行テキストには<code|-を利用している。
次のように修正したところバリデーションが通るようになった。

script:
  - echo build start
  - |-
    sed -e "s/foo: true/foo: false/g" target.yml
  - echo build end 

YAMLlintでバリデーションすると、次のようにシングルクオートを利用した形に変換されるので、本当はこっちのほうがいいのかも。

script:
  - echo build start
  - 'sed -e "s/foo: true/foo: false/g" target.yml'
  - echo build start

複数行テキストで使う|->-の区別がつかなかったので調べたところ、次の記事が参考になった。
>は行末の改行がスペースに変換され、そもそも|がなくても複数行テキストを書けることがわかった。-は最後の改行を消してくれるらしい。奥が深い...。

qiita.com

[まとめ]

  • yamlの値にコロンを含む文字列を利用する場合、複数行テキストを利用するとよい
  • あるいはyamlの値をシングルクオートで囲うのも可
  • yaml複数行テキストは書き方によって改行コード/スペースの有無が異なる