Coverage report: /home/ellis/comp/core/app/packy/pkgbuild.lisp

KindCoveredAll%
expression0120 0.0
branch00nil
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;; lib/skel/comp/pkgbuild.lisp --- Archlinux PKGBUILDs
2
 
3
 ;; Readers and Writers for PKBUILD files
4
 
5
 ;;; Commentary:
6
 
7
 ;; wiki: https://wiki.archlinux.org/title/PKGBUILD
8
 ;; man: https://man.archlinux.org/man/PKGBUILD.5
9
 ;; ref: https://wiki.archlinux.org/title/Creating_packages
10
 
11
 ;;; Code:
12
 (in-package :packy/pkgbuild)
13
 
14
 (defparameter *pkgbuild-filename* "PKGBUILD")
15
 
16
 
17
 (defun parse-pkgbuild-value (l s)
18
   (destructuring-bind (n1 n2 b1 b2) l
19
     (cons (keywordicate (string-upcase (subseq s n1 n2)))
20
           (trim (subseq s b1 b2)))))
21
 
22
 (defun parse-pkgbuild (&optional (file *pkgbuild-filename*))
23
   "Parse FILE as a pkgbuild script using tree-sitter. Returns multiple
24
 values: (VARS FUNCTIONS SRC)"
25
   (let* ((path (probe-file file))
26
          (str (read-file path))
27
          (tree (syn/ts:parse-file :bash path :consume t :produce-cst nil))
28
          vars fns)
29
     (mapc (lambda (x) 
30
             (case (car x)
31
               (:function-definition
32
                (when-let ((body (cadar (member :body (caddr x) :key (lambda (x) (caar x)))))
33
                           (name (cadar (member :name (caddr x) :key (lambda (x) (caar x))))))
34
                  (push (nconc name body) fns)))
35
               (:variable-assignment
36
                (when-let ((name (cadar (member :name (caddr x) :key (lambda (x) (caar x)))))
37
                           (val (cadar (member :value (caddr x) :key (lambda (x) (caar x))))))
38
                  (push (nconc name val) vars)))))
39
           (caddr tree))
40
     (values
41
      (flatten (mapcar (lambda (x) (parse-pkgbuild-value x str)) vars))
42
      (flatten (mapcar (lambda (x) (parse-pkgbuild-value x str)) fns)))))
43
 
44
 (defmethod deserialize ((from pathname) (format (eql :pkgbuild)) &key)
45
   (multiple-value-bind (config fns) (parse-pkgbuild from)
46
     (apply 'make-instance 'pkgbuild :functions fns config)))
47
 
48
 (defclass pkgbuild ()
49
   ((pkgname :initarg :pkgname)
50
    (pkgver :initarg :pkgver)
51
    (pkgrel :initarg :pkgrel)
52
    (pkgdesc :initarg :pkgdesc)
53
    (arch :initarg :arch)
54
    (desc :initarg :desc)
55
    (url :initarg :url)
56
    (license :initarg :license)
57
    (groups :initarg :groups)
58
    (provides :initarg :provides)
59
    (options :initarg :options)
60
    (conflicts :initarg :conflicts)
61
    (replaces :initarg :replaces)
62
    (backup :initarg :backup)
63
    (depends :initarg :depends)
64
    (makedepends :initarg :makedepends)
65
    (optdepends :initarg :optdepends)
66
    (checkdepends :initarg :checkdepends)
67
    (sha256sums :initarg :sha256sums)
68
    (noextract :initarg :noextract)
69
    (source :initarg :source)
70
    (install :initarg :install)
71
    (functions :initarg :functions)))
72
 
73
 (defmethod serde ((self pkgbuild) (path pathname))
74
   "Serialize a pkgbuild SELF to PATH."
75
   (let* ((vars (remove 'functions (mapcar 'slot-definition-name (class-slots (find-class 'pkgbuild)))))
76
          (vals (slot-values self vars))
77
          (fns (slot-value self 'functions)))
78
     (with-open-file (f path :direction :output)
79
       (loop for n in vars
80
             for v in vals
81
             when v
82
             do (format f "~A=~A~%" (string-downcase n) v))
83
       (doplist (k v) fns (format f "~A() ~A~%" (string-downcase k) v)))))
84
 
85
 ;;; Install scripts
86
 ;; pre_install, post_install
87
 ;; pre_upgrade, post_upgrade
88
 ;; pre_remove, post_remove
89
 
90
 ;;; Meta-packages