source: trunk/abcl/contrib/abcl-build/build/util.lisp

Last change on this file was 15535, checked in by Mark Evenson, 3 years ago

abcl-build: implement COPY-DIRECTORIES-RECURSIVELY utility

File size: 3.9 KB
Line 
1;;;; TODO: move to a utility package
2(in-package :abcl/build)
3
4;;; TODO remove
5(defun localize-executable-name (name)
6  (let* ((p (if (pathnamep name)
7                name
8                (pathname name)))
9         (type (pathname-type p)))
10    (make-pathname :defaults p
11                   :type 
12                   (if (uiop:os-windows-p)
13                       (when (null type)
14                         "exe")
15                       type))))
16
17(defun possible-executable-names (name
18          &key (suffixes '("exe" "cmd" "bat") suffixes-p))
19  (let* ((p (if (pathnamep name)
20                name
21                (pathname name)))
22         (type (pathname-type p)))
23    (declare (ignore type))
24    (unless (or (uiop:os-windows-p) suffixes-p)
25      (return-from possible-executable-names
26        (listify name)))
27    (loop
28       :for suffix :in suffixes
29       :with result = (list p)
30       :doing (push (make-pathname :defaults p :type suffix)
31        result)
32       :finally (return (nreverse result)))))
33       
34(defun introspect-path-for (executable)
35  (let ((which-command (if (uiop:os-windows-p)
36                           "where"
37                           "which")))
38    (when (ignore-errors
39            (uiop:run-program (list which-command which-command) :output :string))
40      (dolist (p (possible-executable-names executable))
41  (let ((raw-result 
42         (ignore-errors (uiop:run-program
43             (list which-command
44             (namestring p))
45             :output :string))))
46    (when raw-result
47      (let ((result (first (split-string raw-result #\Newline))))
48        (return-from introspect-path-for
49    (values
50     result
51     (pathname result))))))))))
52
53(defun probe-for-executable (directory executable)
54  (dolist (executable (possible-executable-names executable))
55    (let ((pathname
56     (probe-file
57      (merge-pathnames executable directory))))
58      (when pathname
59  (return-from probe-for-executable
60    pathname)))))
61 
62(defun split-string (string split-char)
63  (loop :for i = 0 :then (1+ j)
64     :as j = (position split-char string :test #'string-equal :start i)
65     :collect (subseq string i j)
66     :while j))
67
68(defun stringify (thing)
69  (cond
70    ((pathnamep thing)
71     (namestring thing))
72    ((stringp thing)
73     thing)
74    (t
75     (error "Don't know how stringify ~a." thing))))
76
77(defun listify (thing)
78  (if (consp thing)
79      thing
80      (list thing)))
81
82(defun some-directory-containing (executable)
83  ;; search path
84  (let ((in-path (introspect-path-for executable)))
85    (when in-path
86      (return-from some-directory-containing
87                   in-path))
88    (dolist (d (if (uiop:os-windows-p)
89                   '(#p"c:/Program Files/") ;; TODO localize me!
90                   '(#p"/usr/local/bin/" #p"/opt/local/bin/" #p"/usr/bin/")))
91      (let* ((e (localize-executable-name
92                 (merge-pathnames executable d)))
93             (p (probe-file e)))
94        (when p
95          (return-from some-directory-containing p))))))
96
97(defun copy-directory-recursively (from to)
98  (flet ((normalize-to-directory (p)
99           (when (or (not (pathnamep p))
100                     (not (and (null (pathname-name p))
101                               (null (pathname-type p)))))
102             (setf p (make-pathname :defaults p
103                                    :name nil :type nil)))
104           p))
105    (normalize-to-directory from)
106    (normalize-to-directory to)
107    (let ((wildcard (merge-pathnames "**/*" from)))
108      (loop :for source :in (directory wildcard)
109            :for relative = (enough-namestring source from)
110            :for destination = (merge-pathnames relative to)
111            :doing
112               (progn 
113                 (ensure-directories-exist destination)
114                 (when (or (pathname-name destination)
115                           (pathname-type destination))
116                   (uiop:copy-file source destination)))))))
117
118
119                                               
120
121                                               
122   
123       
124       
Note: See TracBrowser for help on using the repository browser.