Skip to content

Commit

Permalink
dev: bump clj-kondo (#689)
Browse files Browse the repository at this point in the history
Also:
- bring in clj-kondo provided config for slingshot as a test dep
- have clj-kondo move imports to current ./clj-kondo/imports location
  • Loading branch information
lread authored Jan 16, 2025
1 parent 2ebeb18 commit abf66de
Show file tree
Hide file tree
Showing 16 changed files with 180 additions and 120 deletions.
File renamed without changes.
File renamed without changes.
30 changes: 30 additions & 0 deletions .clj-kondo/imports/etaoin/etaoin/config.edn
Original file line number Diff line number Diff line change
@@ -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/->}}
113 changes: 113 additions & 0 deletions .clj-kondo/imports/etaoin/etaoin/etaoin/api.clj_kondo
Original file line number Diff line number Diff line change
@@ -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))
27 changes: 27 additions & 0 deletions .clj-kondo/imports/etaoin/etaoin/etaoin/api2.clj_kondo
Original file line number Diff line number Diff line change
@@ -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))}))))))
6 changes: 6 additions & 0 deletions .clj-kondo/imports/etaoin/etaoin/etaoin/hooks_util.clj_kondo
Original file line number Diff line number Diff line change
@@ -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))))
File renamed without changes.
File renamed without changes.
File renamed without changes.
62 changes: 0 additions & 62 deletions .clj-kondo/potemkin/potemkin/config.edn

This file was deleted.

56 changes: 0 additions & 56 deletions .clj-kondo/potemkin/potemkin/potemkin/namespaces.clj

This file was deleted.

6 changes: 4 additions & 2 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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"}}
Expand Down

0 comments on commit abf66de

Please sign in to comment.