Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Print API breakage warnings
#!/usr/bin/env bb
;; Example usage:
;; api_diff_bb.clj org.clojure/clojure "1.9.0" "1.10.1"
;; Output:
;; clojure/core_deftype.clj:587:1: warning: Arity 4 of clojure.core/emit-method-builder was removed.
;; clojure/core/reducers.clj:24:1: warning: clojure.core.reducers/compile-if was removed.
(require '[babashka.pods :as pods])
(pods/load-pod 'borkdude/clj-kondo "2020.12.12")
(require '[pod.borkdude.clj-kondo :as clj-kondo])
(require '[clojure.edn :as edn])
(def lib (edn/read-string (first *command-line-args*)))
(def v1 (second *command-line-args*))
(def v2 (nth *command-line-args* 2))
(require '[babashka.deps :as deps])
(require '[clojure.string :as str])
(require '[babashka.classpath :as cp])
(defn path [lib v]
(let [deps `{:deps {~lib {:mvn/version ~v}}}
_ (deps/add-deps deps)
cp (cp/split-classpath (cp/get-classpath))
cp (reverse cp)
lib (str/replace lib "." "/")]
(some #(when (str/includes? % lib)
%) cp)))
(def path1 (path lib v1))
(def path2 (path lib v2))
(defn index-by
[f coll]
(persistent! (reduce #(assoc! %1 (f %2) %2) (transient {}) coll)))
(defn group [vars]
(->> vars
(map #(select-keys % [:ns :name :fixed-arities :varargs-min-arity]))
(index-by (juxt :ns :name))))
(defn vars [lib]
(-> (clj-kondo/run! {:lint [lib] :config {:output {:analysis true :format :edn}}})
:analysis :var-definitions))
(def vars-1 (vars path1))
(def vars-2 (vars path2))
(defn var-symbol [[k v]]
(str k "/" v))
(def compare-group-1 (group vars-1))
(def compare-group-2 (group vars-2))
(def lookup-1 (index-by (juxt :ns :name) vars-1))
(doseq [[k var-1] compare-group-1]
(if-let [var-2 (get compare-group-2 k)]
(let [fixed-arities-v1 (:fixed-arities var-1)
fixed-arities-v2 (:fixed-arities var-2)
varargs-min-arity (:varargs-min-arity var-2)]
(doseq [arity fixed-arities-v1]
(when-not (or (contains? fixed-arities-v2 arity)
(and varargs-min-arity (>= arity varargs-min-arity)))
(let [{:keys [:filename :row :col :private]} (get lookup-1 k)]
(println (str filename ":" row ":" col ":") (str (if private "warning" "error") ":")
"Arity" arity "of" (var-symbol k) "was removed.")))))
(let [{:keys [:filename :row :col :private]} (get lookup-1 k)]
(println (str filename ":" row ":" col ":") (str (if private "warning" "error") ":")
(var-symbol k) "was removed."))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment