-
Notifications
You must be signed in to change notification settings - Fork 5
/
watch_deps.clj
88 lines (78 loc) · 3.15 KB
/
watch_deps.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
(ns lambdaisland.classpath.watch-deps
"Watch deps.edn for changes"
(:require [clojure.java.classpath :as cp]
[clojure.string :as str]
[clojure.java.io :as io]
[clojure.tools.deps.alpha :as deps]
[lambdaisland.classpath :as licp]
[nextjournal.beholder :as beholder])
(:import java.util.regex.Pattern
java.nio.file.LinkOption
java.nio.file.Paths))
(def watcher (atom nil))
(defn canonical-path [p]
(.toRealPath (Paths/get p (into-array String [])) (into-array LinkOption [])))
(def process-root-path (canonical-path "."))
(defn- on-event [deps-path opts {:keys [type path]}]
(locking watcher
(when (and (= :modify type)
;; Before we used "." as the watch path, resulting in a
;; difference between mac, where the path would look like this
;; `/Users/x/project/./deps.edn`, vs Linux where the path would
;; look like this `./deps.edn`.
;;
;; We now turn `"."` into a canonical path before starting the
;; watcher, which means we get fully qualified filenames for both
;; in this equality check.
(= path deps-path))
(try
(println "✨ Reloading"
(str (.relativize process-root-path path))
"✨")
(let [added-paths (remove (set (map str (cp/system-classpath)))
(:classpath-roots (deps/create-basis opts)))]
(doseq [path added-paths]
(println "+" (str/replace path #"^.*/\.m2/repository/" "")))
(licp/install-priority-loader! added-paths))
(catch Exception e
(println "Error while reloading deps.edn")
(println e))))))
(defn start!
"Start a file system watcher to pick up changes in `deps.edn'
Options are passed on to tools.deps when creating the basis, you probably want
to at least put the `:aliases` you need in there.
```
(start! {:aliases [:dev :test]})
```
"
[opts]
(swap! watcher
(fn [w]
(when w
(println "Stopping existing `deps.edn' watchers")
(run! beholder/stop w))
(let [basis (deps/create-basis opts)
roots (cons (str process-root-path)
(when (:include-local-roots? opts)
(->> (vals (:libs basis))
(keep :local/root)
(map canonical-path)
(map str))))]
(doall
(for [root roots]
(beholder/watch
(partial #'on-event (Paths/get root (into-array String ["deps.edn"])) opts)
root)))))))
(defn stop!
"Stop a previously started watcher"
[opts]
(swap! watcher
(fn [w]
(when w
(beholder/stop w))
nil)))
(comment
(start! {:aliases [:dev]})
(deps/create-basis {:aliases [:backend]
:extra '{cider/cider-nrepl #:mvn{:version "0.28.5"}
refactor-nrepl/refactor-nrepl #:mvn{:version "3.5.2"}}}))