File: bundle.lisp

package info (click to toggle)
acl2 7.2dfsg-3
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 198,968 kB
  • ctags: 182,300
  • sloc: lisp: 2,415,261; ansic: 5,675; perl: 5,577; xml: 3,576; sh: 3,255; cpp: 2,835; makefile: 2,440; ruby: 2,402; python: 778; ml: 763; yacc: 709; csh: 355; php: 171; lex: 162; tcl: 44; java: 24; asm: 23; haskell: 17
file content (148 lines) | stat: -rw-r--r-- 6,220 bytes parent folder | download
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(cl:in-package #:cl-user)

(eval-when (:compile-toplevel :load-toplevel :execute)
  (require "asdf")
  (unless (find-package '#:asdf)
    (error "ASDF could not be required")))

(let ((indicator '#:ql-bundle-v1)
      (searcher-name '#:ql-bundle-searcher)
      (base (make-pathname :name nil :type nil
                           :defaults #. (or *compile-file-truename*
                                            *load-truename*))))
  (labels ((file-lines (file)
             (with-open-file (stream file)
               (loop for line = (read-line stream nil)
                     while line
                     collect line)))
           (relative (pathname)
             (merge-pathnames pathname base))
           (pathname-timestamp (pathname)
             #+clisp
             (nth-value 2 (ext:probe-pathname pathname))
             #-clisp
             (file-write-date pathname))
           (system-table (table pathnames)
             (dolist (pathname pathnames table)
               (setf (gethash (pathname-name pathname) table)
                     (relative pathname))))

           (initialize-bundled-systems-table (table data-source)
             (system-table table (file-lines data-source)))

           (local-projects-system-pathnames (data-source)
             (let ((files (directory (merge-pathnames "**/*.asd"
                                                      data-source))))
               (stable-sort (sort files #'string< :key #'namestring)
                            #'<
                            :key (lambda (file)
                                   (length (namestring file))))))
           (initialize-local-projects-table (table data-source)
             (system-table table (local-projects-system-pathnames data-source)))

           (make-table (&key data-source init-function)
             (let ((table (make-hash-table :test 'equalp)))
               (setf (gethash "/data-source" table)
                     data-source
                     (gethash "/timestamp" table)
                     (pathname-timestamp data-source)
                     (gethash "/init" table)
                     init-function)
               table))

           (tcall (table key &rest args)
             (let ((fun (gethash key table)))
               (unless (and fun (functionp fun))
                 (error "Unknown function key ~S" key))
               (apply fun args)))
           (created-timestamp (table)
             (gethash "/timestamp" table))
           (data-source-timestamp (table)
             (pathname-timestamp (data-source table)))
           (data-source (table)
             (gethash "/data-source" table))

           (stalep (table)
             ;; FIXME: Handle newly missing data sources?
             (< (created-timestamp table)
                (data-source-timestamp table)))
           (meta-key-p (key)
             (and (stringp key)
                  (< 0 (length key))
                  (char= (char key 0) #\/)))
           (clear (table)
             ;; Don't clear "/foo" keys
             (maphash (lambda (key value)
                        (declare (ignore value))
                        (unless (meta-key-p key)
                          (remhash key table)))
                      table))
           (initialize (table)
             (tcall table "/init" table (data-source table))
             (setf (gethash "/timestamp" table)
                   (pathname-timestamp (data-source table)))
             table)
           (update (table)
             (clear table)
             (initialize table))
           (lookup (system-name table)
             (when (stalep table)
               (update table))
             (values (gethash system-name table)))

           (search-function (system-name)
             (let ((tables (get searcher-name indicator)))
               (dolist (table tables)
                 (let* ((result (lookup system-name table))
                        (probed (and result (probe-file result))))
                   (when probed
                     (return probed))))))

           (make-bundled-systems-table ()
             (initialize
              (make-table :data-source (relative "system-index.txt")
                          :init-function #'initialize-bundled-systems-table)))
           (make-local-projects-table ()
             (initialize
              (make-table :data-source (relative "local-projects/")
                          :init-function #'initialize-local-projects-table)))

           (=matching-data-sources (&rest tables)
             (let ((data-sources (mapcar #'data-source tables)))
               (lambda (table)
                 (member (data-source table) data-sources
                         :test #'equalp))))

           (check-for-existing-searcher (searchers)
             (block done
               (dolist (searcher searchers)
                 (when (symbolp searcher)
                   (let ((plist (symbol-plist searcher)))
                     (loop for key in plist by #'cddr
                           when
                           (and (symbolp key) (string= key indicator))
                           do
                           (setf indicator key)
                           (setf searcher-name searcher)
                           (return-from done t)))))))

           (clear-asdf (table)
             (maphash (lambda (system-name pathname)
                        (declare (ignore pathname))
                        (asdf:clear-system system-name))
                      table)))

    (let ((existing (check-for-existing-searcher
                     asdf:*system-definition-search-functions*)))
      (let* ((bundled (make-bundled-systems-table))
             (local (make-local-projects-table))
             (existing-tables (get searcher-name indicator))
             (filter (=matching-data-sources bundled local)))
        (setf (get searcher-name indicator)
              (list* local bundled (delete-if filter existing-tables)))
        (clear-asdf local)
        (clear-asdf bundled))
      (unless existing
        (setf (symbol-function searcher-name) #'search-function)
        (push searcher-name asdf:*system-definition-search-functions*)))
    t))