Skip to content

Commit

Permalink
Expose repl task dependencies
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
micha committed Nov 17, 2014
1 parent d2430b3 commit 1a76579
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 20 deletions.
8 changes: 8 additions & 0 deletions boot/core/src/boot/repl.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(ns boot.repl)

(def ^:dynamic *default-dependencies*
(atom '[[org.clojure/tools.nrepl "0.2.4"]]))

(def ^:dynamic *default-middleware*
(atom ['boot.from.io.aviso.nrepl/pretty-middleware]))

6 changes: 3 additions & 3 deletions boot/core/src/boot/repl_server.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns boot.repl-server
(:require
[boot.core :as core]
[boot.repl :as repl]
[boot.from.io.aviso.nrepl :as pretty]
[clojure.java.io :as io]
[clojure.tools.nrepl.server :as server]
Expand Down Expand Up @@ -38,8 +39,6 @@
#'pretty/pretty-middleware
{:requires #{} :expects #{}})

(def ^:dynamic *default-middleware* (atom [#'pretty/pretty-middleware]))

(defn ->var
[thing]
(if-not (symbol? thing)
Expand All @@ -65,7 +64,8 @@
init-ns (or init-ns 'boot.user)
init-ns-mw [(wrap-init-ns init-ns)]
user-mw (->mw-list middleware)
middleware (concat init-ns-mw *default-middleware* user-mw)
default-mw (->mw-list @repl/*default-middleware*)
middleware (concat init-ns-mw default-mw user-mw)
handler (if handler
(->var handler)
(apply server/default-handler middleware))
Expand Down
19 changes: 10 additions & 9 deletions boot/core/src/boot/task/built_in.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[clojure.string :as string]
[boot.pod :as pod]
[boot.file :as file]
[boot.repl :as repl]
[boot.core :as core]
[boot.main :as main]
[boot.util :as util]
Expand Down Expand Up @@ -169,9 +170,10 @@
If no port is specified the server will choose a random one and the client
will read the .nrepl-port file and use that.
The #'boot.repl-server/*default-middleware* dynamic var holds a vector of the
default REPL middleware to be included. You may modify this in your build.boot
file by calling set! or rebinding the var."
The *default-middleware* and *default-dependencies* atoms in the boot.repl-server
namespace contain vectors of default REPL middleware and REPL dependencies to
be loaded when starting the server. You may modify these in your build.boot
file."

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

(let [srv-opts (select-keys *opts* [:bind :port :init-ns :middleware :handler])
cli-opts (-> *opts*
Expand All @@ -194,11 +196,10 @@
:custom-eval eval
:custom-init init
:skip-default-init skip-init))
repl-svr (delay (try (require 'clojure.tools.nrepl.server)
(catch Throwable _
(pod/add-dependencies
(update-in (core/get-env) [:dependencies]
conj '[org.clojure/tools.nrepl "0.2.4"]))))
deps (remove pod/dependency-loaded? @repl/*default-dependencies*)
repl-svr (delay (when (seq deps)
(pod/add-dependencies
(assoc (core/get-env) :dependencies deps)))
(require 'boot.repl-server)
((resolve 'boot.repl-server/start-server) srv-opts))
repl-cli (delay (pod/call-worker `(boot.repl-client/client ~cli-opts)))]
Expand Down
35 changes: 27 additions & 8 deletions boot/pod/src/boot/pod.clj
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,36 @@
first
(.getInputStream jarfile))))))

(defn pom-properties-map
[prop-or-jarpath]
(let [prop (if (instance? Properties prop-or-jarpath)
prop-or-jarpath
(doto (Properties.) (.load (io/input-stream prop-or-jarpath))))
gid (.getProperty prop "groupId")
aid (.getProperty prop "artifactId")]
(defn- pom-prop-map
[props]
(let [gid (.getProperty props "groupId")
aid (.getProperty props "artifactId")
ver (.getProperty props "version")]
{:group-id gid
:artifact-id aid
:project (symbol gid aid)
:version (.getProperty prop "version")}))
:version ver}))

(defn dependency-loaded?
[[project & _]]
(let [[aid gid] (util/extract-ids project)]
(io/resource (format "META-INF/maven/%s/%s/pom.properties" aid gid))))

(defn dependency-pom-properties
[coord]
(doto (Properties.)
(.load (io/input-stream (dependency-loaded? coord)))))

(defn dependency-pom-properties-map
[coord]
(pom-prop-map (dependency-pom-properties coord)))

(defn pom-properties-map
[prop-or-jarpath]
(pom-prop-map
(if (instance? Properties prop-or-jarpath)
prop-or-jarpath
(doto (Properties.) (.load (io/input-stream prop-or-jarpath))))))

(defn pom-xml
[jarpath]
Expand Down

0 comments on commit 1a76579

Please sign in to comment.