|
3 | 3 | [clojure.edn :as edn] |
4 | 4 | [clojure.set :as set] |
5 | 5 | [clojure.spec.alpha :as s] |
6 | | - [clojure.string :as str] |
7 | | - [clojure.tools.deps :as deps] |
8 | | - [clojure.tools.deps.util.maven :as mvn] |
9 | 6 | [namenu.deps-diff.output :as output] |
10 | 7 | [namenu.deps-diff.spec :as spec])) |
11 | 8 |
|
12 | | -;; from tools.gitlibs |
13 | | -(defn- run-git |
14 | | - [& args] |
15 | | - (let [command-args (cons "git" (map str args))] |
16 | | - (let [proc-builder (ProcessBuilder. ^java.util.List command-args) |
17 | | - proc (.start proc-builder) |
18 | | - exit (.waitFor proc) |
19 | | - out (slurp (.getInputStream proc)) |
20 | | - err (slurp (.getErrorStream proc))] |
21 | | - {:args command-args, :exit exit, :out out, :err err}))) |
22 | | - |
23 | | -(defn- read-edn |
24 | | - [path] |
25 | | - (cond |
26 | | - ;; file |
27 | | - (.exists (clojure.java.io/file path)) |
28 | | - (edn/read-string (slurp (str path))) |
29 | | - |
30 | | - ;; git |
31 | | - :else |
32 | | - (let [path (if (str/ends-with? path "deps.edn") |
33 | | - path |
34 | | - (str path ":" "deps.edn")) |
35 | | - sh (run-git "show" path)] |
36 | | - (when-not (zero? (:exit sh)) |
37 | | - (throw (ex-info (str "Couldn't fetch deps.edn from git ref " path) |
38 | | - {:output (:err sh)}))) |
39 | | - (edn/read-string (:out sh))))) |
40 | | - |
41 | | -(defn- resolve-deps [deps aliases] |
42 | | - (-> (deps/create-basis {:project (merge {:mvn/repos mvn/standard-repos} deps) |
43 | | - :aliases aliases}) |
44 | | - :libs |
45 | | - (update-vals #(s/conform ::spec/coord %)))) |
| 9 | +(defn- parse-resolved-tree [file] |
| 10 | + (let [deps-tree (edn/read-string (slurp (str file)))] |
| 11 | + (letfn [(walk [m] |
| 12 | + (mapcat (fn [[k v]] |
| 13 | + (into [[k (dissoc v :children)]] |
| 14 | + (walk (:children v)))) |
| 15 | + m))] |
| 16 | + (->> (walk (:children deps-tree)) |
| 17 | + (keep (fn [[k v]] |
| 18 | + (if (:include v) |
| 19 | + [k (s/conform ::spec/coord (:coord v))]))) |
| 20 | + (into {}))))) |
46 | 21 |
|
47 | 22 | (defmulti print-result! (fn [_ opts] (keyword (:format opts)))) |
48 | 23 |
|
|
59 | 34 | (output/cli data)) |
60 | 35 |
|
61 | 36 | (defn diff* |
62 | | - [{:keys [base target aliases]}] |
63 | | - (let [deps-from (resolve-deps (read-edn base) aliases) |
64 | | - deps-to (resolve-deps (read-edn target) aliases) |
65 | | - |
66 | | - key-set (comp set keys) |
| 37 | + [deps-from deps-to] |
| 38 | + (let [key-set (comp set keys) |
67 | 39 |
|
68 | 40 | [removed-deps added-deps common-deps] (data/diff (key-set deps-from) (key-set deps-to))] |
69 | 41 | ;; don't need to sort here |
|
75 | 47 | (defn diff |
76 | 48 | " |
77 | 49 | opts |
78 | | - :base - git sha |
79 | | - :target - file path |
80 | | - :aliases - seq of aliases to be used creating basis |
| 50 | + :base - tree shaped edn of base deps.edn |
| 51 | + :target - tree shaped edn of target deps.edn |
81 | 52 | :format - #{:edn, :markdown, :cli} |
82 | 53 | " |
83 | | - [{:keys [base target aliases format] :as opts}] |
| 54 | + [{:keys [base target format] :as opts}] |
84 | 55 | (assert (s/valid? ::spec/ref base)) |
85 | 56 | (assert (s/valid? ::spec/ref target)) |
86 | | - (assert (s/valid? ::spec/aliases aliases)) |
87 | 57 | (assert (s/valid? ::spec/format format)) |
88 | 58 |
|
89 | | - (let [d (diff* opts) |
| 59 | + (let [deps-from (parse-resolved-tree base) |
| 60 | + deps-to (parse-resolved-tree target) |
| 61 | + |
| 62 | + d (diff* deps-from deps-to) |
90 | 63 | exit-code (if (output/equal? d) 0 1)] |
91 | 64 | (print-result! d opts) |
92 | 65 | (System/exit exit-code))) |
|
95 | 68 | ;; git show e0f4689c07bc652492bf03eba7edac20ab2bee0f:test/resources/base.edn > base.edn |
96 | 69 | ;; clojure -X namenu.deps-diff/diff base.edn deps.edn |
97 | 70 |
|
98 | | - (diff* {:base "HEAD" :target "deps.edn" :format :cli}) |
99 | | - (diff* {:base "test-resources/base/deps.edn" |
100 | | - :target "test-resources/target/deps.edn" |
101 | | - :aliases [:poly]}) |
102 | | - |
103 | | - (diff* {:base "b2a1ca302959b720e703618a912a4b140389ee55" :target "deps.edn" |
104 | | - :format :cli}) |
105 | | - |
106 | | - (read-edn "HEAD:deps.edn") |
107 | | - |
108 | | - (resolve-deps (read-edn "HEAD:deps.edn") []) |
109 | | - (resolve-deps {:deps {'green-labs/gosura {:git/url "https://github.com/green-labs/gosura" |
110 | | - :git/sha "f1d586669f37a3ca99e14739f9abfb1a02128274"}} |
111 | | - :mvn/repos mvn/standard-repos |
112 | | - } |
113 | | - []) |
| 71 | + (diff* |
| 72 | + (parse-resolved-tree "test-resources/__base.edn") |
| 73 | + (parse-resolved-tree "test-resources/__target.edn")) |
114 | 74 |
|
115 | 75 | (make-ver |
116 | 76 | (s/conform ::spec/coord |
|
0 commit comments