From f6e6a92055d3c79306732586ec12d6c60da476b0 Mon Sep 17 00:00:00 2001 From: anatoly Date: Sun, 28 Feb 2016 18:38:56 -0500 Subject: [PATCH 01/20] onto 0.1.11-SNAPSHOT --- build.boot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.boot b/build.boot index 3411d42..8732879 100644 --- a/build.boot +++ b/build.boot @@ -1,4 +1,4 @@ -(def +version+ "0.1.10") +(def +version+ "0.1.11-SNAPSHOT") (set-env! :source-paths #{"src"} From 7becc38282392323941ddb6e8f54423d704f829e Mon Sep 17 00:00:00 2001 From: Anatoly Date: Tue, 15 Mar 2016 22:18:52 -0400 Subject: [PATCH 02/20] =?UTF-8?q?[docs]:=20(inc=20=C2=A9-year)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 534e636..636034e 100644 --- a/README.md +++ b/README.md @@ -762,7 +762,7 @@ The documentation is [here](doc/runtime-arguments.md#passing-runtime-arguments). ## License -Copyright © 2015 tolitius +Copyright © 2016 tolitius Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version. From f26da26d80531b99804e13a2c41a17c12fee7ff6 Mon Sep 17 00:00:00 2001 From: Mike Konkov Date: Wed, 9 Mar 2016 00:02:37 +0100 Subject: [PATCH 03/20] Readme fix on start-with-states --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 636034e..34d4af8 100644 --- a/README.md +++ b/README.md @@ -384,8 +384,8 @@ When running tests it would be great _not_ to send the real text messages, but r The `start-with-states` function takes other states as substitues: ```clojure -(mount/start-with {#'app.neo/db #'app.test/test-db - #'app.neo/publisher #'app.test/test-publisher}) +(mount/start-with-states {#'app.neo/db #'app.test/test-db + #'app.neo/publisher #'app.test/test-publisher}) ``` `start-with-states` takes a map of states with their substitutes. For example `#'app.nyse/db` here is the real deal (remote) DB that is being substituted with `#'app.test/test-db` state, which could be anything, a map, an in memory DB, etc. From afe96e9aaddc955877bdd553af5eda3de9e491c9 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Mon, 18 Apr 2016 14:27:37 -0400 Subject: [PATCH 04/20] docs: + multiple systems, - "no longer true" diffs --- doc/differences-from-component.md | 42 +++++-------------------------- 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/doc/differences-from-component.md b/doc/differences-from-component.md index 1053ef3..dc1bfc0 100644 --- a/doc/differences-from-component.md +++ b/doc/differences-from-component.md @@ -31,9 +31,7 @@ The not so hidden benefit is REPL time reloadability that it brings to the table - [Boilerplate code](#boilerplate-code) - [Library vs. Framework](#library-vs-framework) - [What Component does better](#what-component-does-better) - - [Swapping alternate implementations](#swapping-alternate-implementations) - - [Uberjar / Packaging](#uberjar--packaging) - - [Multiple separate systems](#multiple-separate-systems) + - [Multiple separate systems within the same JVM](#multiple-separate-systems-within-the-same-jvm) - [Visualizing dependency graph](#visualizing-dependency-graph) @@ -154,42 +152,13 @@ Mount does not need to manage namespaces and vars, since it is very well managed ## What Component does better -### Swapping alternate implementations +### Multiple separate systems within the same JVM -This is someting that is very useful for testing and is very easy to do in Component by simply assoc'ing onto a map. +With Component multiple separate systems can be started _in the same Clojure runtime_ with different settings. Which _might_ be useful for testing, i.e. if you need to have `dev db` and `test db` started in the _same_ REPL, to _run tests within the same REPL you develop in_. -Mount can do it too: https://github.com/tolitius/mount#swapping-alternate-implementations +Development workflows vary and tend to be a subjective / preference based more than a true recipe, but I believe it is much cleaner to run tests in the _separate_ REPL / process. Moreover run them continuesly: i.e. `boot watch speak test`: this way you don't event need to look at that other REPL / terminal, Boot will _tell_ you whether the tests pass or fail after any file is changed. -The reason it is in "Component does it better" section is because, while result is the same, merging maps is a bit simpler than: - -```clojure -(mount/start-with {#'app.nyse/db #'app.test/test-db - #'app.nyse/publisher #'app.test/test-publisher}) -``` - -### Uberjar / Packaging - -Since Component fully controls the `system` where the whole application lives, it is quite simple -to start an application from anywhere including a `-main` function of the uberjar. - -In order to start the whole system in development, Mount just needs `(mount/start)` or `(reset)` -it's [simple](https://github.com/tolitius/mount#the-importance-of-being-reloadable). - -However there is no "tools.namespaces"/REPL at a "stand alone jar runtime" and in order for Mount to start / stop -the app, states need to be `:require`/`:use`d, which is usually done within the same namespace as `-main`. - -Depending on app dependencies, it could only require a few states to be `:require`/`:use`d, others -will be brought transitively. Here is more about mount [packaging](https://github.com/tolitius/mount#packaging) and an [example](uberjar.md#creating-reloadable-uberjarable-app) of building a wepapp uberjar with Mount. - -On the flip side, Component _system_ usually requires all the `:require`s, since in order to be built, it needs to "see" all the top level states. - -###### _conclusion: it's simple in Mount as well, but is left upto developer to require what's needed._ - -### Multiple separate systems - -With Component multiple separate systems can be started _in the same Clojure runtime_ with different settings. Which might be useful for testing. - -Mount keeps states in namespaces, hence the app becomes "[The One](https://en.wikipedia.org/wiki/Neo_(The_Matrix))", and there can't be "multiples The Ones". +Mount keeps states in namespaces, hence the app becomes "[The One](https://en.wikipedia.org/wiki/Neo_(The_Matrix))", and there can't be "multiples The Ones". In practice, if we are talking about stateful external resources, there is trully only _one_ of them with a given configuration. Different configuration => different state. It's is that simple. Testing is not alien to Mount and it knows how to do a thing or two: @@ -197,6 +166,7 @@ Testing is not alien to Mount and it knows how to do a thing or two: * [start an application without certain states](https://github.com/tolitius/mount#start-an-application-without-certain-states) * [swapping alternate implementations](https://github.com/tolitius/mount#swapping-alternate-implementations) * [stop an application except certain states](https://github.com/tolitius/mount#stop-an-application-except-certain-states) +* [composing states](https://github.com/tolitius/mount#composing-states) After [booting mount](http://www.dotkam.com/2015/12/22/the-story-of-booting-mount/) I was secretly thinking of achieving multiple separate systems by running them in different [Boot Pods](https://github.com/boot-clj/boot/wiki/Pods). From e34a164c2ef4e7dc0cbe9d86e18ab98f0f66508f Mon Sep 17 00:00:00 2001 From: anatoly Date: Tue, 26 Apr 2016 16:07:00 -0400 Subject: [PATCH 05/20] temp trace: "mounting.. state name" --- src/mount/core.cljc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mount/core.cljc b/src/mount/core.cljc index 8d4ea82..22f1952 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -144,6 +144,7 @@ :status #{:stopped}} stop (assoc :stop `(fn [] ~stop)))] `(do + (log (str "|| mounting... " ~state-name)) (~'defonce ~state (DerefableState. ~state-name)) (mount-it (~'var ~state) ~state-name ~s-meta) (~'var ~state)))))) From 677aa0cfdcb96862b088459233599a3add3868fa Mon Sep 17 00:00:00 2001 From: anatoly Date: Tue, 31 May 2016 09:24:14 -0400 Subject: [PATCH 06/20] "boot-reload" to 0.4.8 --- build.boot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.boot b/build.boot index 8732879..24475aa 100644 --- a/build.boot +++ b/build.boot @@ -34,7 +34,7 @@ [tolitius/boot-stripper "0.1.0-SNAPSHOT" :scope "test"] [com.cemerick/piggieback "0.2.1" :scope "test" :exclusions [org.clojure/clojurescript]] [weasel "0.7.0" :scope "test" :exclusions [org.clojure/clojurescript]] - [adzerk/boot-reload "0.4.2" :scope "test"] + [adzerk/boot-reload "0.4.8" :scope "test"] [crisptrutski/boot-cljs-test "0.2.1-SNAPSHOT" :scope "test"]]) (require '[adzerk.bootlaces :refer :all] From f4683252df3bc9e5a0885379f1b9f4c48fc4040b Mon Sep 17 00:00:00 2001 From: anatoly Date: Tue, 31 May 2016 09:47:31 -0400 Subject: [PATCH 07/20] upping dev/test deps --- build.boot | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build.boot b/build.boot index 24475aa..4ba00e7 100644 --- a/build.boot +++ b/build.boot @@ -5,10 +5,10 @@ :dependencies '[;; mount brings _no dependencies_, everything here is for ;; mount dev, examples apps and tests - [org.clojure/clojure "1.7.0" :scope "provided"] - [org.clojure/clojurescript "1.7.189" :scope "provided" :classifier "aot"] - [datascript "0.13.3" :scope "provided"] - [compojure "1.4.0" :scope "provided"] + [org.clojure/clojure "1.8.0" :scope "provided"] + [org.clojure/clojurescript "1.7.228" :scope "provided" :classifier "aot"] + [datascript "0.15.0" :scope "provided"] + [compojure "1.5.0" :scope "provided"] [ring/ring-jetty-adapter "1.1.0" :scope "provided"] [cheshire "5.5.0" :scope "provided"] [hiccups "0.3.0" :scope "provided" :exclusions [org.clojure/clojurescript]] @@ -18,24 +18,24 @@ [robert/hooke "1.3.0" :scope "provided"] [org.clojure/tools.namespace "0.2.11" :scope "provided"] [org.clojure/tools.nrepl "0.2.12" :scope "provided"] - [com.datomic/datomic-free "0.9.5327" :scope "provided" :exclusions [joda-time]] + [com.datomic/datomic-free "0.9.5359" :scope "provided" :exclusions [joda-time]] ;; boot clj - [boot/core "2.5.1" :scope "provided"] + [boot/core "2.6.0" :scope "provided"] [adzerk/bootlaces "0.1.13" :scope "test"] [adzerk/boot-logservice "1.0.1" :scope "test"] - [adzerk/boot-test "1.0.6" :scope "test"] + [adzerk/boot-test "1.1.1" :scope "test"] [tolitius/boot-check "0.1.1" :scope "test"] ;; boot cljs - [adzerk/boot-cljs "1.7.170-3" :scope "test"] + [adzerk/boot-cljs "1.7.228-1" :scope "test"] [adzerk/boot-cljs-repl "0.3.0" :scope "test"] [pandeiro/boot-http "0.7.1-SNAPSHOT" :scope "test"] [tolitius/boot-stripper "0.1.0-SNAPSHOT" :scope "test"] [com.cemerick/piggieback "0.2.1" :scope "test" :exclusions [org.clojure/clojurescript]] [weasel "0.7.0" :scope "test" :exclusions [org.clojure/clojurescript]] [adzerk/boot-reload "0.4.8" :scope "test"] - [crisptrutski/boot-cljs-test "0.2.1-SNAPSHOT" :scope "test"]]) + [crisptrutski/boot-cljs-test "0.2.2-SNAPSHOT" :scope "test"]]) (require '[adzerk.bootlaces :refer :all] '[adzerk.boot-test :as bt] From 82ec3d34aafb2afa5e68367e96169a4f9ed5552d Mon Sep 17 00:00:00 2001 From: anatoly Date: Thu, 9 Jun 2016 14:23:50 -0400 Subject: [PATCH 08/20] boot check to 0.1.2 --- build.boot | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.boot b/build.boot index 4ba00e7..fa9db02 100644 --- a/build.boot +++ b/build.boot @@ -25,7 +25,7 @@ [adzerk/bootlaces "0.1.13" :scope "test"] [adzerk/boot-logservice "1.0.1" :scope "test"] [adzerk/boot-test "1.1.1" :scope "test"] - [tolitius/boot-check "0.1.1" :scope "test"] + [tolitius/boot-check "0.1.2" :scope "test"] ;; boot cljs [adzerk/boot-cljs "1.7.228-1" :scope "test"] @@ -35,7 +35,7 @@ [com.cemerick/piggieback "0.2.1" :scope "test" :exclusions [org.clojure/clojurescript]] [weasel "0.7.0" :scope "test" :exclusions [org.clojure/clojurescript]] [adzerk/boot-reload "0.4.8" :scope "test"] - [crisptrutski/boot-cljs-test "0.2.2-SNAPSHOT" :scope "test"]]) + [crisptrutski/boot-cljs-test "0.2.1-SNAPSHOT" :scope "test"]]) (require '[adzerk.bootlaces :refer :all] '[adzerk.boot-test :as bt] @@ -127,6 +127,7 @@ (cljs :optimizations :advanced :ids #{"mount"}))) (task-options! + tcs/test-cljs {:js-env :phantom} push {:ensure-branch nil} pom {:project 'mount :version +version+ From 736d93abd1659313da7822d275cefb4e49b9871b Mon Sep 17 00:00:00 2001 From: Anatoly Date: Thu, 9 Jun 2016 14:46:31 -0400 Subject: [PATCH 09/20] [circle ci]: "0.1.11-SNAPSHOT" to "0.1.11" branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 34d4af8..36944fa 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ _**Alan J. Perlis** from [Structure and Interpretation of Computer Programs](htt module | branch | status ----------|----------|---------- mount | `master` | [![Circle CI](https://circleci.com/gh/tolitius/mount/tree/master.png?style=svg)](https://circleci.com/gh/tolitius/mount/tree/master) - mount | `0.1.11-SNAPSHOT` | [![Circle CI](https://circleci.com/gh/tolitius/mount/tree/0.1.11-SNAPSHOT.png?style=svg)](https://circleci.com/gh/tolitius/mount/tree/0.1.11-SNAPSHOT) + mount | `0.1.11-SNAPSHOT` | [![Circle CI](https://circleci.com/gh/tolitius/mount/tree/0.1.11.png?style=svg)](https://circleci.com/gh/tolitius/mount/tree/0.1.11) [![Clojars Project](http://clojars.org/mount/latest-version.svg)](http://clojars.org/mount) From 19bed168c88cea963a080e2b1253302e618b6bb7 Mon Sep 17 00:00:00 2001 From: anatoly Date: Thu, 9 Jun 2016 17:22:04 -0400 Subject: [PATCH 10/20] [circle]: latest boot.sh --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index b04a609..9b72948 100644 --- a/circle.yml +++ b/circle.yml @@ -4,7 +4,7 @@ machine: dependencies: pre: - - wget https://github.com/boot-clj/boot-bin/releases/download/2.5.2/boot.sh + - wget https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh - mv boot.sh boot && chmod a+x boot && sudo mv boot /usr/local/bin test: From 6ee07a9901e90c1bdaddbd4119f4055f55185c8e Mon Sep 17 00:00:00 2001 From: anatoly Date: Sun, 10 Jul 2016 00:35:47 -0400 Subject: [PATCH 11/20] [docs]: typo in "affected states" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 36944fa..7661421 100644 --- a/README.md +++ b/README.md @@ -562,7 +562,7 @@ dev=> (mount/start) ``` ```clojure dev=> (mount/stop) -{:started [#'app/nrepl +{:stopped [#'app/nrepl #'app.nyse/conn #'app.config/config]} ``` From 76cae93f81f6deffe0782f7c5a620b41a0c3d487 Mon Sep 17 00:00:00 2001 From: Andrea Richiardi Date: Tue, 5 Jul 2016 10:53:39 -0700 Subject: [PATCH 12/20] Add note on ^{:on-reload :noop} According to the Slack conversation with @tolitius --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7661421..12bbc13 100644 --- a/README.md +++ b/README.md @@ -481,6 +481,8 @@ When a running state needs to be just "stopped" on reload, set `:on-reload` to ` Again, by default, if no `:on-reload` meta is added, internally it would be set to `:restart`, in which case a running state will be restarted on a redef / a namespace reload. +Note that `^{:on-reload :noop}` will disable stopping or starting the state on namespace recompilation but it will still obey `(mount/start)` / `(mount/stop)` calls. This means that if any of the namespaces with `(mount/start)` / `(mount/stop)` calls are reloaded or these calls are explicitely executed (i.e. somewhere in the `dev` namespace or in an `:after` clause), the state's start/stop functions will still be called. + ## Cleaning up Deleted States Mount will detect when a state was renamed/deleted from a namespace, and will do two things: From 76fb49896815aec7620aeea5ec5f3e73131af79d Mon Sep 17 00:00:00 2001 From: anatoly Date: Thu, 21 Jul 2016 14:48:30 -0400 Subject: [PATCH 13/20] adding (running-states) --- src/mount/core.cljc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mount/core.cljc b/src/mount/core.cljc index 22f1952..aeaf93f 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -181,6 +181,9 @@ (with-ns ns name)) v))) +(defn running-states [] + (keys @running)) + (defn- unvar-state [s] (->> s (drop 2) (apply str))) ;; magic 2 is removing "#'" in state name From f514782716d2dc96cf200dfa79f6aa2be0b019c6 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Mon, 18 Jul 2016 14:58:29 -0500 Subject: [PATCH 14/20] readme typo fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12bbc13..c39b98e 100644 --- a/README.md +++ b/README.md @@ -585,7 +585,7 @@ The way this is done is via an excellent [robert hooke](https://github.com/techn ## Clojure Version -Since mount [supports both](doc/clojurescript.md#managing-state-in-clojurescript) Clojure and CljoureScript, it relies on [Reader Conditionals](http://clojure.org/reader#The%20Reader--Reader%20Conditionals) that were introduced in `Clojure 1.7`. mount's code is not precompiled (i.e. AOT) and distributed in `.cljc` sources, hence it currently requires `Clojure 1.7` and above. +Since mount [supports both](doc/clojurescript.md#managing-state-in-clojurescript) Clojure and ClojureScript, it relies on [Reader Conditionals](http://clojure.org/reader#The%20Reader--Reader%20Conditionals) that were introduced in `Clojure 1.7`. mount's code is not precompiled (i.e. AOT) and distributed in `.cljc` sources, hence it currently requires `Clojure 1.7` and above. ## Mount and Develop! From ae6763da8cd022a280b44b1296f9ac1eb12f4dfc Mon Sep 17 00:00:00 2001 From: anatoly Date: Tue, 1 Nov 2016 21:23:09 -0400 Subject: [PATCH 15/20] restart listener --- src/mount/core.cljc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/mount/core.cljc b/src/mount/core.cljc index aeaf93f..cbe0afe 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -301,6 +301,25 @@ (var-to-str to) :state)) states)) +;; restart on events + +(defprotocol ChangeListener + (add-watcher [this ks watcher]) + (on-change [this k])) + +(deftype RestartListener [watchers] + ChangeListener + + (add-watcher [_ ks state] + (doseq [k ks] + (swap! watchers update k #(conj % state)))) + + (on-change [_ k] + (let [states (@watchers k)] + (apply stop states) + (apply start states)))) + + ;; explicit, not composable (subject to depreciate?) (defn stop-except [& states] From 7d323e727e7228617ae33ba574a4199c6bf9178b Mon Sep 17 00:00:00 2001 From: anatoly Date: Wed, 2 Nov 2016 11:25:44 -0400 Subject: [PATCH 16/20] new-> restart listener --- src/mount/core.cljc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mount/core.cljc b/src/mount/core.cljc index cbe0afe..1917961 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -319,6 +319,11 @@ (apply stop states) (apply start states)))) +(defn restart-listner + ([] + (restart-listner {})) + ([watchers] + (RestartListener. (atom watchers)))) ;; explicit, not composable (subject to depreciate?) From c189db9d125e89944011d43952f2972db496c751 Mon Sep 17 00:00:00 2001 From: anatoly Date: Wed, 2 Nov 2016 13:54:59 -0400 Subject: [PATCH 17/20] set of keys for restart listener "on-change" --- src/mount/core.cljc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mount/core.cljc b/src/mount/core.cljc index 1917961..314fc57 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -314,10 +314,11 @@ (doseq [k ks] (swap! watchers update k #(conj % state)))) - (on-change [_ k] - (let [states (@watchers k)] - (apply stop states) - (apply start states)))) + (on-change [_ ks] + (doseq [k ks] + (let [states (@watchers k)] + (apply stop states) + (apply start states))))) (defn restart-listner ([] From a0f10407ee34007c883e8e523bcc511502981062 Mon Sep 17 00:00:00 2001 From: anatoly Date: Wed, 2 Nov 2016 13:56:45 -0400 Subject: [PATCH 18/20] [restart]: listner => listener --- src/mount/core.cljc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mount/core.cljc b/src/mount/core.cljc index 314fc57..12a6838 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -320,9 +320,9 @@ (apply stop states) (apply start states))))) -(defn restart-listner +(defn restart-listener ([] - (restart-listner {})) + (restart-listener {})) ([watchers] (RestartListener. (atom watchers)))) From 3218f8afaf84d2f58888eb17537b301273abd12f Mon Sep 17 00:00:00 2001 From: anatoly Date: Wed, 2 Nov 2016 17:43:31 -0400 Subject: [PATCH 19/20] vec states for watchers --- src/mount/core.cljc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mount/core.cljc b/src/mount/core.cljc index 12a6838..7ee4df0 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -312,7 +312,8 @@ (add-watcher [_ ks state] (doseq [k ks] - (swap! watchers update k #(conj % state)))) + (swap! watchers update k (fn [v] + (-> (conj v state) vec))))) (on-change [_ ks] (doseq [k ks] From 1c7f2ccc342f10972b811ce91daf504f92377b02 Mon Sep 17 00:00:00 2001 From: anatoly Date: Wed, 2 Nov 2016 18:20:08 -0400 Subject: [PATCH 20/20] [docs]: link to the latest logging --- README.md | 2 +- src/mount/core.cljc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5baad11..26a5920 100644 --- a/README.md +++ b/README.md @@ -581,7 +581,7 @@ Since mount is a _library_ it should _not_ bring any dependencies unless its fun > But I still these logging statements in the examples. -The way this is done is via an excellent [robert hooke](https://github.com/technomancy/robert-hooke/). Example applications live in `test`, so does the [utility](https://github.com/tolitius/mount/blob/75d7cdc610ce38623d4d3aea1da3170d1c9a3b4b/test/app/utils/logging.clj#L44) that adds logging to all the mount's lifecycle functions on start in [dev.clj](https://github.com/tolitius/mount/blob/75d7cdc610ce38623d4d3aea1da3170d1c9a3b4b/dev/dev.clj#L21). +The way this is done is via an excellent [robert hooke](https://github.com/technomancy/robert-hooke/). Example applications live in `test`, so does the [utility](test/clj/tapp/utils/logging.clj#L42) that adds logging to all the mount's lifecycle functions on start in [dev.clj](https://github.com/tolitius/mount/blob/75d7cdc610ce38623d4d3aea1da3170d1c9a3b4b/dev/dev.clj#L21). ## Clojure Version diff --git a/src/mount/core.cljc b/src/mount/core.cljc index 7ee4df0..4973067 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -317,7 +317,7 @@ (on-change [_ ks] (doseq [k ks] - (let [states (@watchers k)] + (when-let [states (seq (@watchers k))] (apply stop states) (apply start states)))))