Skip to content

Commit

Permalink
nrepl: implement Figwheel REPL API bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
darwin committed Oct 7, 2016
1 parent 0047fea commit e954583
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 12 deletions.
17 changes: 15 additions & 2 deletions src/nrepl/dirac/nrepl/controls.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
[dirac.nrepl.compilers :as compilers]
[dirac.nrepl.state :as state]
[dirac.nrepl.utils :as utils]
[dirac.nrepl.messages :as messages])
[dirac.nrepl.messages :as messages]
[dirac.nrepl.figwheel :as figwheel])
(:import (java.util.regex Pattern)))

; note: this namespace defines the context where special dirac commands are eval'd

(defn error-println [& args]
(apply helpers/error-println args))
(apply helpers/error-println args)
::no-result)

(defn ^:dynamic warn-about-retargeting-if-needed [session]
(if (not= session (state/get-current-session))
Expand Down Expand Up @@ -192,6 +194,17 @@
(error-println (messages/make-report-invalid-compilers-not-killed-msg user-input invalid-compiler-ids)))))))
::no-result)

; -- (dirac! :fig) ----------------------------------------------------------------------------------------------------------

(defmethod dirac! :fig [_ & [fn-name & args]]
(let [result (apply figwheel/call-repl-api! (or fn-name :fig-status) args)]
(let [response (case result
::figwheel/not-found (error-println (messages/make-figwheel-api-not-found-msg))
::figwheel/not-fn (error-println (messages/make-figwheel-bad-api-msg))
result)]
(state/send-response! (utils/prepare-current-env-info-response))
response)))

; -- default handler --------------------------------------------------------------------------------------------------------

(defmethod dirac! :default [command & _]
Expand Down
29 changes: 20 additions & 9 deletions src/nrepl/dirac/nrepl/figwheel.clj
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
(ns dirac.nrepl.figwheel
"We are friends with Figwheel")
"We are friends with Figwheel"
(:require [clojure.tools.logging :as log]))

(defn try-get-figwheel-api-var []
; TODO: would be nice to have some version checking (for sanity)

(defn try-resolve-figwheel-repl-api-symbol [sym]
(try
(ns-resolve 'figwheel-sidecar.repl-api '*repl-api-system*)
(catch Throwable _e
(ns-resolve 'figwheel-sidecar.repl-api sym)
(catch Throwable e
(log/trace e)
nil)))

(defn get-figwheel-repl-api []
(when-let [fig-api-var (try-get-figwheel-api-var)]
(assert (var? fig-api-var))
(var-get fig-api-var)))
(defn try-resolve-figwheel-repl-api [sym]
(let [v (try-resolve-figwheel-repl-api-symbol sym)]
(if (var? v)
(var-get v))))

(defn get-figwheel-system []
(if-let [api (get-figwheel-repl-api)]
(if-let [api (try-resolve-figwheel-repl-api '*repl-api-system*)]
(:figwheel-system api)))

(defn get-figwheel-data []
Expand All @@ -38,3 +42,10 @@
(defn collect-available-compiler-descriptors []
(let [builds (get-figwheel-builds)]
(keep (fn [[_id build]] (make-compiler-descriptor build)) builds)))

(defn call-repl-api! [fn-name & args]
(if-let [f (try-resolve-figwheel-repl-api (symbol (name fn-name)))]
(if (fn? f)
(apply f args)
::not-fn)
::not-found))
9 changes: 9 additions & 0 deletions src/nrepl/dirac/nrepl/messages.clj
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@
(defn ^:dynamic make-retargeting-warning-msg []
(str "You are in a joined Dirac session. This command is being executed as if it was entered in the target session."))

(defn ^:dynamic make-figwheel-api-not-found-msg []
(str "Figwheel API not found. Please make sure you have figwheel-sidecar properly installed in your nREPL server:\n"
"=> https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl"))

(defn ^:dynamic make-figwheel-bad-api-msg []
(str "Figwheel API found but resolved symbol is not a function.\n"
"Please make sure you are loading the latest Figwheel in your nREPL server.\n"
"=> https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl"))

; -- joined session ---------------------------------------------------------------------------------------------------------

(defn ^:dynamic make-missing-nrepl-message-msg []
Expand Down
26 changes: 25 additions & 1 deletion src/nrepl/dirac/nrepl/usage.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
" :disjoin -> disjoin Dirac session"
" :match -> list matching Dirac sessions"
""
" :fig -> Figwheel REPL API bridge"
""
" :version -> print version info"
" :help -> print usage help"
""
Expand Down Expand Up @@ -154,6 +156,27 @@
don't allow killing them via `(dirac! :kill ...)`. You have to use Figwheel's own interface to manipulate its"
" compilers."])

(def ^:dynamic fig-usage
["Usage forms:"
""
" 1. `(dirac! :fig)`"
" 2. `(dirac! :fig api-fn & args)`"
""
"Call Figwheel REPL API (if present)."
""
"This is a bridge provided for convenince to allow controlling Figwheel directly from Dirac REPL."
""
"You may provide api-fn as a string, keyword or symbol. Figwheel API function is resolved dynamically."
"Function arguments must be specified precisely as expected by Figwheel API."
""
" Examples:"
" `(dirac! :fig :fig-status)` ; <= this is equivalent to `(dirac! :fig)`"
" `(dirac! :fig :print-config)`"
" `(dirac! :fig :build-once \"my-build-id\")`"
""
"Please refer to Figwheel docs for full list of control functions:"
" => https://github.com/bhauman/lein-figwheel#repl-figwheel-control-functions"])

; -- public docs map --------------------------------------------------------------------------------------------------------

(defn render-usage [lines]
Expand All @@ -170,4 +193,5 @@
:match (render-usage match-usage)
:switch (render-usage switch-usage)
:spawn (render-usage spawn-usage)
:kill (render-usage kill-usage)})
:kill (render-usage kill-usage)
:fig (render-usage fig-usage)})

0 comments on commit e954583

Please sign in to comment.