yamlをインタラクティブに絞り込みできるCLIを作った

初めに

最近仕事で少しk8s周りを触っています。k8sのマニフェストはyamlですが、 kustomizeなどを使ってリソースをまとめたりすると、どうしても長くなってしまい可読性が下がってしまう問題があります。

そこで、jidのようなインタラクティブに絞り込みできるツールがほしいなと思って調べたんですが、 見つからなかったのでydというCLIを作りました。

使い方

ydではパイプ、ファイル、URLからyamlを読み込めます。

$ yd file.yaml
$ yd https://sample.com/file.yaml
$ yd < file.yaml
$ yd -f file.yaml

CLI実行後、画面上部にクエリを入力する箇所があるので、そこにクエリを入力してyamlをインタラクティブに絞り込んでいきます。 たとえば次のようなyamlがある場合.tagsと入力すると画像のように絞り込めます。 使用できるクエリはこちらを参照してください。

swagger: "2.0"
info:
  description: "This is a sample server Petstore server.  You can find out more about Swagger at <a href=\"http://swagger.io\">http://swag
ger.io</a> or on irc.freenode.net, #swagger.  For this sample, you can use the api key \"special-key\" to test the authorization filters"
  version: 1.0.0
  title: Swagger Petstore YAML
  termsOfService: "http://swagger.io/terms/"
  contact:
    email: "apiteam@swagger.io"
  license:
    name: Apache 2.0
    url: "http://www.apache.org/licenses/LICENSE-2.0.html"
basePath: /v2
tags:
  - name: pet
    description: Everything about your Pets
    externalDocs:
      description: Find out more
      url: "http://swagger.io"
  - name: store
    description: Operations about user
  - name: user
    description: Access to Petstore orders
    externalDocs:
      description: Find out more about our store

しくみ

ydは内部でyqを使っています。yqでは、コア処理がyqlibとして切り出されているためCLIでは内部でそれを使っています。 そのため、クエリのパースや絞り込みの処理は実装せずフロントの部分の実装のみとなっています。

yqlibに関するドキュメントは見つからなかったんですが、 yqの実装ではクエリ(expr)を式としてパースしたあとに評価(eval)するようになっているので直感的でわかりやすかったです。 ydではパーサと評価器を使って入力するたびにパースして評価して、その結果を描画しています。

node, err := ui.Parser.ParseExpression(expr)
if err != nil {
	return
}

...

if err := ui.Evaluator.Evaluate("-", &in, node, ui.Printer); err != nil {
	return
}

ui.View.SetText(tview.TranslateANSI(ui.Out.String())).ScrollToBeginning()

yd自体の実装はとてもシンプルなので詳細な実装が気にいなる方はリポジトリを気軽に覗いてみてください。

最後に

ydはとりあえず雑に作って仕事で最低限使えるレベルになったので公開しましたが、ツールとしての完成度については全然満足していないのでちょいちょい改善していきたいと思います。

動かないところもあるかもしれないんですが、興味ある方は使ってみてください。