-
Notifications
You must be signed in to change notification settings - Fork 13
/
try.clj
80 lines (69 loc) · 2.92 KB
/
try.clj
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
(ns leiningen.try
(:require [leiningen.core.project :as prj]
[leiningen.core.main :as main]))
(defn- version-string?
"Check if a given String represents a version number."
[^String s]
(or (contains? #{"RELEASE" "LATEST"} s)
(Character/isDigit (first s))))
(def ->dep-pairs
"From a sequence of command-line args describing dependency-version pairs,
return a list of vector pairs. If no version is given, 'RELEASE' will be
used.
Example:
(->dep-pairs [\"clj-time\" \"\\\"0.5.1\\\"]\"])
; -> ([clj-time \"0.5.1\"])
(->dep-pairs [\"clj-time\" \"\\\"0.5.1\\\"\"])
; -> ([clj-time \"0.5.1\"])
(->dep-pairs [\"clj-time\" \"conformity\"])
; -> ([clj-time \"RELEASE\"] [conformity \"RELEASE\"])"
(letfn [(lazy-convert [args]
(lazy-seq
(when (seq args)
(let [[^String artifact-str & rst] args
artifact (symbol artifact-str)]
(if-let [[^String v & nxt] (seq rst)]
(if (version-string? v)
(cons [artifact v] (lazy-convert nxt))
(cons [artifact "RELEASE"] (lazy-convert rst)))
(vector [artifact "RELEASE"]))))))]
(fn [args]
(lazy-convert args))))
(defn- add-try-deps
"Add list of try-dependencies to project."
[deps project]
(update-in project [:profiles :try :dependencies] (comp vec concat) deps))
(defn add-reload-data-readers-injection
"Add injection to project map that lets the REPL reload data readers. This is necessary
in cases where no new JVM is spun up, thus `clojure.core` and the available data readers
are not reloaded."
[project]
(if (or (= (:eval-in project) :leiningen)
(:eval-in-leiningen project))
(update-in project [:profiles :try :injections] conj
`(or
(when-let [v# (resolve 'clojure.core/load-data-readers)]
(when-let [f# (var-get v#)]
(when (fn? f#)
(set! *data-readers* (merge *data-readers* (f#))))))
(println "Could not reload Data Readers ...")))
project))
(defn- start-try-repl!
"Resolve try-dependencies and start REPL."
[project]
(let [project (-> project
add-reload-data-readers-injection
;; Necessary to update project map metadata Lein uses internally
prj/project-with-profiles
(prj/merge-profiles [:try]))]
(main/apply-task "repl" project nil)))
(defn ^:no-project-needed ^:higher-order try
"Launch REPL with specified dependencies available.
Usage:
lein try io.rkn/conformity \"0.2.1\" com.datomic/datomic-free \"0.8.4020.26\"
lein try io.rkn/conformity 0.2.1
lein try io.rkn/conformity # This uses the most recent version"
[project & args]
(let [dependencies (->dep-pairs args)
project (add-try-deps dependencies project)]
(start-try-repl! project)))