diff --git a/.gitignore b/.gitignore index abb0409..616fffb 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ /faddle.clj /fiddle/ /.cljdoc-preview +/.cljs_node_repl diff --git a/bb.edn b/bb.edn index 076748e..ca35679 100644 --- a/bb.edn +++ b/bb.edn @@ -17,6 +17,8 @@ ;; commands download-deps {:task download-deps/-main :doc "bring down Clojure deps"} apply-import-vars {:task apply-import-vars/-main :doc "(check|gen-code) - export APIs statically from templates"} + dev-jvm {:task dev-repl/dev-jvm :doc "launch jvm nREPL for development, --help for usage"} + dev-cljs {:task dev-repl/dev-cljs :doc "launch cljs nREPL for development, --help for usage"} lint {:task lint/-main :doc "[--rebuild] lint source code using clj-kondo, eastwood"} -lint-kondo {:task lint-kondo/-main :doc "[--rebuild]"} -lint-eastwood {:task lint-eastwood/-main} diff --git a/deps.edn b/deps.edn index 033dd7e..9ad4607 100644 --- a/deps.edn +++ b/deps.edn @@ -26,6 +26,27 @@ ;; :cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.132"}}} + ;; + ;; REPL to support bb dev-jvm & dev-cljs tasks, see script/dev_repl.clj + ;; + :nrepl + {:extra-deps {nrepl/nrepl {:mvn/version "1.2.0"} + cider/cider-nrepl {:mvn/version "0.49.1"}} + :jvm-opts ["-XX:-OmitStackTraceInFastThrow"]} + + :nrepl/jvm + {:extra-deps {refactor-nrepl/refactor-nrepl {:mvn/version "3.10.0"}} + :main-opts ["-m" "nrepl.cmdline" + "--middleware" "[refactor-nrepl.middleware/wrap-refactor cider.nrepl/cider-middleware]" + "-i"]} + + :nrepl/cljs ;; note shadow-cljs does its own thing, this is for a REPL with + ;; support for plain old ClojureScript + {:extra-deps {cider/piggieback {:mvn/version "0.5.3"}} + :main-opts ["-m" "nrepl.cmdline" + "--middleware" "[cider.nrepl/cider-middleware cider.piggieback/wrap-cljs-repl]" + "-i"]} + ;; ;; Linting ;; diff --git a/doc/02-developer-guide.adoc b/doc/02-developer-guide.adoc index 676d3a7..1b9bf21 100644 --- a/doc/02-developer-guide.adoc +++ b/doc/02-developer-guide.adoc @@ -166,6 +166,26 @@ bb apply-import-vars check The check command will exit with 0 if no changes are required, otherwise it will exit with 1. Our build script will run the check command and fail the build if there are any pending changes that have not been applied. +== REPLs + +To launch a nREPL server: + +---- +bb dev-jvm +---- + +From your IDE, cider connect clj to this REPL server. + + +For a nREPL server that also includes ClojureScript support: + +---- +bb dev-cljs +---- + +From your IDE, cider connect cljs to this REPL server. + + == Testing During Development Your personal preference will likely be different, but during maintenance and refactoring, I found running tests continuously for Clojure and ClojureScript helpful. diff --git a/script/dev_repl.clj b/script/dev_repl.clj new file mode 100644 index 0000000..ef499f6 --- /dev/null +++ b/script/dev_repl.clj @@ -0,0 +1,60 @@ +(ns dev-repl + (:require [babashka.cli :as cli] + [babashka.process :as process] + [lread.status-line :as status])) + +(def cli-spec {:help {:desc "This usage help"} + + ;; cider nrepl pass through opts + :host {:ref "" + :alias :h + :default "127.0.0.1" + :desc "Host address"} + :bind {:ref "" + :alias :b + :default "127.0.0.1" + :desc "Bind address"} + :port {:ref "" + :coerce :int + :default 0 + :alias :p + :desc "Port, 0 for auto-select"}}) + +(defn- usage-help[] + (status/line :head "Usage help") + (status/line :detail (cli/format-opts {:spec cli-spec :order [:host :bind :port :help]}))) + +(defn- usage-fail [msg] + (status/line :error msg) + (usage-help) + (System/exit 1)) + +(defn- parse-opts [args] + (let [opts (cli/parse-opts args {:spec cli-spec + :restrict true + :error-fn (fn [{:keys [msg]}] + (usage-fail msg))})] + (when-let [extra-gunk (-> (meta opts) :org.babashka/cli)] + (usage-fail (str "unrecognized on the command line: " (pr-str extra-gunk)))) + opts)) + + +(defn launch-repl [flavor args] + (let [opts (parse-opts args)] + (if (:help opts) + (usage-help) + (do (status/line :head "Launching Clojure %s nREPL" (name flavor)) + (process/exec "clj" (str "-M:1.11:test-common:nrepl:nrepl/" (case flavor + :cljs "cljs:cljs" + :jvm "jvm")) + "-h" (:host opts) + "-b" (:bind opts) + "-p" (:port opts)))))) + +;; Entry points +(defn dev-jvm [& args] + (launch-repl :jvm args)) + + +(defn dev-cljs [& args] + (launch-repl :cljs args))