forked from technomancy/leiningen
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeps.clj
More file actions
144 lines (128 loc) · 5.28 KB
/
Copy pathdeps.clj
File metadata and controls
144 lines (128 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
(ns leiningen.deps
"Download all dependencies."
(:require [leiningen.core.classpath :as classpath]
[leiningen.core.main :as main]
[leiningen.core.eval :as eval]
[leiningen.core.user :as user]
[cemerick.pomegranate.aether :as aether]
[clojure.pprint :as pp]
[clojure.java.io :as io])
(:import (org.sonatype.aether.resolution DependencyResolutionException)
(org.sonatype.aether.collection DependencyGraphTransformer)
(org.sonatype.aether.util.graph.transformer
ChainedDependencyGraphTransformer)))
(defn message-for-version-range [path]
(str (->> path
(map #(if-let [dependency (.getDependency %)]
(if-let [artifact (.getArtifact dependency)]
(str "["
(.getGroupId artifact)
"/"
(.getArtifactId artifact)
" \""
(.getVersionConstraint %)
"\"]"))))
(remove nil?)
(interpose " -> ")
(apply str))))
(def ranges (atom []))
(defn- check-for-range [node parents]
(if-let [vc (.getVersionConstraint node)]
(if-not (empty? (.getRanges vc))
(swap! ranges conj (conj parents node))))
(every? #(check-for-range % (conj parents node))
(.getChildren node)))
(defn add-no-ranges-transformer [session]
(.setDependencyGraphTransformer
session
(ChainedDependencyGraphTransformer.
(into-array DependencyGraphTransformer
[(reify DependencyGraphTransformer
(transformGraph [self node context]
(reset! ranges [])
(check-for-range node [])
node))
(.getDependencyGraphTransformer session)]))))
(defn- walk-deps
([deps f level]
(doseq [[dep subdeps] deps]
(f dep level)
(when subdeps
(walk-deps subdeps f (inc level)))))
([deps f]
(walk-deps deps f 0)))
(defn- print-dep [dep level]
(println (apply str (repeat (* 2 level) \space)) (pr-str dep)))
(declare check-signature)
(defn- fetch-key [signature err]
(if (re-find #"Can't check signature: public key not found" err)
(let [key (second (re-find #"using \w+ key ID (.+)" err))
{:keys [exit]} (user/gpg "--recv-keys" "--" key)]
(if (zero? exit)
(check-signature signature)
:no-key))
:bad-signature))
(defn- check-signature [signature]
(let [{:keys [err exit]} (user/gpg "--verify" "--" (str signature))]
(if (zero? exit)
:signed ; TODO distinguish between signed and trusted
(fetch-key signature err))))
(defn- get-signature [project dep]
(let [dep-map (assoc (apply hash-map (drop 2 dep))
;; TODO: check pom signature too
:extension "jar.asc")
dep (into (vec (take 2 dep)) (apply concat dep-map))]
(try (->> (aether/resolve-dependencies
:repositories (:repositories project)
:mirrors (:mirrors project)
:coordinates [dep])
(aether/dependency-files)
(filter #(.endsWith (.getName %) ".asc"))
(first))
(catch DependencyResolutionException _))))
(defn- verify [project dep _]
(let [signature (get-signature project dep)
status (if signature
(check-signature signature)
:unsigned)]
;; TODO: support successful exit code only on fully-signed deps
(println status (pr-str dep))))
(defn deps
"Show details about dependencies.
USAGE: lein deps :tree
Show the full dependency tree for the current project.
USAGE: lein deps :verify
Check signatures of each dependency. ALPHA: subject to change.
USAGE: lein deps
Force Leiningen to download the dependencies it needs. This usage is
deprecated as it should happen automatically on demand.
Normally snapshot dependencies will be checked once every 24 hours; to
force them to be updated, use `lein -U $TASK`."
([project]
(deps project nil))
([project command]
(try
(cond (= command ":tree")
(let [hierarchy (classpath/dependency-hierarchy
:dependencies project
:repository-session-fn
(comp add-no-ranges-transformer
aether/repository-session))
ranges (distinct (map message-for-version-range
@ranges))]
(when (not (empty? ranges))
(println "WARNING!!! version ranges found for:")
(doseq [dep-string ranges]
(println dep-string))
(println))
(walk-deps hierarchy
print-dep))
(= command ":verify")
(if (user/gpg-available?)
(walk-deps (classpath/dependency-hierarchy :dependencies project)
(partial verify project))
(main/abort
"Could not verify - gpg not available.\nSee `lein help gpg` for how to setup gpg."))
:else (classpath/resolve-dependencies :dependencies project))
(catch DependencyResolutionException e
(main/abort (.getMessage e))))))