So, the last point that hasn’t really been addressed here at all is how to easily and automatically reset routes/the system, for those without a quick command such as
C-c C-x in emacs.
I’ve been playing around over the past week or so with the concept of yet another file watcher component that issues a
(reloaded.repl/reset) command when files are changed. After a few attempts, I’ve got a working implementation that actually seems to work pretty OK, all things considered.
Feel free to try it out here: https://github.com/featheredtoast/repl-watcher
Include for the project (dev) dependencies:
(:require [repl-watcher.core :refer [repl-watcher])
and include it in the system map:
(defn dev-system 
(let [config (config)]
(assoc (testnut.application/app-system config)
:auto-resetter (repl-watcher ["src/clj"] "(reloaded.repl/reset)"))))
(Why yes, I name all my chestnut testing projects “testnut” why do you ask?)
The component will open a repl connection at the beginning, and sends the reset command to the open repl on file changes.
On first attempt at writing this, I noticed that I was getting a very strange
IllegalStateException("Can't change/establish root binding of: *ns* with set") error when running
(reloaded.repl/reset) directly from a file watcher. The root of this is due to the way that tools.namespace.repl is implemented - it turns out that
*ns* cannot be altered outside of a REPL environment. The workaround was to connect to the nrepl environment and issue commands there.
I’ve abstracted the way that this works, so that any command can be run in the repl, but I’m demonstrating with
reloaded.repl because that’s what I had in mind when writing this.
Let me know what you think!