概要
開発中のlkmlfmtというフォーマッタがある程度使える段階になったので紹介する。GitHubのREADMEに書かなかった開発動機や実装方針の話も書き残しておく。
背景
Lookerのショートカット一覧を見るとCtrl+Shift+F
でファイルをフォーマットできると書いてあるが、それだけじゃあ足りないのだよ。sql: ;;
やhtml: ;;
で埋め込まれたコードまでフォーマットする手段がほしい...しかもliquidテンプレートもいい感じに扱ってほしい...そんな動機で開発し始めたのがlkmlfmt。
実装方針
ゼロから自前で実装するのはしんどいので、可能な限り他力本願を貫く。
- 大枠のLookMLのフォーマットだけ自前で実装する
- といっても構文解析にはlarkを使ったりとなるべく楽をする
-
sql: ;;
で埋め込まれたコードはsqlfmtでフォーマットする- jinjaまじりのsqlをフォーマットできるので、liquid ↔ jinjaの変換だけ手伝えばSQLのフォーマットを丸投げできる
-
html: ;;
で埋め込まれたコードはDjHTMLでフォーマットする- jinjaまじりのhtmlをフォーマットできるので、liquid ↔ jinjaの変換だけ手伝えばHTMLのフォーマットを丸投げできる
- djLintもよさそうだったが、今回の目的だとやや使いにくい1ので不採用
- Prettierのplugin(prettier-plugin-liquid)を使えばliquidまじりのhtmlをフォーマットできそうだが、ここだけJavaScriptで実装するのも面倒なので不採用
使い方
local
Pythonに慣れた人には同じみのpip
コマンドでインストールする。
pip install lkmlfmt
lkmlfmt
というコマンドが利用可能になるので、引数として対象ファイル(複数あってもよいしディレクトリでもよい)を指定するだけ。
cat > ./temp.lkml << EOF
view: view_name {
derived_table: {
sql: with cte as (select column_name from tablename where ts between current_date()-7 and current_date()) select column_name from cte ;;
}
dimension: column_name {
html:
{% if value == "foo" %}
<img src="https://example.com/foo"/>
{% else %}
<img src="https://example.com/bar"/>
{% endif %} ;;
}}
EOF
lkmlfmt ./temp.lkml
cat ./temp.lkml
# view: view_name {
# derived_table: {
# sql:
# with
# cte as (
# select column_name
# from tablename
# where ts between current_date() - 7 and current_date()
# )
# select column_name
# from cte
# ;;
# }
# dimension: column_name {
# html:
# {% if value == "foo" %}
# <img src="https://example.com/foo"/>
# {% else %}
# <img src="https://example.com/bar"/>
# {% endif %}
# ;;
# }
# }
フォーマッタあるあるだけれど、--check
オプションを付けるとフォーマット済みかどうかの確認だけ行う。そのほか細かいオプションはlkmlfmt --help
で確認できる。
GitHub Actions
LookMLをlocalで書くことは少ないだろうから、GitHubActionsで動くようにしておくと多分便利。Pull Requstがフォーマット済みか確認するならこんな感じ。
on: [pull_request]
jobs:
format-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11' # '>=3.11' is required
- run: pip install lkmlfmt
- run: lkmlfmt --check path/to/lookml/file/or/directory
特定のbranchに対してシュッとフォーマットのPull Requestを出すならこんな感じ。事前にSettings > Actions > GeneralからPull Requestの作成を許可する必要がある。
on: [workflow_dispatch]
jobs:
format-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11' # '>=3.11' is required
- run: pip install lkmlfmt
- run: lkmlfmt path/to/lookml/file/or/directory
- uses: peter-evans/create-pull-request@v5
with:
branch: format/${{ github.ref_name }}
もっとちゃんと運用するなら、依存packageを含めてversionを固定したり、installしたpackageをcacheしたりしておきたい。その場合requirements.txtをproject直下においてsetup-python
の部分を以下のようにするとよいはず3。
- uses: actions/setup-python@v4
with:
python-version: '3.11'
cache: 'pip' # 追記
今後
以下はまだできていないのでやっていく。
- liquidテンプレートの内側(
{%
と%}
とかで囲まれた部分)はまだフォーマットできない4のでやっていく - docstringをちゃんと書いたり、Pull Requestを受け付ける準備をする
バグも随時直すので、もし見つけたらこの記事のコメント欄やGitHubのIssueで報告してもらえるとありがたいです。