/
plugin.clj
104 lines (87 loc) · 3.01 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
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
103
104
(ns kaocha.plugin
(:require [kaocha.output :as output]
[clojure.string :as str]
[slingshot.slingshot :refer [try+ throw+]]))
(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 [plugin-name]
(if (qualified-keyword? plugin-name)
(when-not (try-require (symbol (str (namespace plugin-name) "." (name plugin-name))))
(try-require (symbol (namespace plugin-name))))
(try-require (symbol (name plugin-name)))))
(defmulti -register "Add your plugin to the stack"
(fn [name plugins] name))
(defmethod -register :default [name plugins]
(output/error "Couldn't load plugin " name)
(throw+ {:kaocha/early-exit 254} nil (str "Couldn't load plugin " name)))
(defn register [plugin-name plugin-stack]
(try-load-third-party-lib plugin-name)
(-register plugin-name plugin-stack))
(defn normalize-name [plugin-name]
(if (and (simple-keyword? plugin-name)
(not (str/includes? "." (name plugin-name))))
;; Namespaces without a period are not valid, we treat these as
;; kaocha.plugin/*
(keyword "kaocha.plugin" (name plugin-name))
plugin-name))
(defn load-all [names]
(reduce #(register %2 %1) [] (distinct (map normalize-name 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)
(output/warn "Plugin " (:kaocha.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)
var-sym (symbol (str (name id) "-hooks"))
[desc & hooks] (if (string? (first hooks))
hooks
(cons "" hooks))]
`(do
~@(map (fn [[hook & fn-tail]]
`(defn ~(symbol (str (name id) "-" hook "-hook")) ~@fn-tail))
hooks)
(def ~var-sym
~(into {:kaocha.plugin/id plugin-id
:kaocha.plugin/description desc}
(map (fn [[hook & _]]
[(keyword "kaocha.hooks" (str hook))
(symbol (str (name id) "-" hook "-hook"))]))
hooks))
(defmethod -register ~plugin-id [_# plugins#]
(conj plugins# ~var-sym)))))
(comment
(= (run-hook [{:foo inc} {:foo inc}] :foo 2)
4))
;; HOOKS
;; :cli-options
;; :config
;; :pre-load
;; :post-load
;; :pre-run
;; :post-run
;; :wrap-run
;; :pre-test
;; :post-test
;; :pre-report
;; :pre-load-test
;; :post-load-test
;; :post-summary
;; :main