aboutsummaryrefslogtreecommitdiff
path: root/lux-lein/src/leiningen/lux/watch.clj
blob: 87f8929e18a0e19391c3062738389cabf797fd3a (plain)
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
;;  Copyright (c) Eduardo Julian. All rights reserved.
;;  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
;;  If a copy of the MPL was not distributed with this file,
;;  You can obtain one at http://mozilla.org/MPL/2.0/.

(ns leiningen.lux.watch
  (:require [leiningen.core.classpath :as classpath])
  (:import (java.io File)
           (java.nio.file FileSystems
                          Path
                          WatchEvent$Kind
                          StandardWatchEventKinds
                          WatchService
                          WatchKey)))

(defn ^:private file-tree [path]
  (let [dir (new File path)]
    (if (and (.exists dir)
             (.isDirectory dir))
      (->> (.listFiles dir) (mapcat (comp file-tree #(.getAbsolutePath ^File %))) (cons path))
      (list))))

(defn ^:private drain! [^WatchService watcher]
  (when-let [^WatchKey key (.poll watcher)]
    (when (and (.isValid key)
               (not (.isEmpty (.pollEvents key))))
      
      (.reset key)
      (recur watcher))))

(defn watch [action project]
  (let [fs (FileSystems/getDefault)
        ^WatchService watcher (.newWatchService fs)
        dirs-to-watch (->> (concat (get project :test-paths (list))
                                   (get project :source-paths (list)))
                           (mapcat file-tree)
                           (map #(.getPath fs % (into-array String []))))
        _ (doseq [^Path dir dirs-to-watch]
            (.register dir watcher (into-array WatchEvent$Kind [StandardWatchEventKinds/ENTRY_MODIFY])))]
    (do (action)
      (loop []
        (do (when-let [^WatchKey key (.poll watcher)]
              (when (.isValid key)
                (.pollEvents key)
                (.reset key)
                (drain! watcher)
                (action)))
          (Thread/sleep 1000)
          (recur))))
    ))