YAML を用いる独自の設定ファイル(いわゆる「オレオレ YAML」)を作る際は、その YAML ファイルのスキーマ (その設定ファイルがどのような key, value を持つべきなのかの情報) を JSON Schema として書いて紐付けを行うと、エディタのサポートが得られて便利、という話をします。
JSON Schema を用意すると、YAML Language Server が補完等を行ってくれる
YAML ファイルの記述を支援するツールとして、YAML Language Server1 があり、YAML ファイルのバリデーション、入力の補完や、値の説明などを行ってくれます。
(Ref: https://github.com/redhat-developer/vscode-yaml#features)
補完等を行うために、 YAML Language Server はそのファイルに合わせた JSON Schema を参照しています。 (JSON Schema という名前にも関わらずびっくりですが使えます)
基本的には JSON Schema Store という様々なファイルの JSON Schema を保管するサイトから引っ張ってきているのですが、自分で独自の YAML ファイルと JSON Schema の紐付けの設定を行うことも出来ます。
オレオレ YAML の JSON Schema を用意して YAML Language Server の支援を受けられるようにするやり方
…ということで、オレオレ YAML が YAML Language Server の支援を受けられるように、オレオレ YAML 用の JSON Schema を作って紐付るやり方を説明していきます。
必要なのは、
- オレオレ YAML 用の JSON Schema ファイルを用意する
- 用意した JSON Schema ファイルと YAML ファイルと紐付けする (YAML ファイルのコメントとして、対応する JSON Schema を宣言する)
の2ステップです。
今回、例として Docker Compose っぽい内容の設定ファイルを例として用意しています。(サンプルリポジトリ: https://github.com/tomoasleep/yaml-json-schema-example)
必要な設定を行うと、以下のような補完などが行えるようになります。
1. オレオレ YAML に対応した JSON Schema を用意する
用意する方法は言語などによって様々なやり方があり、もちろん手で書くのもありなのですが、言語によってはコードから生成することが出来ます。一から JSON Schema を書いて、 YAML の内容と対応するように維持し続けるのは骨が折れるので、コード生成等を利用するのはおすすめです。
例えば、 golang では、 https://github.com/invopop/jsonschema が type 定義から対応する JSON Schema を生成できます。 yaml
tag の情報も参照出来るので一貫性をもたせやすく、出力する JSON Schema のカスタマイズも出来るので便利です。
type Config struct {
Version string `yaml:"version"`
Services map[string]Service `yaml:"services" jsonschema:"title=Services,description=Container definitions"`
}
type Service struct {
Image string `yaml:"image" jsonschema:"required,title=Image,description=The image to run,example=alpine:latest"`
Ports []PortMapping `yaml:"ports" jsonschema:"title=Ports,description=Ports to expose,example=3000:3000"`
Env map[string]string `yaml:"env"`
}
2. YAML ファイルのコメントで、対応する JSON Schema を宣言する
独自の YAML ファイルとに対応する JSON Schema の紐付けは、以下の # yaml-language-server:
から始まるコメントを YAML ファイルの先頭行に記述すると出来ます。
# yaml-language-server: $schema=<urlOrPathToTheSchema>
services:
web:
image: alpine:latest
ports:
- "3000:3000"
- "8080:8080"
<urlOrPathToTheSchema>
には以下のように、相対パス、絶対パス (~ での Home Directory は指定不可)、 URL のいずれかになります。
# yaml-language-server: $schema=/absolute/path/to/schema
# yaml-language-server: $schema=../relative/path/to/schema
# yaml-language-server: $schema=http://url-to-schema
基本的には同じリポジトリに YAML ファイルと JSON Schema ファイルを同梱出来るなら相対パスで指定、同梱が難しいなら JSON Schema ファイルをパブリックな場所にアップロードして、その URL を指定する、などになると思います。
そして、YAML ファイルの雛形を生成するさいに、自動でこのコメントを含めるようにすると、 YAML Language Server を使うエディタ拡張をインストールしているユーザーは、追加の設定不要でいきなり補完などが行えるようになります。
2'. (他の方法) YAML Language Server の設定として紐付けを書く
コメントとして書く方法の他には、 YAML Language Server の設定として以下のような設定を渡すと、紐付けが行なえます。
"yaml.schemas": {
"path-to-json-schema": "/myYamlFile.yaml"
}
YAML Language Server への設定の渡し方はエディタによって異なるのですが、例えば VSCode では .vscode/settings.json に書いて渡すことが出来ます。
おわりに
YAML 関連の一部ツールでは JSON Schema が使われていて、 YAML Language Server の他にも YAML の Validator (https://json-schema-everywhere.github.io/yaml) などもあったり、他にも JSON Schema からドキュメント生成などにも流用できたりします。
なので、 YAML で独自の設定ファイルを用意する際は、そのスキーマとなる JSON Schema ファイルも用意するといろいろと便利でおすすめです
-
YAML Language Server は VSCode の YAML extension などのバックエンドとして使われていて、 Language Server なので、 VSCode に限らず様々なエディタから使うことが出来ます。 ↩