JSONのチェックくらいjqでやればええやろ、そう思っていた時期が私にもありました。
背景
ECSのタスク定義など、${foo}
みたいな環境変数をJSONに含めることは結構あります。
例えばこういうのですね。
{ "name": "main", "image": "${IMAGE_NAME}", "essential": true, "portMappings": [ { "protocol": "tcp", "containerPort": ${PORT} } ] }
このJSONは${IMAGE_NAME}
と${PORT}
を設定すると正しいJSONになります。
$ IMAGE_NAME=Foo PORT=80 envsubst < sample.json.template | jq { "name": "main", "image": "Foo", "essential": true, "portMappings": [ { "protocol": "tcp", "containerPort": 80 } ] }
実はここは${IMAGE_NAME}
を設定しなくても、"${IMAGE_NAME}"
が""
(空文字)に置換されるのでJSON的には正しくなります。ただし、${PORT}
のような数値はそういうわけにも行きません。"containerPort":
のような形で残ってしまうため、環境変数の設定をしないとjqによる検証は失敗します。これではシンタックスの誤りが含まれているのか、環境変数がセットされていないだけなのかが分かりません。
そこで
JSONのシンタックスをチェックしたいだけなのに、いちいち環境変数を集めるのは面倒ですね。そんなわけで環境変数をロードしなくてもシンタックスだけチェックしてくれるツールを書きました
$ jv sample.json.template
シンタックスが正しい(もし環境変数がセットされていれば正しいJSONになる)のでこれはパスします。${PORT}
の直後にカンマを入れてみましょう。これで環境変数がセットされていたとしても不正なJSONになります。
{ "name": "main", "image": "${IMAGE_NAME}", "essential": true, "portMappings": [ { "protocol": "tcp", "containerPort": ${PORT}, } ] }
$ jv sample.json.template syntax error at line 9 } ^^^ invalid character '}' looking for beginning of object key string
あとがき
まあこのツール、${foo}
みたいなのを全部0に置換してから検証してるだけなんですけどね...