Maven or gradle? Grunt or gulp? Leiningen or boot…?

It doesn’t matter whether you’re a front- or back-end dev, sooner or later you have to complete your toolbox and choose a right hammer for the right nail. The problem is, all these tools in our ever changing programming world rotate so fast and details between them become so subtle that you’re barely able to check all of them out, understand the philosophy behind and take a reasonable decision. In particular it’s noticeable in javascript world where new ideas emerge with the speed of light. Do you know what’s the usual lifetime of shiny new javascript library, one of 4 hundreds coming out daily? Well, I don’t know too but I guess you wouldn’t be able to complete a todo app before the library of your choice became deprecated :)

Speaking of project building tools, as a Clojurists we happily sit in a comfort zone. Up until recently, there was only one way to keep your clojure project organized - Leiningen. Elegant declarative way which leiningen used to describe entire project with all its dependencies and profiles immediately reminded me of maven tons of hand-crafted pom.xmls. Easy when you finally get it, extremally hard when you try to customize.

Right on the other corner stands Boot. Instead of declarative DSL it gives a full power of Clojure - each task is just a Clojure function. It’s even more fun when you realize that boot tasks can be called (just as regular functions) straight from REPL. Having seen that first time crazy idea sparkled in my mind…

I guess every Clojurist already read Clojure Workflow Reloaded. General idea behind is dead simple. To have a reloadable “system” one needs to implement start/stop/reset functions and call them to start the system, to stop it and reload when needed. Now, let’s assume we have it already written, it works as expected and the only pain is to switch to repl and call our reset function each time something substantial has changed in our app.

Wouldn’t it be nicer to have resetting under the Emacs shortcut so every Clojure project following Stuart’s reloadable flow (ie. having system start/stop/reset implemented) could be restarted just by a simple key stroke?

This is where Boot really shines. To have system reloadable by Boot we need to implement reset task:

(require '[foo.system])

(deftask reset
  "Restarts system"
  []
  (foo.system/reset))

Each boot-ized project following this simple rule immediately becomes reset-able just by calling boot.user/reset. That simply means, we could evaluate it directly from Emacs connected to REPL via glorious Cider:

(defun repl-reset ()
  "Sends (reset) to currently running repl"
  (interactive)
  (save-buffer)
  (cider-interactive-eval "(boot.user/reset)"))

(global-set-key (kbd "C-x x") 'repl-reset)

Have a nice system resets ;)