-
Notifications
You must be signed in to change notification settings - Fork 0
/
loop.lisp
40 lines (38 loc) · 1.36 KB
/
loop.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
(defpackage :kiln/scripts/loop
(:documentation "Write shell loops with the loop macro")
(:use :cl)
(:import-from :cmd)
(:import-from :serapeum :string^= :drop :string+ :null-if-empty)
(:shadow :t)
(:export :main))
(in-package :kiln/scripts/loop)
(defun parse-loop (args)
(let* ((shell
(or (uiop:getenvp "SHELL")
"/bin/sh"))
(vars))
(flet ((shell (arg)
`(cmd:cmd
"env"
,@(mapcar (lambda (var)
`(list (string+
',(string-downcase var)
"="
,var)))
vars)
',(list shell) "-c" ',(list (drop 1 arg)))))
(cons 'loop
(loop for arg in args
collecting
(cond ((string^= "!" arg)
(shell arg))
((string^= "@" arg)
(let* ((var-name (string-upcase (drop 1 arg)))
(var (intern var-name)))
(push var vars)
var))
((every #'digit-char-p arg)
(parse-integer arg))
(cl:t (intern (string-upcase arg)))))))))
(defun main (args)
(eval (parse-loop args)))