stowm 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,340 @@
1
+ ;; #-*- mode: nendo; syntax: scheme -*-;;
2
+ ;; main program of stowm
3
+
4
+ (require "fileutils")
5
+
6
+ (define (display-help)
7
+ (print "")
8
+ (print "Usage: ")
9
+ (print " 1. stowm URL of tar.gz ... fetch, generate specfile, build, install program.")
10
+ (print " stowm xxx.tar.gz ... generate specfile, build, install program.")
11
+ (print " 2. stowm list [proj] ... display installed program list.")
12
+ (print " 3. stowm enable [num] ... enable installed program. (stow -R)")
13
+ (print " stowm enable [proj] ... enable installed program by name. (stow -D & stow -R)")
14
+ (print " 4. stowm disable [num] ... disable installed program. (stow -D)")
15
+ (print " stowm disable [proj] ... disalbe installed program by name. (stow -D)")
16
+ (print " stowm rebuild [num] ... rebuild program. (create Makefile.tmp again)")
17
+ (print " 5 stowm env ... display stowm environment.")
18
+ (print ""))
19
+
20
+
21
+ (define (pickup-package path)
22
+ (cond
23
+ ((stowm-regex-match "/stow/([^/]+)" path)
24
+ => second)
25
+ (else
26
+ #f)))
27
+
28
+ ;; return:
29
+ ;; ( (package1 . symlink-file1) (package2 . symlink-file2) ... )
30
+ (define (get-installed-alist local stow-home)
31
+ (let1 script (sprintf "find %s -type l | grep -v %s > /tmp/stowm.cache\n" local stow-home)
32
+ (stowm-exec-sh script #f)
33
+ (with-open "/tmp/stowm.cache"
34
+ (lambda (f)
35
+ (let* ((froms
36
+ (map
37
+ (lambda (line)
38
+ (line.chomp))
39
+ (f.readlines.to_list)))
40
+ (link-alist
41
+ (filter-map
42
+ (lambda (fn)
43
+ (let1 link (pickup-package (File.readlink fn))
44
+ (and link
45
+ (cons link fn))))
46
+ froms)))
47
+ link-alist)))))
48
+
49
+ ;; return:
50
+ ;; (
51
+ ;; ;; (package-name installed? stowed? exist in repos?)
52
+ ;; (package1 i s p 0)
53
+ ;; (package2 #f #f #f 0)
54
+ ;; .
55
+ ;; .
56
+ ;; )
57
+ (define (get-stowed-list home-repos stow-home link-alist)
58
+ (let* ((projs (stowm-get-dir-entries home-repos))
59
+ (projs-hash (apply hash-table eq?
60
+ (map (lambda (x) (cons x #t))
61
+ projs)))
62
+ (stowed (stowm-get-dir-entries stow-home))
63
+ (stowed-hash (apply hash-table eq?
64
+ (map (lambda (x) (cons x #t))
65
+ stowed)))
66
+ (all (sort (delete-duplicates (append projs stowed))))
67
+ (installed-hash (alist->hash-table link-alist)))
68
+ (map
69
+ (lambda (x cnt)
70
+ (cons x ;; package-name like "ruby-2.1.3"
71
+ (list
72
+ (if (hash-table-exist? stowed-hash x)
73
+ (if (hash-table-exist? installed-hash x) 'e false) ;; enabled?
74
+ false)
75
+ (if (hash-table-exist? stowed-hash x) 'i false) ;; installed to stow directory?
76
+ (if (hash-table-exist? projs-hash x) 's false) ;; exist specfile?
77
+ cnt)))
78
+ all
79
+ (range (length all)))))
80
+
81
+ ;; rebuild ~/.stowm.db
82
+ (define (save-installed-db env)
83
+ (let* ([link-alist (get-installed-alist (local env) (stow-home env))]
84
+ [stowed-list (get-stowed-list (home-repos env) (stow-home env) link-alist]])
85
+ (printf "Info: rebuild [%s]\n" (db-path env))
86
+ (with-open (db-path env)
87
+ (lambda (f)
88
+ (pretty-print stowed-list f))
89
+ "w"))
90
+ 0)
91
+
92
+ ;; rebuild latest installed db info.
93
+ (define (rebuild-installed-db env)
94
+ (when (or
95
+ (not (File.exist? (db-path env)))
96
+ (let ([stow-home-fs (File::Stat.new (stow-home env))]
97
+ [db-fs (File::Stat.new (db-path env))])
98
+ (<
99
+ (db-fs.mtime.to_i)
100
+ (stow-home-fs.mtime.to_i)))
101
+ (let ((local-bin-fs (File::Stat.new (bin env))]
102
+ [db-fs (File::Stat.new (db-path env))])
103
+ (<
104
+ (db-fs.mtime.to_i)
105
+ (local-bin-fs.mtime.to_i))))
106
+ (save-installed-db env))
107
+ (with-open (db-path env)
108
+ (lambda (f)
109
+ (read f))))
110
+
111
+
112
+
113
+ (define (display-list stowed-list keyword)
114
+ (define (ox bool-val)
115
+ (if bool-val "O" "-"))
116
+ (define _format_h " %-35s %11s %11s\n")
117
+ (define _format_d " %3d) %-35s %11s %11s\n")
118
+
119
+ (let1 lst
120
+ (if keyword
121
+ (filter
122
+ (lambda (x)
123
+ (stowm-regex-match keyword (car x)))
124
+ (stowed-list-to-tree stowed-list))
125
+ (stowed-list-to-tree stowed-list))
126
+
127
+ (print
128
+ (apply +
129
+ (cons
130
+ (sprintf _format_h " <name>" "<enabled>" "<installed>")
131
+ (map
132
+ (lambda (tree)
133
+ (apply +
134
+ (cons
135
+ (sprintf " %s \n" (car tree))
136
+ (map
137
+ (lambda (x)
138
+ (sprintf _format_d
139
+ (fifth x)
140
+ (+ " " (first x))
141
+ (ox (second x))
142
+ (ox (third x))))
143
+ (cdr tree)))))
144
+ lst))))))
145
+
146
+ (define (stowm-stderr-tee str)
147
+ (STDERR.printf "Info: %s\n" str)
148
+ str)
149
+
150
+
151
+ (define (stowm-restow env delete-item restow-item)
152
+ (let1 script (string-join
153
+ (list
154
+ (+ "cd " (stow-home env))
155
+ (if (null? delete-item)
156
+ ""
157
+ (stowm-stderr-tee (sprintf "%s -D %s" (stow-program env) (car delete-item))))
158
+ (if (null? restow-item)
159
+ ""
160
+ (stowm-stderr-tee (sprintf "%s -R %s" (stow-program env) (car restow-item))))
161
+ "")
162
+ "\n")
163
+ (stowm-exec-sh script #f)
164
+ (save-installed-db env)
165
+ (with-open (db-path env)
166
+ (lambda (f)
167
+ (read f)))))
168
+
169
+
170
+ ;; build the package
171
+ (define (build-package env spec-obj makefile-dir)
172
+ (let* (
173
+ [makefile-path
174
+ (+ makefile-dir "/Makefile.tmp")]
175
+ [makefile-str
176
+ (create-makefile spec-obj (home-repos env))])
177
+
178
+ ;; save Makefile.tmp and build
179
+ (with-open
180
+ makefile-path
181
+ (lambda (f)
182
+ (f.printf "%s" makefile-str)
183
+ (STDERR.printf "Info : created Makefile [%s] \n" makefile-path))
184
+ "w")
185
+
186
+ (let1 script (+
187
+ (sprintf "make -C %s -f Makefile.tmp clean\n" makefile-dir)
188
+ (sprintf "make -C %s -f Makefile.tmp\n" makefile-dir))
189
+ (stowm-exec-sh script))))
190
+
191
+
192
+ ;; action by url
193
+ (define (action-by-url env url)
194
+ (let* ([parsed (stowm-parse-url url)]
195
+ [specfile-str
196
+ (create-specfile (stow-home env) url)]
197
+ [specfile-dir
198
+ (+ (home-repos env) "/" (package parsed))]
199
+ [specfile-path
200
+ (+ specfile-dir "/" (package parsed) ".yml")]
201
+ [makefile-dir
202
+ (+ (temp env) "/" (package parsed))])
203
+
204
+ ;; create directory
205
+ (when (not (File.exist? specfile-dir))
206
+ (FileUtils.mkdir_p specfile-dir))
207
+
208
+ (when (not (File.exist? makefile-dir))
209
+ (FileUtils.mkdir_p makefile-dir))
210
+
211
+ ;; save specfile
212
+ (if (File.exist? specfile-path)
213
+ (STDERR.printf "Info : alreay exist [%s] file. didn't touch.\n" specfile-path)
214
+ (with-open
215
+ specfile-path
216
+ (lambda (f)
217
+ (f.printf "%s" specfile-str)
218
+ (STDERR.printf "Info : created spec [%s] \n" specfile-path))
219
+ "w"))
220
+
221
+ ;; load exist specfile
222
+ (let1 spec-obj
223
+ (cond
224
+ ((File.exist? specfile-path)
225
+ (load-specfile specfile-path))
226
+ (else
227
+ (STDERR.printf "Error : not exist specfile [%s].")
228
+ (exit 1)))
229
+ (build-package env spec-obj makefile-dir))))
230
+
231
+
232
+
233
+ (define (action-by-keyword-name env keyword name stowed-list)
234
+ ;; resolve program number by name
235
+ (let1 tree (stowed-list-to-tree stowed-list)
236
+ (cond
237
+ ((eqv? 'enable keyword)
238
+ (let1 num
239
+ (resolve-program-number name 'e tree)
240
+ (if num
241
+ ;; restow already enabled one
242
+ (action-by-keyword-num env 'enable num stowed-list)
243
+ (begin
244
+ (STDERR.printf "Error: package [%s] was not stowed yet.\n" name)
245
+ (display-help)
246
+ (exit 1)))))
247
+ ((eqv? 'disable keyword)
248
+ (let1 num
249
+ (resolve-program-number name 'e tree)
250
+ (if num
251
+ ;; disable already enabled one
252
+ (action-by-keyword-num env 'disable num stowed-list)
253
+ (begin
254
+ (STDERR.printf "Error: selected package [%s] was not enabled.\n" name)
255
+ (display-help)
256
+ (exit 1))))))))
257
+
258
+
259
+ (define (rebuild-num env number stowed-list)
260
+ (let1 found
261
+ (filter
262
+ (lambda (x)
263
+ (= number (fifth x)))
264
+ stowed-list)
265
+ (if (null? found)
266
+ (begin
267
+ (STDERR.printf "Error: selected number [%d] was not found...\n" number)
268
+ (exit 1))
269
+ (let* ([dirname (caar found)]
270
+ [basename (car (stowm-split-filename dirname))]
271
+ [specfile-dir
272
+ (+ (home-repos env) "/" dirname)]
273
+ [specfile-path
274
+ (+ specfile-dir "/" dirname ".yml")]
275
+ [makefile-dir
276
+ (+ (temp env) "/" dirname)])
277
+
278
+ ;; load exist specfile
279
+ (let1 spec-obj
280
+ (cond
281
+ ((File.exist? specfile-path)
282
+ (load-specfile specfile-path))
283
+ (else
284
+ (STDERR.printf "Error : not exist specfile [%s].")
285
+ (exit 1)))
286
+ (build-package env spec-obj makefile-dir))))))
287
+
288
+
289
+ (define (action-by-keyword-num env keyword number stowed-list)
290
+
291
+ (let* ([delete-action (eqv? 'disable keyword)]
292
+ ;; ----------
293
+ ;; search the number in list
294
+ ;; ----------
295
+ (found
296
+ (filter
297
+ (lambda (x)
298
+ (= number (fifth x)))
299
+ stowed-list)))
300
+ (if (null? found)
301
+ (begin
302
+ (STDERR.printf "Error: selected number [%d] was not found...\n" number)
303
+ (exit 1))
304
+ (let* ([dirname (caar found)]
305
+ [basename (car (stowm-split-filename dirname))]
306
+ [tree (stowed-list-to-tree stowed-list)]
307
+ [selection (assv-ref basename tree)])
308
+ (let ((delete-item
309
+ (filter-map
310
+ (lambda (x)
311
+ (if (= 'e (second x)) ;; enabled?
312
+ (car x)
313
+ nil))
314
+ selection))
315
+ (restow-item
316
+ (filter-map
317
+ (lambda (x)
318
+ (if (and (= 'i (third x)) ;; installed?
319
+ (= number (fifth x)))
320
+ (car x)
321
+ nil))
322
+ selection)))
323
+ (cond
324
+ ((null? restow-item)
325
+ (STDERR.printf "Error: selected number [%d] was not installed yet. \n" number)
326
+ (exit 1))
327
+ (delete-action
328
+ (let1 lst (stowm-restow env delete-item '())
329
+ (display-list lst basename)))
330
+ ((equal? delete-item restow-item)
331
+ (STDERR.printf "Info: restow [%s].\n" (car restow-item))
332
+ (let1 lst (stowm-restow env delete-item restow-item)
333
+ (display-list lst basename)))
334
+ (else
335
+ (let1 lst (stowm-restow env delete-item restow-item)
336
+ (display-list lst basename)))))))))
337
+
338
+ (define uname
339
+ (let1 f (IO.popen "uname" "r+")
340
+ f.readline.chop))