From abf66de96be7e9682206eafefa5232ef6f3855a8 Mon Sep 17 00:00:00 2001 From: Lee Read Date: Thu, 16 Jan 2025 16:39:50 -0500 Subject: [PATCH] dev: bump clj-kondo (#689) Also: - bring in clj-kondo provided config for slingshot as a test dep - have clj-kondo move imports to current ./clj-kondo/imports location --- .../{ => imports}/babashka/fs/config.edn | 0 .../clj_kondo/slingshot/try_plus.clj | 0 .../clj-kondo/slingshot/config.edn | 0 .clj-kondo/imports/etaoin/etaoin/config.edn | 30 +++++ .../etaoin/etaoin/etaoin/api.clj_kondo | 113 ++++++++++++++++++ .../etaoin/etaoin/etaoin/api2.clj_kondo | 27 +++++ .../etaoin/etaoin/etaoin/hooks_util.clj_kondo | 6 + .../http-kit/http-kit/config.edn | 0 .../http-kit/httpkit/with_channel.clj | 0 .../lread/status-line/config.edn | 0 .../rewrite-clj/rewrite-clj/config.edn | 0 .../{ => imports}/taoensso/encore/config.edn | 0 .../taoensso/encore/taoensso/encore.clj | 0 .clj-kondo/potemkin/potemkin/config.edn | 62 ---------- .../potemkin/potemkin/potemkin/namespaces.clj | 56 --------- deps.edn | 6 +- 16 files changed, 180 insertions(+), 120 deletions(-) rename .clj-kondo/{ => imports}/babashka/fs/config.edn (100%) rename .clj-kondo/{ => imports}/clj-kondo/slingshot/clj_kondo/slingshot/try_plus.clj (100%) rename .clj-kondo/{ => imports}/clj-kondo/slingshot/config.edn (100%) create mode 100644 .clj-kondo/imports/etaoin/etaoin/config.edn create mode 100644 .clj-kondo/imports/etaoin/etaoin/etaoin/api.clj_kondo create mode 100644 .clj-kondo/imports/etaoin/etaoin/etaoin/api2.clj_kondo create mode 100644 .clj-kondo/imports/etaoin/etaoin/etaoin/hooks_util.clj_kondo rename .clj-kondo/{ => imports}/http-kit/http-kit/config.edn (100%) rename .clj-kondo/{ => imports}/http-kit/http-kit/httpkit/with_channel.clj (100%) rename .clj-kondo/{ => imports}/lread/status-line/config.edn (100%) rename .clj-kondo/{ => imports}/rewrite-clj/rewrite-clj/config.edn (100%) rename .clj-kondo/{ => imports}/taoensso/encore/config.edn (100%) rename .clj-kondo/{ => imports}/taoensso/encore/taoensso/encore.clj (100%) delete mode 100644 .clj-kondo/potemkin/potemkin/config.edn delete mode 100644 .clj-kondo/potemkin/potemkin/potemkin/namespaces.clj diff --git a/.clj-kondo/babashka/fs/config.edn b/.clj-kondo/imports/babashka/fs/config.edn similarity index 100% rename from .clj-kondo/babashka/fs/config.edn rename to .clj-kondo/imports/babashka/fs/config.edn diff --git a/.clj-kondo/clj-kondo/slingshot/clj_kondo/slingshot/try_plus.clj b/.clj-kondo/imports/clj-kondo/slingshot/clj_kondo/slingshot/try_plus.clj similarity index 100% rename from .clj-kondo/clj-kondo/slingshot/clj_kondo/slingshot/try_plus.clj rename to .clj-kondo/imports/clj-kondo/slingshot/clj_kondo/slingshot/try_plus.clj diff --git a/.clj-kondo/clj-kondo/slingshot/config.edn b/.clj-kondo/imports/clj-kondo/slingshot/config.edn similarity index 100% rename from .clj-kondo/clj-kondo/slingshot/config.edn rename to .clj-kondo/imports/clj-kondo/slingshot/config.edn diff --git a/.clj-kondo/imports/etaoin/etaoin/config.edn b/.clj-kondo/imports/etaoin/etaoin/config.edn new file mode 100644 index 00000000..f4d49326 --- /dev/null +++ b/.clj-kondo/imports/etaoin/etaoin/config.edn @@ -0,0 +1,30 @@ +{:linters + {:etaoin/with-x-action {:level :error} + :etaoin/binding-sym {:level :error} + :etaoin/opts-map-type {:level :error} + :etaoin/opts-map-pos {:level :error} + :etaoin/empty-opts {:level :warning}} + :hooks + {:analyze-call + {etaoin.api/with-chrome etaoin.api/with-browser + etaoin.api/with-chrome-headless etaoin.api/with-browser + etaoin.api/with-firefox etaoin.api/with-browser + etaoin.api/with-firefox-headless etaoin.api/with-browser + etaoin.api/with-edge etaoin.api/with-browser + etaoin.api/with-edge-headless etaoin.api/with-browser + etaoin.api/with-safari etaoin.api/with-browser + + etaoin.api/with-driver etaoin.api/with-driver + etaoin.api/with-key-down etaoin.api/with-key-down + etaoin.api/with-pointer-btn-down etaoin.api/with-pointer-btn-down + + ;; api2 moves to a more conventional let-ish vector syntax + etaoin.api2/with-chrome etaoin.api2/with-browser + etaoin.api2/with-chrome-headless etaoin.api2/with-browser + etaoin.api2/with-edge etaoin.api2/with-browser + etaoin.api2/with-edge-headless etaoin.api2/with-browser + etaoin.api2/with-firefox etaoin.api2/with-browser + etaoin.api2/with-firefox-headless etaoin.api2/with-browser + etaoin.api2/with-safari etaoin.api2/with-browser}} + :lint-as + {etaoin.api/with-pointer-left-btn-down clojure.core/->}} diff --git a/.clj-kondo/imports/etaoin/etaoin/etaoin/api.clj_kondo b/.clj-kondo/imports/etaoin/etaoin/etaoin/api.clj_kondo new file mode 100644 index 00000000..650b8b31 --- /dev/null +++ b/.clj-kondo/imports/etaoin/etaoin/etaoin/api.clj_kondo @@ -0,0 +1,113 @@ +(ns etaoin.api + (:require [clj-kondo.hooks-api :as api] + [etaoin.hooks-util :as h])) + +(defn- nil-node? [n] + (and (api/token-node? n) (nil? (api/sexpr n)))) + +(defn- with-bound-arg [node arg-offset] + (let [macro-args (rest (:children node)) + leading-args (take arg-offset macro-args) + interesting-args (drop arg-offset macro-args) + [opts binding-sym & body] (if (h/symbol-node? (second interesting-args)) + interesting-args + (cons nil interesting-args))] + ;; if the user has specified nil or {} for options we can suggest that is not necessary + (when (and opts + (or (and (api/map-node? opts) (not (seq (:children opts)))) + (nil-node? opts))) + (api/reg-finding! (assoc (meta opts) + :message "Empty or nil driver options can be omitted" + :type :etaoin/empty-opts))) + + (cond + (not (h/symbol-node? binding-sym)) + ;; it makes more sense here to report on the incoming node position instead of what we expect to be the binding-sym + (api/reg-finding! (assoc (meta node) + :message "Expected binding symbol for driver" + :type :etaoin/binding-sym)) + + ;; we don't want to explicitly expect a map because the map might come from + ;; an evalution, but we can do some checks + (and opts ;; we'll assume a list-node is a function call (eval) + (not (nil-node? opts)) ;; nil is actually old-v1 syntax acceptable + (not (api/list-node? opts)) ;; some fn call + (not (h/symbol-node? opts)) ;; from a binding maybe + ;; there are other eval node types... @(something) for example... maybe we'll add them in if folks ask + (not (api/map-node? opts))) + ;; we can report directly on the opts node, because at this point we know we expect + ;; this arg position to be an opts map + (api/reg-finding! (assoc (meta opts) + :message "When specified, opts should be a map" + :type :etaoin/opts-map-type)) + + ;; one last nicety, if the first form in body is a map, the user has accidentally swapped + ;; binding and opt args + (api/map-node? (first body)) + (api/reg-finding! (assoc (meta (first body)) + :message "When specified, opts must appear before binding symbol" + :type :etaoin/opts-map-pos)) + + :else + {:node (api/list-node + (list* + (api/token-node 'let) + ;; simulate the effect, macro is creating a new thing (driver for example) + ;; via binding it. I don't think the bound value matters for the linting process + (api/vector-node [binding-sym (api/map-node [])]) + ;; reference the other args so that they are not linted as unused + (api/vector-node leading-args) + opts ;; might be a binding, so ref it too + body))}))) + +(defn- with-x-down + "This is somewhat of a maybe an odd duck. + I think it is assumed to be used within a threading macro. + And itself employs a threadfirst macro. + So each body form need to have an action (dummy or not) threaded into it." + [node] + (let [macro-args (rest (:children node)) + [input x & body] macro-args + dummy-action (api/map-node [])] + {:node (api/list-node + (apply list* + (api/token-node 'do) + ;; reference x and input just in case they contain something lint-relevant + x input + ;; dump the body, threading a dummy action in as first arg + (map (fn [body-form] + (cond + ;; not certain this is absolutely what we want, but maybe close enough + (h/symbol-node? body-form) (api/list-node (list* body-form dummy-action)) + (api/list-node? body-form) (let [children (:children body-form)] + (assoc body-form :children (apply list* + (first children) + dummy-action + (rest children)))) + :else + (api/reg-finding! (assoc (meta body-form) + :message "expected to be threaded through an action" + :type :etaoin/with-x-action)))) + body)))})) + +(defn with-browser + "Covers etaoin.api/with-chrome and all its variants + [opt? bind & body]" + [{:keys [node]}] + (with-bound-arg node 0)) + +(defn with-driver + "Very similar to with-browser but bound arg is 1 deeper + [type opt? bind & body]" + [{:keys [node]}] + (with-bound-arg node 1)) + +(defn with-key-down + "[input key & body]" + [{:keys [node]}] + (with-x-down node)) + +(defn with-pointer-btn-down + "[input button & body]" + [{:keys [node]}] + (with-x-down node)) diff --git a/.clj-kondo/imports/etaoin/etaoin/etaoin/api2.clj_kondo b/.clj-kondo/imports/etaoin/etaoin/etaoin/api2.clj_kondo new file mode 100644 index 00000000..f5655c3a --- /dev/null +++ b/.clj-kondo/imports/etaoin/etaoin/etaoin/api2.clj_kondo @@ -0,0 +1,27 @@ +(ns etaoin.api2 + (:require [clj-kondo.hooks-api :as api] + [etaoin.hooks-util :as h])) + +(defn with-browser + "Newer variants for api2 + [[bind & [options]] & body]" + [{:keys [node]}] + (let [macro-args (rest (:children node)) + binding-like-vector (first macro-args)] + (if-not (api/vector-node? binding-like-vector) + ;; could use clj-kondo findings, but I think this is good for now + (throw (ex-info "Expected vector for first arg" {})) + (let [binding-sym (-> binding-like-vector :children first)] + (if-not (h/symbol-node? binding-sym) + (throw (ex-info "Expected binding symbol for first arg in vector" {})) + (let [other-args (rest binding-like-vector) + body (rest macro-args)] + {:node (api/list-node + (list* + (api/token-node 'let) + ;; simulate the effect, macro is creating a new thing (driver for example) + ;; via binding it. I don't think the bound value matters for the linting process + (api/vector-node [binding-sym (api/map-node [])]) + ;; reference the other args so that they are not linted as unused + (api/vector-node other-args) + body))})))))) diff --git a/.clj-kondo/imports/etaoin/etaoin/etaoin/hooks_util.clj_kondo b/.clj-kondo/imports/etaoin/etaoin/etaoin/hooks_util.clj_kondo new file mode 100644 index 00000000..cd416a0b --- /dev/null +++ b/.clj-kondo/imports/etaoin/etaoin/etaoin/hooks_util.clj_kondo @@ -0,0 +1,6 @@ +(ns etaoin.hooks-util + (:require [clj-kondo.hooks-api :as api])) + +(defn symbol-node? [node] + (and (api/token-node? node) + (symbol? (api/sexpr node)))) diff --git a/.clj-kondo/http-kit/http-kit/config.edn b/.clj-kondo/imports/http-kit/http-kit/config.edn similarity index 100% rename from .clj-kondo/http-kit/http-kit/config.edn rename to .clj-kondo/imports/http-kit/http-kit/config.edn diff --git a/.clj-kondo/http-kit/http-kit/httpkit/with_channel.clj b/.clj-kondo/imports/http-kit/http-kit/httpkit/with_channel.clj similarity index 100% rename from .clj-kondo/http-kit/http-kit/httpkit/with_channel.clj rename to .clj-kondo/imports/http-kit/http-kit/httpkit/with_channel.clj diff --git a/.clj-kondo/lread/status-line/config.edn b/.clj-kondo/imports/lread/status-line/config.edn similarity index 100% rename from .clj-kondo/lread/status-line/config.edn rename to .clj-kondo/imports/lread/status-line/config.edn diff --git a/.clj-kondo/rewrite-clj/rewrite-clj/config.edn b/.clj-kondo/imports/rewrite-clj/rewrite-clj/config.edn similarity index 100% rename from .clj-kondo/rewrite-clj/rewrite-clj/config.edn rename to .clj-kondo/imports/rewrite-clj/rewrite-clj/config.edn diff --git a/.clj-kondo/taoensso/encore/config.edn b/.clj-kondo/imports/taoensso/encore/config.edn similarity index 100% rename from .clj-kondo/taoensso/encore/config.edn rename to .clj-kondo/imports/taoensso/encore/config.edn diff --git a/.clj-kondo/taoensso/encore/taoensso/encore.clj b/.clj-kondo/imports/taoensso/encore/taoensso/encore.clj similarity index 100% rename from .clj-kondo/taoensso/encore/taoensso/encore.clj rename to .clj-kondo/imports/taoensso/encore/taoensso/encore.clj diff --git a/.clj-kondo/potemkin/potemkin/config.edn b/.clj-kondo/potemkin/potemkin/config.edn deleted file mode 100644 index 3f59f3e8..00000000 --- a/.clj-kondo/potemkin/potemkin/config.edn +++ /dev/null @@ -1,62 +0,0 @@ -{:lint-as {potemkin.collections/compile-if clojure.core/if - potemkin.collections/reify-map-type clojure.core/reify - potemkin.collections/def-map-type clj-kondo.lint-as/def-catch-all - potemkin.collections/def-derived-map clj-kondo.lint-as/def-catch-all - - potemkin.types/reify+ clojure.core/reify - potemkin.types/defprotocol+ clojure.core/defprotocol - potemkin.types/deftype+ clojure.core/deftype - potemkin.types/defrecord+ clojure.core/defrecord - potemkin.types/definterface+ clojure.core/defprotocol - potemkin.types/extend-protocol+ clojure.core/extend-protocol - potemkin.types/def-abstract-type clj-kondo.lint-as/def-catch-all - - potemkin.utils/doit clojure.core/doseq - potemkin.utils/doary clojure.core/doseq - potemkin.utils/condp-case clojure.core/condp - potemkin.utils/fast-bound-fn clojure.core/bound-fn - - potemkin.walk/prewalk clojure.walk/prewalk - potemkin.walk/postwalk clojure.walk/postwalk - potemkin.walk/walk clojure.walk/walk - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;; top-level from import-vars - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ;; Have hooks - ;;potemkin/import-fn potemkin.namespaces/import-fn - ;;potemkin/import-macro potemkin.namespaces/import-macro - ;;potemkin/import-def potemkin.namespaces/import-def - - ;; Internal, not transitive - ;;potemkin/unify-gensyms potemkin.macros/unify-gensyms - ;;potemkin/normalize-gensyms potemkin.macros/normalize-gensyms - ;;potemkin/equivalent? potemkin.macros/equivalent? - - potemkin/condp-case clojure.core/condp - potemkin/doit potemkin.utils/doit - potemkin/doary potemkin.utils/doary - - potemkin/def-abstract-type clj-kondo.lint-as/def-catch-all - potemkin/reify+ clojure.core/reify - potemkin/defprotocol+ clojure.core/defprotocol - potemkin/deftype+ clojure.core/deftype - potemkin/defrecord+ clojure.core/defrecord - potemkin/definterface+ clojure.core/defprotocol - potemkin/extend-protocol+ clojure.core/extend-protocol - - potemkin/reify-map-type clojure.core/reify - potemkin/def-derived-map clj-kondo.lint-as/def-catch-all - potemkin/def-map-type clj-kondo.lint-as/def-catch-all} - - ;; leave import-vars alone, kondo special-cases it - :hooks {:macroexpand {#_#_potemkin.namespaces/import-vars potemkin.namespaces/import-vars - potemkin.namespaces/import-fn potemkin.namespaces/import-fn - potemkin.namespaces/import-macro potemkin.namespaces/import-macro - potemkin.namespaces/import-def potemkin.namespaces/import-def - - #_#_potemkin/import-vars potemkin.namespaces/import-vars - potemkin/import-fn potemkin.namespaces/import-fn - potemkin/import-macro potemkin.namespaces/import-macro - potemkin/import-def potemkin.namespaces/import-def}}} diff --git a/.clj-kondo/potemkin/potemkin/potemkin/namespaces.clj b/.clj-kondo/potemkin/potemkin/potemkin/namespaces.clj deleted file mode 100644 index a247af5c..00000000 --- a/.clj-kondo/potemkin/potemkin/potemkin/namespaces.clj +++ /dev/null @@ -1,56 +0,0 @@ -(ns potemkin.namespaces - (:require [clj-kondo.hooks-api :as api])) - -(defn import-macro* - ([sym] - `(def ~(-> sym name symbol) ~sym)) - ([sym name] - `(def ~name ~sym))) - -(defmacro import-fn - ([sym] - (import-macro* sym)) - ([sym name] - (import-macro* sym name))) - -(defmacro import-macro - ([sym] - (import-macro* sym)) - ([sym name] - (import-macro* sym name))) - -(defmacro import-def - ([sym] - (import-macro* sym)) - ([sym name] - (import-macro* sym name))) - -#_ -(defmacro import-vars - "Imports a list of vars from other namespaces." - [& syms] - (let [unravel (fn unravel [x] - (if (sequential? x) - (->> x - rest - (mapcat unravel) - (map - #(symbol - (str (first x) - (when-let [n (namespace %)] - (str "." n))) - (name %)))) - [x])) - syms (mapcat unravel syms) - result `(do - ~@(map - (fn [sym] - (let [vr (resolve sym) - m (meta vr)] - (cond - (nil? vr) `(throw (ex-info (format "`%s` does not exist" '~sym) {})) - (:macro m) `(def ~(-> sym name symbol) ~sym) - (:arglists m) `(def ~(-> sym name symbol) ~sym) - :else `(def ~(-> sym name symbol) ~sym)))) - syms))] - result)) diff --git a/deps.edn b/deps.edn index 14fee40f..4eb0459a 100644 --- a/deps.edn +++ b/deps.edn @@ -24,7 +24,9 @@ org.babashka/cli {:mvn/version "0.8.62"} ch.qos.logback/logback-classic {:mvn/version "1.3.15"} ;; for http-client which uses apache http client 4.x which uses commons logging - org.slf4j/jcl-over-slf4j {:mvn/version "2.0.16"}} + org.slf4j/jcl-over-slf4j {:mvn/version "2.0.16"} + ;; slingshot does not have a kondo config, grab kondo team provided config from here + io.github.clj-kondo/config-slingshot-slingshot {:mvn/version "1.0.0"}} :exec-fn test-shared/test :org.babashka/cli {:coerce {:nses [:symbol] :patterns [:string] @@ -61,7 +63,7 @@ :jvm-opts ["-Dclojure.storm.instrumentOnlyPrefixes=etaoin"]} ;; for consistent linting we use a specific version of clj-kondo through the jvm - :clj-kondo {:extra-deps {clj-kondo/clj-kondo {:mvn/version "2024.11.14"}} + :clj-kondo {:extra-deps {clj-kondo/clj-kondo {:mvn/version "2025.01.16"}} :main-opts ["-m" "clj-kondo.main"]} :eastwood {:extra-deps {jonase/eastwood {:mvn/version "1.4.3"}}