From 8441208d29eba9adddeb8ac13d7ad7c760a8b830 Mon Sep 17 00:00:00 2001 From: liquidz Date: Sat, 19 Oct 2024 13:34:28 +0900 Subject: [PATCH] fix: Update clj-kondo component not to use babashka.pods --- resources/config.edn | 3 +- src/elin/component/clj_kondo.clj | 64 +++++++++++++++++++++----------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/resources/config.edn b/resources/config.edn index 45c025b4..ddb63b84 100644 --- a/resources/config.edn +++ b/resources/config.edn @@ -85,5 +85,6 @@ :initialize {:export {"g:elin_http_server_port" #ref [:http-server :port]}}} - :clj-kondo {:config {:output {:analysis {:protocol-impls true + :clj-kondo {:command "clj-kondo" + :config {:output {:analysis {:protocol-impls true :arglists true}}}}} diff --git a/src/elin/component/clj_kondo.clj b/src/elin/component/clj_kondo.clj index 5979c646..ff686205 100644 --- a/src/elin/component/clj_kondo.clj +++ b/src/elin/component/clj_kondo.clj @@ -1,6 +1,9 @@ (ns elin.component.clj-kondo + "NOTE: + When using `babashka.pods`, repeatedly running linting on a large codebase caused the memory usage to gradually increase, affecting performance. + Therefore, instead of using pods, we switched to starting the `clj-kondo` process each time it’s needed." (:require - [babashka.pods :as b.pods] + [babashka.process :as b.process] [clojure.core.async :as async] [clojure.edn :as edn] [clojure.java.io :as io] @@ -10,6 +13,7 @@ [elin.protocol.clj-kondo :as e.p.clj-kondo] [elin.protocol.host :as e.p.host] [elin.util.file :as e.u.file] + [malli.core :as m] [taoensso.timbre :as timbre])) (defn- get-project-root-directory @@ -26,27 +30,46 @@ (str (str/replace user-dir "/" "_") ".edn")))) -(def clj-kondo-available? +(m/=> clj-kondo-available? [:=> [:cat string?] boolean?]) +(defn- clj-kondo-available? + [command] (try - (b.pods/load-pod "clj-kondo") - true + (zero? (:exit (b.process/shell command "--version"))) (catch Exception _ false))) -(when clj-kondo-available? - (require '[pod.borkdude.clj-kondo :as clj-kondo])) +(defn- clj-kondo-run! + [{:keys [command lint config shell-config]}] + (try + (let [lint-args (->> (or lint []) + (map #(vector "--lint" %))) + config' (assoc-in config [:output :format] :edn)] + (->> [command lint-args "--config" (pr-str config')] + (flatten) + (apply b.process/shell (merge {:out :string :continue true} + shell-config)) + (:out) + (edn/read-string))) + (catch Exception ex + (timbre/info "Failed to run clj-kondo" ex) + {}))) (defrecord CljKondo [;; COMPONENTS lazy-host ;; CONFIGS + command config ;; PARAMS + available? analyzing?-atom analyzed-atom] component/Lifecycle (start [this] (timbre/info "CljKondo component: Started") (assoc this + :available? (if command + (clj-kondo-available? command) + false) :analyzing?-atom (atom false) :analyzed-atom (atom nil))) @@ -57,7 +80,7 @@ e.p.clj-kondo/ICljKondo (analyze [this] (cond - (not clj-kondo-available?) + (not available?) (async/go (e/unavailable {:message "clj-kondo is unavailable"})) (e.p.clj-kondo/analyzing? this) @@ -67,9 +90,9 @@ (do (reset! analyzing?-atom true) (async/thread (try - #_{:clj-kondo/ignore [:unresolved-namespace]} (e/let [project-root-dir (get-project-root-directory lazy-host) - res (clj-kondo/run! {:lint [project-root-dir] + res (clj-kondo-run! {:command command + :lint [project-root-dir] :config config}) cache-path (get-cache-file-path project-root-dir)] (spit cache-path (pr-str res)) @@ -79,7 +102,7 @@ (restore [this] (cond - (not clj-kondo-available?) + (not available?) (async/go (e/unavailable {:message "clj-kondo is unavailable"})) (e.p.clj-kondo/analyzing? this) @@ -106,22 +129,19 @@ (some? @analyzed-atom)) (analysis [this] - (when (and clj-kondo-available? + (when (and available? (e.p.clj-kondo/analyzed? this)) (:analysis @analyzed-atom))) (analyze-code!! [_ code] - (when clj-kondo-available? - (let [file (java.io.File/createTempFile (str (random-uuid)) ".clj")] - (try - (spit file code) - (clj-kondo/run! {:lint [(.getAbsolutePath file)] - :config {:output {:analysis {:protocol-impls true - :arglists true - :locals true - :keywords true}}}}) - (finally - (.delete file))))))) + (when available? + (clj-kondo-run! {:command command + :lint ["-"] + :config {:output {:analysis {:protocol-impls true + :arglists true + :locals true + :keywords true}}} + :shell-config {:in code}})))) (defn new-clj-kondo [config]