シナプスの技術部システム開発課の小園です。
CUE言語をとあるきっかけでさわってみました。
CUE言語とは
設定記述言語です。
テキストベースのデータの定義、検証などができます。
(JSONやYAMLのようなデータ定義の仕様です。)
CUE Playgroundというブラウザで実行可能なツールがあるので、簡単に試す事ができます。
DaggerというCI/CDツールが気になって見てみた時に設定記述言語として採用されていたため、その存在を知りました。
(この記事内ではDaggerの紹介はリンクのみにします。)
コマンドラインツールのインストール
CUE言語にはコマンドラインツールがあります。
コマンドラインツールを使う事で、データの検証や、CUEファイルからJSON/YAMLへの変換などができます。
インストールはHomebrewを使える環境であればHomebrewから、それ以外は公式サイトよりバイナリファイルをダウンロードして展開、配置をします。
詳細は公式マニュアルを参照ください。
CUEファイルの記述例
簡単なCUEファイルサンプルを用意しました。
# cat person.cue // Person Bob Bob: {name: "Bob", age: 28, sex: "male"} // Person Alice Alice: { name: "Alice" age: 27 sex: "female" }
CUEファイルの評価をします。
記述内容に問題があれば、エラーが出ます。
# cue eval person.cue Bob: { name: "Bob" age: 28 sex: "male" } Alice: { name: "Alice" age: 27 sex: "female" }
JSONで出力する事もできます。
慣れ親しんだJSONにする事でCUEファイルの定義がどのような内容か判ります。
# cue eval person.cue --out json { "Bob": { "name": "Bob", "age": 28, "sex": "male" }, "Alice": { "name": "Alice", "age": 27, "sex": "female" } }
CUE言語の特徴
サンプルの内容から、以下のようなことが挙げられます。
- CUEファイル内にコメントを入れる事が可能。
- フィールドの最後のカンマが不要。
- 外側のカッコの省略が可能。
- CUEファイルを操作するためのコマンドラインツール(cue)が提供されている。
- JSON/YAMLでの出力が可能。
他にも、以下のような事が可能です。
- スキーマ定義が書け、検証が可能。
- JSON/YAMLからCUE言語への変換が可能。
- 環境による設定記述内容の出し分けが可能。
デメリットとして以下のようなことが挙げられます。
- マイナーである。
- ドキュメントはそろっているので、実利用上は問題は無い。
- パーサー実装がまだ少ない。
- メインの設定ファイルとしては使い難い。
- 実装があるのは、Go言語位。
JSON/YAMLとの違い
JSONとの違い
JSONと比較した場合の優位点は以下のようになります。
- JSONは末尾カンマを適切に処理する必要があるが、CUE言語は不要である場合が多い。
YAMLとの違い
YAMLと比較した場合の優位点は以下のようになります。
- YAMLはインデントを正確に記述する必要があるが、CUE言語にはインデントを気にする必要はない。
スキーマ定義
スキーマ定義を含むCUEファイルは以下のようになります。
# cat person.cue // Person定義 #Person: { name: string age: int & >=0 & <=120 sex: string & "male" | "female" } // Person Bob Bob: #Person Bob: {name: "Bob", age: 28, sex: "male"} // Person Alice Alice: #Person Alice: { name: "Alice" age: 27 sex: "female" }
#から始まる箇所でスキーマ定義をしています。
検証をし、JSONで出力します。
エラーが無く、JSONが出力され、検証をされたことがわかります。
(検証でエラーになった場合には、JSONは出力されません。)
# cue eval person.cue --out json { "Bob": { "name": "Bob", "age": 28, "sex": "male" }, "Alice": { "name": "Alice", "age": 27, "sex": "female" } }
環境による設定記述内容の出し分け
CUEファイル以下のように記載します。
# cat person.cue _env: "prd" | "stg" | "dev" @tag(env) // Person定義 #Person: { name: string age: int & >=0 & <=120 sex: string & "male" | "female" role: *"staff" | string } // Person Bob Bob: #Person Bob: {name: "Bob", age: 28, sex: "male"} // Person Alice Alice: #Person Alice: { name: "Alice" age: 27 sex: "female" if _env == "dev" { role: "admin" } }
roleはデフォルト値がstaff
である設定がされていますが、途中のif文で変数_envの値がdev
の場合には、roleがadmin
となるようにしています。
cueコマンドより変数_envをdev
と定義して、JSONを作成します。
意図したとおりに、Aliceのroleがadmin
になっています。
# cue eval -t env=dev person.cue --out=json { "Bob": { "name": "Bob", "age": 28, "sex": "male", "role": "staff" }, "Alice": { "name": "Alice", "age": 27, "sex": "female", "role": "admin" } }
変数_envの値をstg
としてJSONを作成します。
意図したとおりに、Aliceのroleはstaff
になっています。
# cue eval -t env=stg person.cue --out=json { "Bob": { "name": "Bob", "age": 28, "sex": "male", "role": "staff" }, "Alice": { "name": "Alice", "age": 27, "sex": "female", "role": "staff" } }
まとめ
CUE言語は既存の設定記述言語(JSON/YAML)の問題点を解決できています。
ですが、CUE言語をメインとして使うには、周辺環境(パーサーなど)が整っていません。
一方で、JSONやYAMLファイルを柔軟に出力する手段としては有効です。
環境によって設定内容を書き換える場合などの場合には手段の候補になり得ます。