-
Notifications
You must be signed in to change notification settings - Fork 35
/
boot_reload.clj
91 lines (79 loc) · 3.19 KB
/
boot_reload.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
(ns adzerk.boot-reload
{:boot/export-tasks true}
(:require
[clojure.java.io :as io]
[clojure.set :as set]
[boot.pod :as pod]
[boot.file :as file]
[boot.util :refer :all]
[boot.core :refer :all]
[boot.from.backtick :refer [template]]))
(def ^:private deps '[[http-kit "2.1.18"]])
(defn- make-pod []
(future (-> (get-env) (update-in [:dependencies] into deps) pod/make-pod)))
(defn- changed [before after]
(when before
(->> (fileset-diff before after :hash)
output-files
(sort-by :dependency-order)
(map tmp-path))))
(defn- start-server [pod {:keys [ip port] :as opts}]
(let [{:keys [ip port]}
(pod/with-call-in pod (adzerk.boot-reload.server/start ~opts))
host (if-not (= ip "0.0.0.0") ip "localhost")]
(with-let [url (format "ws://%s:%d" host port)]
(info "<< started reload server on %s >>\n" url))))
(defn- write-cljs! [f url on-jsload]
(info "Writing %s...\n" (.getName f))
(->> (template
((ns adzerk.boot-reload
(:require
[adzerk.boot-reload.client :as client]
~@(when on-jsload [(symbol (namespace on-jsload))])))
(when-not (client/alive?)
(client/connect ~url {:on-jsload #(~(or on-jsload '+))}))))
(map pr-str) (interpose "\n") (apply str) (spit f)))
(defn- send-changed! [pod asset-path changed]
(when-not (empty? changed)
(pod/with-call-in pod
(adzerk.boot-reload.server/send-changed!
~(get-env :target-path)
~asset-path
~changed))))
(defn- add-init!
[in-file out-file]
(let [ns 'adzerk.boot-reload
spec (-> in-file slurp read-string)]
(when (not= :nodejs (-> spec :compiler-options :target))
(info "Adding :require %s to %s...\n" ns (.getName in-file))
(io/make-parents out-file)
(-> spec
(update-in [:require] conj ns)
pr-str
((partial spit out-file))))))
(deftask reload
"Live reload of page resources in browser via websocket.
The default configuration starts a websocket server on a random available
port on localhost."
[i ip ADDR str "The (optional) IP address for the websocket server to listen on."
p port PORT int "The (optional) port the websocket server listens on."
j on-jsload SYM sym "The (optional) callback to call when JS files are reloaded."
a asset-path PATH str "The (optional) asset-path. This is removed from the start of reloaded urls."]
(let [pod (make-pod)
src (tmp-dir!)
tmp (tmp-dir!)
prev (atom nil)
out (doto (io/file src "adzerk" "boot_reload.cljs") io/make-parents)]
(set-env! :source-paths #(conj % (.getPath src)))
(write-cljs! out (start-server @pod {:ip ip :port port}) on-jsload)
(comp
(with-pre-wrap fileset
(doseq [f (->> fileset input-files (by-ext [".cljs.edn"]))]
(let [path (tmp-path f)
in-file (tmp-file f)
out-file (io/file tmp path)]
(add-init! in-file out-file)))
(-> fileset (add-resource tmp) commit!))
(with-post-wrap fileset
(send-changed! @pod asset-path (changed @prev fileset))
(reset! prev fileset)))))