/
apathetic-watch.rkt
64 lines (56 loc) · 2.11 KB
/
apathetic-watch.rkt
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
#lang racket/base
(require
racket/contract)
(provide
(contract-out
[apathetic-watch (->* () (path-on-disk?) thread?)]))
;; ------------------------------------------------------------------
;; Implementation
(require
racket/file
racket/async-channel
"./filesystem.rkt"
"./threads.rkt")
(define-values (report-activity report-status) (report-iface 'apathetic))
(define (apathetic-watch [path (current-directory)])
(thread (lambda ()
(let loop ()
(with-handlers ([exn:fail:filesystem? void])
(sync/enable-break
(guard-evt (lambda () (report-status 'watching path) never-evt))
(bulk-filesystem-change-evt (cons path (if (directory-exists? path)
(recursive-file-list path)
null))))
(report-activity 'change path)
(loop))))))
(module+ test
(require
rackunit
(submod "./filesystem.rkt" test-lib)
(submod "./threads.rkt" test-lib))
(test-case
"Apathetic watch on directory"
(parameterize ([current-directory (create-temp-directory)])
(define th (apathetic-watch))
(define wd (current-directory))
(define (lifecycle thunk)
(expect-status (list 'apathetic 'watching wd))
(thunk)
(expect-activity (list 'apathetic 'change wd)))
(lifecycle (lambda () (create-file "a")))
(lifecycle (lambda () (make-directory "dir")))
(lifecycle (lambda () (create-file "dir/b"))) ; Make sure new files are caught recursively
(lifecycle (lambda () (delete-directory/files wd)))
(expect-silence)
(check-true (thread-dead? th))))
(test-case
"Apathetic watch on file"
(parameterize ([current-directory (create-temp-directory)])
(define target (build-path "solo"))
(create-file target)
(define th (apathetic-watch target))
(expect-status (list 'apathetic 'watching target))
(delete-file "solo")
(expect-activity (list 'apathetic 'change target))
(expect-silence)
(check-true (thread-dead? th)))))