-
Notifications
You must be signed in to change notification settings - Fork 3
/
list-files.lisp
118 lines (107 loc) · 4.98 KB
/
list-files.lisp
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
#+xcvb (module (:depends-on ("dependencies-interpreter" "commands")))
(in-package :xcvb)
;;; LIST-GRAINS
(defparameter *grains-list* ())
(defparameter *grains-table* (make-hash-table :test 'equal))
(defclass grain-listing-traversal (simplifying-traversal)
())
(defmethod graph-for :around ((env grain-listing-traversal) spec)
(multiple-value-bind (v foundp) (gethash spec *grains-table*)
(if foundp
v
(progn
(setf (gethash spec *grains-table*) nil)
(let ((v (call-next-method)))
(setf (gethash spec *grains-table*) v)
(pushnew v *grains-list*)
v)))))
(defun list-grains (specs)
(let ((env (make-instance 'grain-listing-traversal))
(*use-cfasls* nil)
(*grains-list* ())
(*grains-table* (make-hash-table :test 'equal)))
(dolist (spec specs)
(build-command-for env spec))
(reverse *grains-list*)))
;;; TODO: some magic to break circularities that are due to flattening conditionals.
(define-build-command-for :when ((env grain-listing-traversal) expression &rest dependencies)
(declare (ignore expression))
(build-command-for* env dependencies))
(define-build-command-for :cond ((env grain-listing-traversal) &rest cond-expressions)
(dolist (cond-expression cond-expressions)
(build-command-for* env (cdr cond-expression))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Remove XCVB ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-command remove-xcvb-command
(("remove-xcvb" "rm-x" "rmx" "rx")
(&rest keys &key)
`(,@+build-option-spec+
,@+source-registry-option-spec+
,@+verbosity-option-spec+)
"Remove XCVB modules from files in build"
"Given an XCVB build file, removes the XCVB modules from each of the files listed in the build file."
(build))
(apply 'handle-global-options keys)
(remove-xcvb-from-build build))
(define-command list-files-command
(("list-files" "lf")
(&rest keys &key)
`(,@+multi-build-option-spec+
,@+source-registry-option-spec+
,@+verbosity-option-spec+
(("long" #\l) :type boolean :optional t :documentation "long format"))
"List files in a XCVB build"
"Given an XCVB build file, list all files that are directly part of that build."
(build long))
(apply 'handle-global-options keys)
(log-format 10 "Listing files for build ~S~%" build)
;; TODO: Put handle-case here to trap the error for a noncanonical fullname
;; the the user is likely to type one day by accident.
(loop :for spec :in build
:for (target bgrain) = (multiple-value-list (handle-target spec))
:collect target :into targets
:collect bgrain :into builds
:finally
(let* ((all-grains (list-grains targets))
(grains (remove-if-not
(lambda (grain)
(and (typep grain '(or lisp-module-grain source-grain))
(member (build-module-grain-for grain) builds)))
(remove-duplicates all-grains)))
(files (mapcar 'grain-pathname grains)))
(format t (if long "(~{~S~^~%~})~%" "~{~A~%~}") files))))
(define-command purge-xcvb-command
(("purge-xcvb" "pux" "px")
(files) ()
"Remove XCVB module statements from explicitly listed files"
"Given a list of files, remove the XCVB module statements from each Lisp file and delete specified build files.")
(initialize-environment)
(loop :for f :in files
:for p = (probe-file f) :do
(when p
(cond
((equal (cons (pathname-name p) (pathname-type p)) '("build" . "xcvb"))
(delete-file p))
((equal (pathname-type p) "lisp")
(log-format 4 "Removing module statements from ~A" p)
(remove-module-from-file p))))))
;; Using the build.xcvb as a starting point, finds files and
;; strips XCVB modules from them.
(defun remove-xcvb-from-build (fullname)
(multiple-value-bind (target-dependency build) (handle-target fullname)
(log-format 7 "Removing XCVB from build ~A~% (path ~S)" build (grain-pathname build))
(flet ((source-lisp-grain-p (grain)
(log-format 7 "Inspecting grain ~A" grain)
(when (and (typep grain 'lisp-file-grain)
(slot-boundp grain 'computation)
(null (grain-computation grain)))
(log-format 8 "This grain is in build ~A" (build-module-grain-for grain))
(log-format 9 "EQ: ~A EQUAL NAMES: ~A"
;; for some reason, the builds are different objects(!). HOW???
(eq build (build-module-grain-for grain))
(equal (fullname build) (fullname (build-module-grain-for grain))))
(equal (fullname build) (fullname (build-module-grain-for grain))))))
(dolist (grain (remove-if-not #'source-lisp-grain-p (list-grains (list target-dependency))))
(log-format 5 "Removing module declaration from ~A" (grain-pathname grain))
(remove-module-from-file (grain-pathname grain))))
(log-format 5 "Deleting build file for ~A" (grain-pathname build))
(delete-file (grain-pathname build))))