/
plugin.clj
69 lines (56 loc) · 1.83 KB
/
plugin.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
(ns kaocha.plugin
(:require [kaocha.output :as out]))
(def ^:dynamic *current-chain* [])
(defmacro with-plugins [chain & body]
`(binding [*current-chain* ~chain] ~@body))
;; TODO: duplicated from testable, not sure yet where to put it.
(defn- try-require [n]
(try
(require n)
true
(catch java.io.FileNotFoundException e
false)))
(defn try-load-third-party-lib [type]
(if (qualified-keyword? type)
(when-not (try-require (symbol (str (namespace type) "." (name type))))
(try-require (symbol (namespace type))))
(try-require (symbol (name type)))))
(defmulti -register "Add your plugin to the stack"
(fn [name plugins] name))
(defn register [name plugins]
(try-load-third-party-lib name)
(-register name plugins))
(defn load-all [names]
(reduce #(register %2 %1) [] names))
(defn run-hook* [plugins step value & extra-args]
(reduce (fn [value plugin]
(if-let [step-fn (get plugin step)]
(let [value (apply step-fn value extra-args)]
(when (nil? value)
(out/warn "Plugin " (:id plugin) " hook " step " returned nil."))
value)
value))
value
plugins))
(defn run-hook [step value & extra-args]
(apply run-hook* *current-chain* step value extra-args))
(defmacro defplugin
{:style/indent [1 :form [1]]}
[id & hooks]
(let [plugin-id (keyword id)]
`(defmethod -register ~plugin-id [_# plugins#]
(conj plugins#
~(into {:kaocha.plugin/id plugin-id}
(map (fn [[hook & fn-tail]]
[(keyword "kaocha.hooks" (str hook))
`(fn ~@fn-tail)]))
hooks)))))
(comment
(= (run-hook [{:foo inc} {:foo inc}] :foo 2)
4))
;; HOOKS
;; :config
;; :pre-load
;; :post-load
;; :pre-run
;; :post-run