/
watch.clj
84 lines (78 loc) · 3.79 KB
/
watch.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
(ns kaocha.watch
(:require [hawk.core :as hawk]
[kaocha.api :as api]
[kaocha.result :as result]
[clojure.java.io :as io]
[lambdaisland.tools.namespace.dir :as ctn-dir]
[lambdaisland.tools.namespace.file :as ctn-file]
[lambdaisland.tools.namespace.parse :as ctn-parse]
[lambdaisland.tools.namespace.reload :as ctn-reload]
[lambdaisland.tools.namespace.track :as ctn-track]
[clojure.string :as str]
[clojure.set :as set]
[kaocha.testable :as testable]
[kaocha.stacktrace :as stacktrace]
[kaocha.output :as output]
[clojure.test :as t]))
(defn- try-run [config]
(let [result (try
(api/run config)
(catch Throwable t
(println "[watch] Fatal error in test run" t)))]
(println)
result))
(defn run [config]
(let [watch-paths (into #{} (comp (remove :kaocha.testable/skip)
(map (juxt :kaocha/test-paths :kaocha/source-paths))
cat
cat
(map io/file))
(:kaocha/tests config))
watch-chan (java.util.concurrent.ArrayBlockingQueue. 1024)
drain-watch-chan! (fn [] (doall (take-while identity (repeatedly #(.poll watch-chan)))))
tracker (-> (ctn-track/tracker)
(ctn-dir/scan-dirs watch-paths)
(dissoc :lambdaisland.tools.namespace.track/unload
:lambdaisland.tools.namespace.track/load))]
(future
(try
(loop [tracker tracker
focus nil]
(let [unload (set (::ctn-track/unload tracker))
load (set (::ctn-track/load tracker))
load-error (::ctn-file/load-error tracker)
reload (set/intersection unload load)
unload (set/difference unload reload)
load (set/difference load reload)
tracker (ctn-reload/track-reload (assoc tracker ::ctn-file/load-error {}))]
(when (seq load-error)
(doseq [[f e] load-error]
(output/warn "Failed loading" f)
(stacktrace/print-cause-trace e t/*stack-trace-depth*)))
(when (seq unload) (println "[watch] Unloading" unload))
(when (seq load) (println "[watch] Loading" unload))
(when (seq reload) (println "[watch] Reloading" reload))
(when (seq focus) (println "[watch] Re-running failed tests" (set focus)))
(let [config' (cond-> config (seq focus) (assoc :kaocha.filter/focus focus))
result (try-run config')]
(if (and (seq focus) (not (result/failed? result)))
(do
(println "[watch] Failed tests pass, re-running all tests.")
(drain-watch-chan!)
(recur (ctn-dir/scan-dirs tracker watch-paths) nil))
(let [f (.take watch-chan)]
(drain-watch-chan!)
(recur (ctn-dir/scan-dirs tracker watch-paths)
(->> result
testable/test-seq
(filter result/failed-one?)
(map ::testable/id))))))))
(catch Throwable t
(.printStackTrace t))
(finally
(println "[watch] loop broken"))))
(hawk/watch! [{:paths watch-paths
:handler (fn [ctx event]
(when (= (:kind event) :modify)
(.put watch-chan (:file event))))}])
@(promise)))