2022-01-08 追記 ここから =====
cljstyle を教えてもらったー!
2022-01-08 追記 ここまで =====
cljfmt をサクサク動かしたいのやー
↓Clojure 用の Linter の clj-kondo は GraalVM で Native Image 化してあるのでサクサク動く
GitHub - clj-kondo/clj-kondo: A linter for Clojure code that sparks joy.
↓でも、Clojure 用の Formatter の cljfmt は Leiningen で動かさないといけないので遅い
GitHub - weavejester/cljfmt: A tool for formatting Clojure code
cljfmt も Native Image があったらいいのになぁ
って思って探してみたら
↓こういうのが見つかった
Konrad Mrozek / cljfmt-graalvm · GitLab
けど、ちょっとバージョンが古いし、独自スクリプトでラップしてて、オプションをサポートしてないみたい?なので、もっといい感じのないかなぁ?そのまま cljfmt の機能を全部使いたいんだよなぁって思ってたら
↓あれ?本家に PR あるやん?しかもマージされてるやん?おお?
Native image by bsless · Pull Request #186 · weavejester/cljfmt · GitHub
ということでビルドしてみるー
M1 Mac なんだけどいけるかなぁ???
GraalVM の準備
SDKMAN! で GraalVM をインストールして、最後に「デフォルトにする?」って聞かれるけど、したくないので No にして
❯ sdk i java 21.3.0.r17-grl Do you want java 21.3.0.r17-grl to be set as default? (Y/n): n
今のシェルでだけで GraalVM を使うようにして
❯ sdk use java 21.3.0.r17-grl Using java version 21.3.0.r17-grl in this shell.
Native Image をインストール
❯ gu install native-image Downloading: Release index file from oca.opensource.oracle.com Downloading: Component catalog from www.graalvm.org Processing Component: Native Image Downloading: Component native-image: Native Image from github.com Installing new component: Native Image (org.graalvm.native-image, version 21.3.0)
これで GraalVM の準備は OK
ビルドの準備
cljfmt のソースコードを clone してきて、プロジェクトの中の cljfmt フォルダに入る
❯ git clone git@github.com:weavejester/cljfmt.git ❯ cd cljfmt/cljfmt
↓lein-native-image ってプラグインがあるんだねー。便利
GitHub - taylorwood/lein-native-image: A Leiningen plugin to build GraalVM native images
これを使ってビルドするんだけど、そのままだとビルドが通らない↓
❯ lein native-image Compiling ClojureScript... Reloading Clojure file "cljfmt.test-util.common" failed. clojure.lang.Compiler$CompilerException: Syntax error compiling at (cljfmt/test_util/common.cljc:1:1).
よく分かんないけど project.clj の :hooks に書いてある cljsbuild をコメントアウトすればいいのかな?↓
;; :hooks [leiningen.cljsbuild]
はいビルド
❯ lein native-image ... [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] (clinit): 386.71 ms, 2.51 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] (typeflow): 15,335.96 ms, 2.51 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] (objects): 36,926.89 ms, 2.51 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] (features): 4,169.75 ms, 2.51 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] analysis: 58,275.88 ms, 2.51 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] universe: 3,879.56 ms, 2.47 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] (parse): 4,026.37 ms, 2.31 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] (inline): 3,612.80 ms, 2.24 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] (compile): 34,094.63 ms, 2.37 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] compile: 43,646.86 ms, 2.37 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] image: 3,863.29 ms, 2.30 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] write: 3,045.97 ms, 2.33 GB [/Users/..../cljfmt/cljfmt/target/cljfmt:38771] [total]: 127,314.04 ms, 2.33 GB # Printing build artifacts to: /Users/..../cljfmt/cljfmt/target/cljfmt.build_artifacts.txt Created native image /Users/..../cljfmt/cljfmt/target/cljfmt
お。できたっぽい!Native Image のビルドだから10分くらい覚悟してたけど2分で終わった!平和な気持ち。
パスの通ったところに置いとこか
❯ sudo cp target/cljfmt /usr/local/bin ❯ cljfmt cljfmt [OPTIONS] COMMAND [PATHS ...] --help --file-pattern FILE_PATTERN \.clj[csx]?$ --indents INDENTS_PATH --alias-map ALIAS_MAP_PATH --project-root PROJECT_ROOT . --[no-]ansi --[no-]indentation --[no-]remove-multiple-non-indenting-spaces --[no-]remove-surrounding-whitespace --[no-]remove-trailing-whitespace --[no-]insert-missing-whitespace --[no-]remove-consecutive-blank-lines
動かすー
適当なプロジェクトで試してみる。まずは普通に lein で実行した場合
❯ time lein cljfmt check ... 13 file(s) formatted incorrectly lein cljfmt check . 7.67s user 3.48s system 104% cpu 10.678 total
10秒!遅い!
Native Image で実行した場合
❯ time cljfmt check ... 13 file(s) formatted incorrectly cljfmt check . 0.41s user 0.08s system 96% cpu 0.513 total
0.5秒!良い!
IDEA に設定
この速さなら保存するたびに実行するんでもいけるぞー!って、FileWatcher プラグインで保存時に実行されるように設定してみたけど、IDEA の自動保存で書いてる途中にフォーマットされてしまうのでちょっと無理だったw
なので、External Tools に設定して、ショートカットで実行するようにしておいた。便利。
おしまい!
GraalVM (Native Image) すごいなー。そして cljfmt の公式で Native Image のビルド設定が入ってて素敵!