From 1bb9fa31f72214e19c76a93a70151ade6581fb35 Mon Sep 17 00:00:00 2001 From: Hagmonk Date: Tue, 10 Jul 2018 14:03:25 -0700 Subject: [PATCH 1/5] Proposed fix for #537 - revert `cider.nrepl/init` such that it takes a vector of middlewares - have `cider.nrepl/init` pass a map of arguments to `start-nrepl` - tweak cider nrepl boot task to pass a map to `start-nrepl` directly - set defaults for `port` and `bind` to keep `nrepl-server` happy --- src/cider/tasks.clj | 6 +++--- src/cider_nrepl/main.clj | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cider/tasks.clj b/src/cider/tasks.clj index cb1d2d36d..3c4f54ef9 100644 --- a/src/cider/tasks.clj +++ b/src/cider/tasks.clj @@ -30,6 +30,6 @@ (util/dbug* "nREPL middleware: %s\n" (vec default-mws)) (boot.core/with-pass-thru [_] (require 'cider-nrepl.main) - ((resolve 'cider-nrepl.main/init) {:middleware default-mws - :port port - :bind bind})))) + ((resolve 'cider-nrepl.main/start-nrepl) {:middleware default-mws + :port port + :bind bind})))) diff --git a/src/cider_nrepl/main.clj b/src/cider_nrepl/main.clj index f2452edad..d97cf9854 100644 --- a/src/cider_nrepl/main.clj +++ b/src/cider_nrepl/main.clj @@ -30,7 +30,7 @@ (defn start-nrepl [opts] - (let [{:keys [handler middleware bind port]} opts + (let [{:keys [handler middleware bind port] :or {port 0 bind "::"}} opts handler (cond-> (or handler nrepl.server/default-handler) middleware (apply (->mw-list middleware))) @@ -51,7 +51,7 @@ (defn init ([] (init nil)) - ([opts] - (start-nrepl opts) + ([handlers] + (start-nrepl {:handler handlers}) ;; Return nil so the value doesn't print nil)) From e6c9a6c2f0007f08a24d521eb6cfcf990954eae2 Mon Sep 17 00:00:00 2001 From: Hagmonk Date: Wed, 11 Jul 2018 12:27:38 -0700 Subject: [PATCH 2/5] Actually fix #537, and rub it all over with tests --- src/cider_nrepl/main.clj | 37 ++++++++++++++++++------ test/clj/cider/nrepl/main_test.clj | 45 ++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 test/clj/cider/nrepl/main_test.clj diff --git a/src/cider_nrepl/main.clj b/src/cider_nrepl/main.clj index d97cf9854..9b0067191 100644 --- a/src/cider_nrepl/main.clj +++ b/src/cider_nrepl/main.clj @@ -28,17 +28,36 @@ [middleware-var-strs] (into [] mw-xf middleware-var-strs)) +(defn- build-handler + [{:keys [handler middleware]}] + (let [handler (or handler nrepl.server/default-handler)] + (if middleware + (apply handler (->mw-list middleware)) + (handler)))) + (defn start-nrepl - [opts] - (let [{:keys [handler middleware bind port] :or {port 0 bind "::"}} opts + "Starts a socket-based nREPL server. Accepts a map with the following keys: + + * :port — defaults to 0, which autoselects an open port + + * :bind — bind address, by default \"::\" (falling back to \"localhost\" if + \"::\" isn't resolved by the underlying network stack) - handler (cond-> (or handler nrepl.server/default-handler) - middleware (apply (->mw-list middleware))) + * :handler — the nREPL message handler to use for each incoming connection; + defaults to the result of `(nrepl.server/default-handler)` + * :middleware - a sequence of vars or string which can be resolved to vars, + representing middleware you wish to mix in to the nREPL handler. Vars can + resolve to a sequence of vars, in which case they'll be flattened into the + list of middleware." + [{:keys [bind port] :as opts}] + (let [handler + (build-handler opts) + {:keys [server-socket port] :as server} (nrepl.server/start-server :handler handler - :bind bind - :port port) + :bind (or bind "::") + :port (or port 0)) bind (-> server-socket (.getInetAddress) (.getHostName))] @@ -50,8 +69,8 @@ (defn init ([] - (init nil)) - ([handlers] - (start-nrepl {:handler handlers}) + (start-nrepl {})) + ([middleware] + (start-nrepl {:middleware middleware}) ;; Return nil so the value doesn't print nil)) diff --git a/test/clj/cider/nrepl/main_test.clj b/test/clj/cider/nrepl/main_test.clj new file mode 100644 index 000000000..c673d2adc --- /dev/null +++ b/test/clj/cider/nrepl/main_test.clj @@ -0,0 +1,45 @@ +(ns cider.nrepl.main-test + (:require [cider.nrepl :refer [wrap-debug cider-middleware]] + [cider-nrepl.main :as m] + [clojure.test :refer :all] + [clojure.tools.nrepl :as nrepl] + [clojure.tools.nrepl.server :as nrepl.server] + [clojure.tools.nrepl.transport :as transport])) + +(defn start-stop-nrepl-session + [opts] + (with-open [server (#'m/start-nrepl opts) + transport (nrepl/connect :port (:port server))] + (transport/send transport {:op "clone" :id 1}) + (let [session-id (:new-session (transport/recv transport 1000))] + (assert session-id) + (transport/send transport {:session session-id + :id 2 + :op "clone"}) + (is (= (:status (transport/recv transport 1000)) ["done"]))))) + +(deftest start-nrepl-test + (testing "passing a specific handler should work" + (let [opts {:handler nrepl.server/default-handler}] + (start-stop-nrepl-session opts))) + + (testing "passing a sequence instead of a map shouldn't crash" + (let [opts ["cider.nrepl/cider-middleware"]] + (start-stop-nrepl-session opts))) + + (testing "passing nil shouldn't crash" + (let [opts nil] + (start-stop-nrepl-session opts))) + + (testing "passing valid middleware should work" + (let [opts {:middleware ["cider.nrepl/cider-middleware"]}] + (start-stop-nrepl-session opts))) + + (testing "passing options as given by boot task middleware should work" + (let [opts {:middleware '(cider.nrepl.middleware.version/wrap-version + cider.nrepl.middleware.apropos/wrap-apropos) + :port nil + :bind nil}] + (start-stop-nrepl-session opts)))) + + From 8edfbdfbc6049463ceb59fdfca5c4008ff129614 Mon Sep 17 00:00:00 2001 From: Hagmonk Date: Wed, 11 Jul 2018 12:56:38 -0700 Subject: [PATCH 3/5] Appease the cljfmt checks --- src/cider_nrepl/main.clj | 2 +- test/clj/cider/nrepl/main_test.clj | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cider_nrepl/main.clj b/src/cider_nrepl/main.clj index 9b0067191..39e1d97cd 100644 --- a/src/cider_nrepl/main.clj +++ b/src/cider_nrepl/main.clj @@ -53,7 +53,7 @@ [{:keys [bind port] :as opts}] (let [handler (build-handler opts) - + {:keys [server-socket port] :as server} (nrepl.server/start-server :handler handler :bind (or bind "::") diff --git a/test/clj/cider/nrepl/main_test.clj b/test/clj/cider/nrepl/main_test.clj index c673d2adc..42fb4ebda 100644 --- a/test/clj/cider/nrepl/main_test.clj +++ b/test/clj/cider/nrepl/main_test.clj @@ -1,4 +1,4 @@ -(ns cider.nrepl.main-test +(ns cider.nrepl.main-test (:require [cider.nrepl :refer [wrap-debug cider-middleware]] [cider-nrepl.main :as m] [clojure.test :refer :all] @@ -6,8 +6,7 @@ [clojure.tools.nrepl.server :as nrepl.server] [clojure.tools.nrepl.transport :as transport])) -(defn start-stop-nrepl-session - [opts] +(defn start-stop-nrepl-session [opts] (with-open [server (#'m/start-nrepl opts) transport (nrepl/connect :port (:port server))] (transport/send transport {:op "clone" :id 1}) @@ -22,7 +21,7 @@ (testing "passing a specific handler should work" (let [opts {:handler nrepl.server/default-handler}] (start-stop-nrepl-session opts))) - + (testing "passing a sequence instead of a map shouldn't crash" (let [opts ["cider.nrepl/cider-middleware"]] (start-stop-nrepl-session opts))) @@ -42,4 +41,3 @@ :bind nil}] (start-stop-nrepl-session opts)))) - From f169b4fe635f976ceea28f1ae991c5eb9198afa7 Mon Sep 17 00:00:00 2001 From: Hagmonk Date: Wed, 11 Jul 2018 13:05:16 -0700 Subject: [PATCH 4/5] Fix 'Protocol family unavailable' in test It appears travis hosts don't have IPv6 enabled, and `nrepl.server/start-server`s claim to fall back to localhost if `::` can't be resolved is not entirely true ... --- src/cider_nrepl/main.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cider_nrepl/main.clj b/src/cider_nrepl/main.clj index 39e1d97cd..ba1024a45 100644 --- a/src/cider_nrepl/main.clj +++ b/src/cider_nrepl/main.clj @@ -56,7 +56,7 @@ {:keys [server-socket port] :as server} (nrepl.server/start-server :handler handler - :bind (or bind "::") + :bind (or bind "localhost") :port (or port 0)) bind From 14eec03739df1f660ba8c25dc49d283ee9ea6a56 Mon Sep 17 00:00:00 2001 From: Hagmonk Date: Wed, 11 Jul 2018 23:06:52 -0700 Subject: [PATCH 5/5] Incorporate PR feedback! --- src/cider_nrepl/main.clj | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cider_nrepl/main.clj b/src/cider_nrepl/main.clj index ba1024a45..7155e1066 100644 --- a/src/cider_nrepl/main.clj +++ b/src/cider_nrepl/main.clj @@ -29,11 +29,8 @@ (into [] mw-xf middleware-var-strs)) (defn- build-handler - [{:keys [handler middleware]}] - (let [handler (or handler nrepl.server/default-handler)] - (if middleware - (apply handler (->mw-list middleware)) - (handler)))) + [middleware] + (apply nrepl.server/default-handler (->mw-list middleware))) (defn start-nrepl "Starts a socket-based nREPL server. Accepts a map with the following keys: @@ -50,9 +47,11 @@ representing middleware you wish to mix in to the nREPL handler. Vars can resolve to a sequence of vars, in which case they'll be flattened into the list of middleware." - [{:keys [bind port] :as opts}] + [{:keys [handler middleware bind port] :as opts}] (let [handler - (build-handler opts) + (if handler + (handler) + (build-handler middleware)) {:keys [server-socket port] :as server} (nrepl.server/start-server :handler handler