~evhan/beaker

beaker/chicken-clean.scm -rw-r--r-- 3.6 KiB
ca9604fcEvan Hanson Add links to example uses of Nix helpers 1 year, 5 months ago
                                                                                
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Clean up build artifacts.
;;;
;;; Copyright (c) 2018-2019, Evan Hanson
;;;
;;; See LICENSE for details.
;;;

;;
;; The `chicken-clean` program deletes egg build artifacts.
;;
;; A simple set of file patterns is used to determine what should be
;; deleted. This includes compiled programs, binary objects (`o`, `obj`,
;; `so`, `dll`), and files generated by the CHICKEN toolchain (`build.sh`,
;; `install.sh`, `import.scm`, `inline`, `profile`, `types`).
;;
;; When run with the `-interactive` flag, a confirmation prompt will be
;; displayed before any files are deleted.
;;
(declare
  (module (chicken-clean))
  (import (beaker egg info)
          (beaker interactive)
          (chicken condition)
          (chicken errno)
          (chicken file)
          (chicken irregex)
          (chicken pathname)
          (chicken process-context)
          (chicken sort)
          (chicken string)
          (srfi 1)))

(define (local-egg-build-artifacts)
  (let ((egg-files (glob "*.egg" "chicken/*.egg")))
    (map symbol->string (append-map egg-programs egg-files))))

(define (disposable-file? path)
  (and (not (directory-exists? path))
       (or (member (normalize-pathname path)
                   (local-egg-build-artifacts))
           (irregex-match
            `(or ,(glob->sre "*.o")
                 ,(glob->sre "*.obj")
                 ,(glob->sre "*.so")
                 ,(glob->sre "*.dll")
                 ,(glob->sre "*.build.sh")
                 ,(glob->sre "*.build.target.sh")
                 ,(glob->sre "*.install.sh")
                 ,(glob->sre "*.install.target.sh")
                 ,(glob->sre "*.import.scm")
                 ,(glob->sre "*.inline")
                 ,(glob->sre "*.link")
                 ,(glob->sre "*.profile")
                 ,(glob->sre "*.types"))
            (pathname-strip-directory path)))))

(define (file-removal-summary paths)
  (conc "The following files will be removed:"
        #\newline
        #\newline
        (foldl (lambda (s p) (conc s "  " p #\newline)) "" paths)
        #\newline
        "Continue?"))

(define (disposable-directory? path)
  (and (directory-exists? path)
       ((flip every)
        (directory path)
        (lambda (p)
          (let ((p* (make-pathname path p)))
            (or (disposable-file? p*)
                (disposable-directory? p*)))))))

(define (remove-file path)
  (message 1 (conc "Removing " path))
  (delete-file* path))

(define (remove-directory path)
  (message 1 (conc "Removing " path))
  (condition-case (delete-directory path)
    (e (i/o file)
       (unless (or (= (errno) errno/noent)
                   (= (errno) errno/notempty))
         (signal e)))))

(define (clean-working-directory)
  (let* ((files       (find-files "." test: disposable-file?))
         (directories (find-files "." test: disposable-directory?))
         (sorted      (sort (append files directories) string<?)))
    (when (and (pair? sorted) (prompt (file-removal-summary sorted)))
      (for-each remove-file files)
      (for-each remove-directory directories))))

(define (usage status)
  (message 0 (conc "Usage: " (pathname-file (program-name)) " [-interactive | -quiet | -verbose]"))
  (exit status))

(define (main)
  ((flip for-each)
   (command-line-arguments)
   (lambda (flag)
     (case (string->symbol flag)
       ((-quiet) (verbosity (sub1 (verbosity))))
       ((-verbose) (verbosity (add1 (verbosity))))
       ((-interactive) (interactive #t))
       ((-h -help) (usage 0))
       (else (usage 1)))))
  (clean-working-directory))

(cond-expand
  (compiling (main))
  (else))