Skip to content

Commit 1a76579

Browse files
committed
Expose repl task dependencies
The repl task is special because it can't run in a pod. It needs to run in the project context and have access to the environment of the build.boot script. In order to keep the project classpath pristine when the REPL is not in use, the nREPL dependencies are not loaded until the repl task actually needs to run. This presents difficulties with middleware, since most of these are in namespaces that assume tools.nrepl is available. To support middlware in this environment we expose two atoms: - boot.repl/*default-dependencies* atom containing a vector of maven coordinates in the (set-env! :dependencies '[...]) format. These dependencies will be added only when the repl task is run, and only if the project does not already have explicit dependencies for the deps it would otherwise load. - boot.repl/*default-middleware* atom containing a vector of namespace qualified symbols corresponding to desired middleware. The repl task will resolve them at runtime as necessary, so they don't need to be resolvable from the build.boot. Modify these to change dependencies or middleware loaded by default by the repl task. The middleware option to the repl task adds middleware in addition to these defaults. The handler option will override these.
1 parent d2430b3 commit 1a76579

File tree

4 files changed

+48
-20
lines changed

4 files changed

+48
-20
lines changed

boot/core/src/boot/repl.clj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(ns boot.repl)
2+
3+
(def ^:dynamic *default-dependencies*
4+
(atom '[[org.clojure/tools.nrepl "0.2.4"]]))
5+
6+
(def ^:dynamic *default-middleware*
7+
(atom ['boot.from.io.aviso.nrepl/pretty-middleware]))
8+

boot/core/src/boot/repl_server.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(ns boot.repl-server
22
(:require
33
[boot.core :as core]
4+
[boot.repl :as repl]
45
[boot.from.io.aviso.nrepl :as pretty]
56
[clojure.java.io :as io]
67
[clojure.tools.nrepl.server :as server]
@@ -38,8 +39,6 @@
3839
#'pretty/pretty-middleware
3940
{:requires #{} :expects #{}})
4041

41-
(def ^:dynamic *default-middleware* (atom [#'pretty/pretty-middleware]))
42-
4342
(defn ->var
4443
[thing]
4544
(if-not (symbol? thing)
@@ -65,7 +64,8 @@
6564
init-ns (or init-ns 'boot.user)
6665
init-ns-mw [(wrap-init-ns init-ns)]
6766
user-mw (->mw-list middleware)
68-
middleware (concat init-ns-mw *default-middleware* user-mw)
67+
default-mw (->mw-list @repl/*default-middleware*)
68+
middleware (concat init-ns-mw default-mw user-mw)
6969
handler (if handler
7070
(->var handler)
7171
(apply server/default-handler middleware))

boot/core/src/boot/task/built_in.clj

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[clojure.string :as string]
66
[boot.pod :as pod]
77
[boot.file :as file]
8+
[boot.repl :as repl]
89
[boot.core :as core]
910
[boot.main :as main]
1011
[boot.util :as util]
@@ -169,9 +170,10 @@
169170
If no port is specified the server will choose a random one and the client
170171
will read the .nrepl-port file and use that.
171172
172-
The #'boot.repl-server/*default-middleware* dynamic var holds a vector of the
173-
default REPL middleware to be included. You may modify this in your build.boot
174-
file by calling set! or rebinding the var."
173+
The *default-middleware* and *default-dependencies* atoms in the boot.repl-server
174+
namespace contain vectors of default REPL middleware and REPL dependencies to
175+
be loaded when starting the server. You may modify these in your build.boot
176+
file."
175177

176178
[s server bool "Start REPL server only."
177179
c client bool "Start REPL client only."
@@ -184,7 +186,7 @@
184186
p port PORT int "The port to listen on and/or connect to."
185187
n init-ns NS sym "The initial REPL namespace."
186188
m middleware SYM [sym] "The REPL middleware vector."
187-
x handler SYM sym "The REPL handler, when used middleware option is ignored"]
189+
x handler SYM sym "The REPL handler (overrides middleware options)."]
188190

189191
(let [srv-opts (select-keys *opts* [:bind :port :init-ns :middleware :handler])
190192
cli-opts (-> *opts*
@@ -194,11 +196,10 @@
194196
:custom-eval eval
195197
:custom-init init
196198
:skip-default-init skip-init))
197-
repl-svr (delay (try (require 'clojure.tools.nrepl.server)
198-
(catch Throwable _
199-
(pod/add-dependencies
200-
(update-in (core/get-env) [:dependencies]
201-
conj '[org.clojure/tools.nrepl "0.2.4"]))))
199+
deps (remove pod/dependency-loaded? @repl/*default-dependencies*)
200+
repl-svr (delay (when (seq deps)
201+
(pod/add-dependencies
202+
(assoc (core/get-env) :dependencies deps)))
202203
(require 'boot.repl-server)
203204
((resolve 'boot.repl-server/start-server) srv-opts))
204205
repl-cli (delay (pod/call-worker `(boot.repl-client/client ~cli-opts)))]

boot/pod/src/boot/pod.clj

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,36 @@
103103
first
104104
(.getInputStream jarfile))))))
105105

106-
(defn pom-properties-map
107-
[prop-or-jarpath]
108-
(let [prop (if (instance? Properties prop-or-jarpath)
109-
prop-or-jarpath
110-
(doto (Properties.) (.load (io/input-stream prop-or-jarpath))))
111-
gid (.getProperty prop "groupId")
112-
aid (.getProperty prop "artifactId")]
106+
(defn- pom-prop-map
107+
[props]
108+
(let [gid (.getProperty props "groupId")
109+
aid (.getProperty props "artifactId")
110+
ver (.getProperty props "version")]
113111
{:group-id gid
114112
:artifact-id aid
115113
:project (symbol gid aid)
116-
:version (.getProperty prop "version")}))
114+
:version ver}))
115+
116+
(defn dependency-loaded?
117+
[[project & _]]
118+
(let [[aid gid] (util/extract-ids project)]
119+
(io/resource (format "META-INF/maven/%s/%s/pom.properties" aid gid))))
120+
121+
(defn dependency-pom-properties
122+
[coord]
123+
(doto (Properties.)
124+
(.load (io/input-stream (dependency-loaded? coord)))))
125+
126+
(defn dependency-pom-properties-map
127+
[coord]
128+
(pom-prop-map (dependency-pom-properties coord)))
129+
130+
(defn pom-properties-map
131+
[prop-or-jarpath]
132+
(pom-prop-map
133+
(if (instance? Properties prop-or-jarpath)
134+
prop-or-jarpath
135+
(doto (Properties.) (.load (io/input-stream prop-or-jarpath))))))
117136

118137
(defn pom-xml
119138
[jarpath]

0 commit comments

Comments
 (0)