Merge pull request #268619 from tweag/lib-descriptions
[NixPkgs.git] / pkgs / development / lisp-modules / import / nix.lisp
blob4ea9689186299b2f9829271dbd2add4d2cecb152
1 (defpackage org.lispbuilds.nix/nix
2 (:documentation "Utilities for generating Nix code")
3 (:use :cl)
4 (:import-from :str)
5 (:import-from :ppcre)
6 (:import-from :arrow-macros :->>)
7 (:import-from :org.lispbuilds.nix/util :replace-regexes)
8 (:export
9 :nix-eval
10 :nixify-symbol
11 :system-master
12 :make-pname
13 :*nix-attrs-depth*))
15 (in-package org.lispbuilds.nix/nix)
17 ;; Path names are alphanumeric and can include the symbols +-._?= and
18 ;; must not begin with a period.
19 (defun make-pname (string)
20 (replace-regexes '("^[.]" "[^a-zA-Z0-9+-._?=]")
21 '("_" "_")
22 string))
24 (defun system-master (system)
25 (first (str:split "/" system)))
27 ;;;; Nix generation
29 (defun nix-eval (exp)
30 (assert (consp exp))
31 (ecase (car exp)
32 (:string (nix-string (cadr exp)))
33 (:list (apply #'nix-list (rest exp)))
34 (:funcall (apply #'nix-funcall (rest exp)))
35 (:attrs (nix-attrs (cdr exp)))
36 (:merge (apply #'nix-merge (cdr exp)))
37 (:symbol (nix-symbol (cadr exp)))))
39 (defun nix-string (object)
40 (format nil "\"~a\"" object))
42 (defun nixify-symbol (string)
43 (flet ((fix-special-chars (str)
44 (replace-regexes '("[_]" "[+]$" "[+][/]" "[+]" "[.]" "[/]")
45 '("__" "_plus" "_plus/" "_plus_" "_dot_" "_slash_")
46 str)))
47 (if (ppcre:scan "^[0-9]" string)
48 (str:concat "_" (fix-special-chars string))
49 (fix-special-chars string))))
52 (defun nix-symbol (object)
53 (nixify-symbol (format nil "~a" object)))
55 (defun nix-list (&rest things)
56 (format nil "[ ~{~A~^ ~} ]" (mapcar 'nix-eval things)))
57 (defvar *nix-attrs-depth* 0)
59 (defun nix-attrs (keyvals)
60 (when (null keyvals)
61 (return-from nix-attrs "{}"))
62 (let ((*nix-attrs-depth* (1+ *nix-attrs-depth*)))
63 (format
64 nil
65 (->> "{~%*depth*~{~{~A = ~A;~}~^~%*depth*~}~%*depth-1*}"
66 (str:replace-all "*depth*" (str:repeat *nix-attrs-depth* " "))
67 (str:replace-all "*depth-1*" (str:repeat (1- *nix-attrs-depth*) " ")))
68 (mapcar (lambda (keyval)
69 (let ((key (car keyval))
70 (val (cadr keyval)))
71 (list (nix-symbol key)
72 (nix-eval val))))
73 keyvals))))
75 (defun nix-funcall (fun &rest args)
76 (format nil "(~a ~{~a~^ ~})"
77 (nixify-symbol fun)
78 (mapcar 'nix-eval args)))
80 (defun nix-merge (a b)
81 (format nil "(~a // ~b)"
82 (nix-eval a)
83 (nix-eval b)))