Last active
July 21, 2023 21:27
-
-
Save ethpran/e1741a5c408aec831b5e3a7e24f40fea to your computer and use it in GitHub Desktop.
clj-kondo hook for mount/defstate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{:linters {:mount/defstate {:level :warning}} | |
:hooks {:analyze-call {mount.core/defstate hooks.defstate/defstate}}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns hooks.defstate | |
(:require [clj-kondo.hooks-api :as api])) | |
(defn defstate [{:keys [:node]}] | |
(let [args (rest (:children node)) | |
args (if (string? (api/sexpr (first args))) | |
(next args) | |
args) | |
[n & args] args | |
m (when-let [m (first (:meta n))] | |
(api/sexpr m)) | |
m (if (map? m) m {}) | |
ks (cond-> (take 1 args) | |
(> (count args) 2) (conj (nth args 2))) | |
invalid-key (first (remove (comp (partial contains? #{:start :stop}) api/sexpr) ks))] | |
(cond | |
invalid-key | |
(api/reg-finding! | |
{:message (str "lifecycle functions can only contain `:start` and `:stop`. illegal function found: " (api/sexpr invalid-key)) | |
:type :mount/defstate | |
:row (:row (meta invalid-key)) | |
:col (:col (meta invalid-key))}) | |
(not (contains? (set (map api/sexpr ks)) :start)) | |
(throw (ex-info "lifecycle functions must include `:start`" {})) | |
((complement contains?) #{2 4} (count args)) | |
(throw (ex-info "lifecycle functions must consist of no more than 2 pair forms: `:start` and `:stop`" {})) | |
(and (contains? m :on-reload) (not (contains? #{:noop :stop} (:on-reload m)))) | |
(api/reg-finding! | |
{:message "metadata `:on-reload` key can only have value of `noop` or `stop`" | |
:type :mount/defstate | |
:row (:row (meta n)) | |
:col (:col (meta n))}) | |
:else | |
{:node (api/list-node | |
(list* | |
(api/token-node 'fn*) | |
(api/vector-node [n]) | |
n | |
args))}))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for this!