forked from clasp-developers/clasp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
koga
executable file
·127 lines (116 loc) · 5.19 KB
/
koga
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
#!/usr/bin/env -S sbcl --script
#+sbcl
(progn
(in-package "SB-IMPL")
(sb-ext:without-package-locks
(let ((old (fdefinition 'sb-impl::make-fd-stream)))
(defun sb-impl::make-fd-stream (fd &rest rest)
(apply old fd :auto-close nil rest)))))
(require :asdf)
(defparameter *git* nil)
(defun check-repo (&key directory repository &allow-other-keys)
(format t "~:[Did not find~;Found~] ~A clone in ~A, assuming everything is okay.~%"
(probe-file directory) repository directory))
(defun sync-repo (help &key directory repository branch commit &allow-other-keys
&aux (exists (probe-file directory)))
(unless (and help exists)
(cond (exists
(format t "Fetching ~A~%" repository)
(uiop:run-program (list *git* "fetch" "--quiet")
:output :interactive
:error-output :output
:directory directory))
(t
(format t "Cloning ~A~%" repository)
(uiop:run-program (list *git* "clone" repository (namestring directory))
:output :interactive
:error-output :output)))
(when (or commit branch)
(format t "Checking out ~A from ~A~%" (or commit branch) repository)
(uiop:run-program (list *git* "checkout" "--quiet" (or commit branch))
:output :interactive
:error-output :output
:directory directory))
(when (and branch (not commit))
(format t "Fast forwarding to origin/~A from ~A~%" branch repository)
(uiop:run-program (list *git* "merge" "--ff-only" (format nil "origin/~A" branch))
:output :interactive
:error-output :output
:directory directory))))
(defun split-keywords (value)
(if (stringp value)
(loop with end = (length value)
for left = 0 then (1+ right)
for right = (or (position #\, value :start left) end)
collect (intern (string-upcase (subseq value left right)) "KEYWORD")
until (>= right end))
value))
(defparameter +option-parsers+
(list :extensions #'split-keywords
:skip-sync #'split-keywords))
(defun parse-string-option (arg start eq-pos)
(let ((name (intern (string-upcase (subseq arg start eq-pos))
"KEYWORD")))
(list name (funcall (getf +option-parsers+
name
#'identity)
(subseq arg (1+ eq-pos))))))
(defun parse-boolean-option (arg start)
(if (and (>= (length arg) (+ 3 start))
(char= #\n (char arg start))
(char= #\o (char arg (1+ start)))
(char= #\- (char arg (+ 2 start))))
(list (intern (string-upcase (subseq arg (+ 3 start))) "KEYWORD")
nil)
(list (intern (string-upcase (subseq arg start)) "KEYWORD")
t)))
(defun parse-command-line-arguments ()
(loop for arg in (uiop:command-line-arguments)
for start = (position-if (lambda (x)
(not (char= #\- x)))
arg)
for eq-pos = (position #\= arg)
when eq-pos
append (parse-string-option arg start eq-pos)
else
append (parse-boolean-option arg start)))
(let* ((initargs (nconc (parse-command-line-arguments)
(ignore-errors (uiop:read-file-form #P"config.sexp"))
(ignore-errors (uiop:read-file-form #P"version.sexp"))))
(*git* (getf initargs :git "git"))
(build (getf initargs :build-path "build/"))
(extensions (getf initargs :extensions))
(skip-sync (getf initargs :skip-sync))
(help (getf initargs :help)))
;; Get all the external dependencies
(unless help
(format t "Synchronizing external repositories~%~%"))
(loop for source in (uiop:read-file-form #P"repos.sexp")
for name = (getf source :name)
for extension = (getf source :extension)
if (or (eq t skip-sync)
(member name skip-sync))
do (apply #'check-repo source)
else if (or (not extension)
(member extension extensions))
do (apply #'sync-repo help source)
unless help
do (terpri))
(when (and (not help)
(getf initargs :clean))
(format t "Cleaning up previous build~%~%")
(uiop:delete-directory-tree (truename build)
:validate t
:if-does-not-exist :ignore))
;; Do the absolute minimum to inform ASDF about the location of systems
;; in order to find the clasp root and the desired build directory.
(asdf:initialize-source-registry
`(:source-registry (:tree ,(uiop:getcwd))
:inherit-configuration))
(asdf:initialize-output-translations
`(:output-translations (t (,(merge-pathnames (merge-pathnames #P"host-fasl/" build)
(uiop:getcwd))
:implementation))
:inherit-configuration))
(asdf:load-system :koga)
(apply #'uiop:symbol-call "KOGA" (if help "HELP" "SETUP") initargs))