-
Notifications
You must be signed in to change notification settings - Fork 6
/
library.rkt
130 lines (114 loc) · 4.44 KB
/
library.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
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#lang racket/base
(require racket/contract
racket/dict
racket/file
racket/set
"base.rkt"
)
;; A library is a hash where a key is a directory (as a string)
;; and a value is a list of files (string without path) to *not* include (called exclusions).
;; That is, by default all non-excluded files are included (in particular the new ones).
(define (new-library)
(define lib (make-hash))
(add-directory! lib (path->string user-script-dir))
lib)
(define (library? lib)
(hash? lib))
(define (load [file library-file])
(if (file-exists? file)
(hash-copy (file->value file))
(new-library)))
(define (save! lib [file library-file])
(make-directory* user-script-dir)
(write-to-file lib file #:exists 'replace))
(define (directories lib)
(dict-keys lib))
(define (exclusions lib dir #:build? [build? #f])
(define exs (dict-ref lib (path-string->string dir) '()))
(if build?
(map (λ (x) (build-path dir x)) exs)
exs))
;; Returns the list of script files in the given directory.
;; If exclude is not #f, then only such files that are not listed as exclusions
;; in the library are returned.
(define (files lib [dir user-script-dir] #:exclude? [exclude? #t])
(define script-files
(map path->string
(filter (λ (f) (script-file? (build-path dir f)))
(if (directory-exists? dir)
(directory-list dir #:build? #f)
'()))))
(cond [exclude?
(define except-list (exclusions lib dir))
(set-subtract script-files except-list)]
[else script-files]))
;; Returns the list full paths of script files --in all listed directories of the library.
;; The keyword argument `exclude?' is as in `files'.
(define (all-files lib #:exclude? [exclude? #t])
(for*/list ([dir (in-dict-keys lib)]
[f (in-list (files lib dir #:exclude? exclude?))])
(build-path dir f)))
(define (add-directory! lib dir [excl '()])
(dict-ref! lib (path-string->string dir) excl)
(void))
(define (remove-directory! lib dir)
(dict-remove! lib (path-string->string dir)))
(define (exclude! lib dir filename)
(dict-update! lib
(path-string->string dir)
(λ (excl) (set-add excl filename))))
(define (include! lib dir filename)
(dict-update! lib
(path-string->string dir)
(λ (excl) (set-remove excl filename))))
(define (add-third-party-script-directory! dir [excl '()])
(define lib (load))
(add-directory! lib dir excl)
(save! lib))
(define (remove-third-party-script-directory! dir)
(define lib (load))
(remove-directory! lib dir)
(save! lib))
(provide/contract
[library? (any/c . -> . boolean?)]
[new-library (-> library?)]
[load ([]
[path-string?] ; does not need to exist
. ->* . library?)]
[save! ([library?]
[path-string?]
. ->* . void?)]
[directories (library?
. -> . (listof string?))]
[exclusions ([library? path-string?]
[#:build? boolean?]
. ->* . (listof path-string?))]
[files ([library?]
[path-string? #:exclude? boolean?]
. ->* . (listof string?))]
[all-files ([library?]
[#:exclude? boolean?]
. ->* . (listof path-string?))]
[add-directory! ([library?
(and/c path-string? absolute-path? directory-exists?)]
[list?]
. ->* . void?)]
[remove-directory! (library?
(and/c path-string? absolute-path?)
. -> . void?)]
[exclude! (library?
(and/c path-string? absolute-path?)
(and/c string? path-free?)
. -> . void?)]
[include! (library?
(and/c path-string? absolute-path?)
(and/c string? path-free?)
. -> . void?)]
[add-third-party-script-directory!
([(and/c path-string? absolute-path?)]
[(listof (and/c string? path-free?))]
. ->* . void?)]
[remove-third-party-script-directory!
((and/c path-string? absolute-path?)
. -> . void?)]
)