-
Notifications
You must be signed in to change notification settings - Fork 16
/
repl.clj
102 lines (89 loc) · 2.73 KB
/
repl.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(ns juxt.clip.repl
"REPL utilities for running a system during development."
(:require
[clojure.tools.namespace.repl :as tns.repl]
[juxt.clip.core :as clip]
[juxt.clip.edn :as clip.edn]))
(tns.repl/disable-reload!)
(def ^:private default-initializer
(fn [& args]
(throw (Error. "No function to get system config found. Did you forget to run `set-init!`?"))))
(def system nil)
(def ^:private initializer default-initializer)
(defn- stop-system
[system]
(when system
(let [{::keys [deref] :as system-config} (::system-config (meta system))]
(deref (clip/stop system-config system))))
nil)
(defn- start-system
[system-config]
(let [{::keys [deref]} system-config]
(vary-meta
(try
(deref (clip/start system-config))
(catch Throwable t
(if-let [system (::clip/system (ex-data t))]
;; Partially started system found, we should call stop on it to clean
;; up.
(do
(try
(clip/stop system-config system)
(catch Throwable stop-t
(throw
(ex-info
"Exception thrown while starting system. Exception also thrown while stopping system."
{:stop-exception stop-t}
t))))
(throw (ex-cause t)))
(throw t))))
merge {::system-config system-config})))
(defn- force*
"Like force, but for anything that can be deref'd"
[ref]
(if
(or (instance? clojure.lang.IBlockingDeref ref)
(instance? java.util.concurrent.Future ref))
(deref ref)
ref))
(defmethod clip.edn/load-key ::deref
[_k deref]
(if (fn? deref)
deref
(requiring-resolve deref)))
(defn set-init!
"Set the initializer to init-fn. Should be a function which takes no
arguments and returns the system config to use for the REPL."
[init-fn]
(alter-var-root #'initializer (constantly #(merge {::deref force*} (init-fn)))))
(defn start
"Stops any existing systems and starts a new one calling the initializer set
by set-init!"
[]
(alter-var-root
#'system
(fn [system]
(stop-system system)
(start-system (initializer))))
:started)
(defn ^:deprecated go
"Calls `start`. Exists for compatibility with other component libraries."
[]
(start))
(defn stop
"Stop the running system (if running)"
[]
(alter-var-root #'system stop-system)
:stopped)
(defn reset
"Stop the running system, refresh using tools.namespace, and then start the
new system."
[]
(stop)
(tns.repl/refresh :after `start))
(defn reset-all
"Stop the running system, refresh-all using tools.namespace, and then start
the new system."
[]
(stop)
(tns.repl/refresh-all :after `start))