Move macrovich macro in separate namespace and tweak

This patch makes sure we use a separate namespace for macrovich and that macros
are correctly loaded. It avoids having warnings under :advanced.  It also puts
vars back where they were before as they look in the right order.
This commit is contained in:
Andrea Richiardi 2018-04-06 21:23:40 -07:00
parent be6e9be246
commit 1ccff026de
3 changed files with 64 additions and 69 deletions

View file

@ -1,16 +1,34 @@
(ns mount.core
#?(:clj (:require [mount.tools.macro :refer [deftime on-error throw-runtime] :as macro]
#?(:clj (:require [mount.tools.macro :refer [on-error throw-runtime] :as macro]
[mount.tools.macrovich :refer [deftime]]
[mount.tools.logger :refer [log]]
[clojure.set :refer [intersection]]
[clojure.string :as s])
:cljs (:require [mount.tools.macro :as macro]
:cljs (:require [mount.tools.macro]
[clojure.set :refer [intersection]]
[mount.tools.logger :refer [log]]))
#?(:cljs (:require-macros [mount.core]
[mount.tools.macro :refer [deftime on-error throw-runtime]])))
[mount.tools.macro :refer [on-error throw-runtime]]
[mount.tools.macrovich :refer [deftime]])))
(defn- with-ns [ns name]
(str "#'" ns "/" name))
(defonce ^:private -args (atom {})) ;; mostly for command line args and external files
(defonce ^:private state-seq (atom 0))
(defonce ^:private mode (atom :clj))
(defonce ^:private meta-state (atom {}))
(defonce ^:private running (atom {})) ;; to clean dirty states on redefs
;; supporting tools.namespace: (disable-reload!)
#?(:clj
(alter-meta! *ns* assoc ::load false)) ;; to exclude the dependency
(defn- make-state-seq [state]
(or (:order (@meta-state state))
(swap! state-seq inc)))
(deftype NotStartedState [state]
Object
(toString [this]
(str "'" state "' is not started (to start all the states call mount/start)")))
;;TODO validate the whole lifecycle
(defn- validate [{:keys [start stop suspend resume] :as lifecycle}]
@ -18,24 +36,8 @@
(not start) (throw-runtime "can't start a stateful thing without a start function. (i.e. missing :start fn)")
(or suspend resume) (throw-runtime "suspend / resume lifecycle support was removed in \"0.1.10\" in favor of (mount/stop-except)")))
(defonce ^:private -args (atom {})) ;; mostly for command line args and external files
(defonce ^:private mode (atom :clj))
(defonce ^:private running (atom {})) ;; to clean dirty states on redefs
(defonce ^:private state-seq (atom 0))
(defonce ^:private meta-state (atom {}))
(defn- make-state-seq [state]
(or (:order (@meta-state state))
(swap! state-seq inc)))
;; supporting tools.namespace: (disable-reload!)
#?(:clj
(alter-meta! *ns* assoc ::load false)) ;; to exclude the dependency
(deftype NotStartedState [state]
Object
(toString [this]
(str "'" state "' is not started (to start all the states call mount/start)")))
(defn- with-ns [ns name]
(str "#'" ns "/" name))
(defn- pounded? [f]
(let [pound "(fn* [] "] ;;TODO: think of a better (i.e. typed) way to distinguish #(f params) from (fn [params] (...)))
@ -166,7 +168,7 @@
Pass ^{:on-reload :noop} to prevent auto-restart
on ns recompilation, or :stop to stop on recompilation."
[state & body]
(let [[state params] (macro/name-with-attributes state body)
(let [[state params] (mount.tools.macro/name-with-attributes state body)
{:keys [start stop] :as lifecycle} (apply hash-map params)
state-name (with-ns *ns* state)
order (make-state-seq state-name)]

View file

@ -1,54 +1,26 @@
(ns mount.tools.macro
(:refer-clojure :exclude [case])
#?(:cljs (:require-macros [mount.tools.macro :refer [deftime case]])))
;; From https://github.com/cgrand/macrovich 0.2.0
;; Licensed under EPL v1. Copyright Cristophe Grand.
(defmacro deftime
"This block will only be evaluated at the correct time for macro definition, at other times its content
are removed.
For Clojure it always behaves like a `do` block.
For Clojurescript/JVM the block is only visible to Clojure.
For self-hosted Clojurescript the block is only visible when defining macros in the pseudo-namespace."
[& body]
(when #?(:clj (not (:ns &env)) :cljs (re-matches #".*\$macros" (name (ns-name *ns*))))
`(do ~@body)))
(defmacro usetime
"This block content is not included at macro definition time.
For Clojure it always behaves like a `do` block.
For Clojurescript/JVM the block is only visible to Clojurescript.
For self-hosted Clojurescript the block is invisible when defining macros in the pseudo-namespace."
[& body]
(when #?(:clj true :cljs (not (re-matches #".*\$macros" (name (ns-name *ns*)))))
`(do ~@body)))
(defmacro case [& {:keys [cljs clj]}]
(if (contains? &env '&env)
`(if (:ns ~'&env) ~cljs ~clj)
(if #?(:clj (:ns &env) :cljs true)
cljs
clj)))
#?(:cljs (:require-macros [mount.tools.macrovich :refer [deftime]])
:clj (:require [mount.tools.macrovich :refer [deftime]])))
(deftime
(defmacro on-error [msg f & {:keys [fail?]
:or {fail? true}}]
`(case
:clj (try ~f
(catch Throwable t#
(if ~fail?
(throw (RuntimeException. ~msg t#))
{:f-failed (ex-info ~msg {} t#)})))
:cljs (try ~f
(catch :default t#
(if ~fail?
(throw (~'str ~msg " " t#))
{:f-failed (ex-info ~msg {} t#)})))))
(defmacro on-error [msg f & {:keys [fail?]
:or {fail? true}}]
`(mount.tools.macrovich/case
:clj (try ~f
(catch Throwable t#
(if ~fail?
(throw (RuntimeException. ~msg t#))
{:f-failed (ex-info ~msg {} t#)})))
:cljs (try ~f
(catch :default t#
(if ~fail?
(throw (~'str ~msg " " t#))
{:f-failed (ex-info ~msg {} t#)})))))
(defmacro throw-runtime [msg]
`(throw (case :clj (RuntimeException. ~msg)
:cljs (~'str ~msg))))
(defmacro throw-runtime [msg]
`(throw (mount.tools.macrovich/case :clj (RuntimeException. ~msg) :cljs (~'str ~msg))))
)

View file

@ -0,0 +1,21 @@
(ns ^{:doc "From https://github.com/cgrand/macrovich. Licensed under EPL v1.
Copyright Cristophe Grand." }
mount.tools.macrovich
(:refer-clojure :exclude [case]))
(defmacro deftime
"This block will only be evaluated at the correct time for macro definition, at other times its content
are removed.
For Clojure it always behaves like a `do` block.
For Clojurescript/JVM the block is only visible to Clojure.
For self-hosted Clojurescript the block is only visible when defining macros in the pseudo-namespace."
[& body]
(when #?(:clj (not (:ns &env)) :cljs (re-matches #".*\$macros" (name (ns-name *ns*))))
`(do ~@body)))
(defmacro case [& {:keys [cljs clj]}]
(if (contains? &env '&env)
`(if (:ns ~'&env) ~cljs ~clj)
(if #?(:clj (:ns &env) :cljs true)
cljs
clj)))