at master 2.5 kB view raw
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*)) 14 15(in-package org.lispbuilds.nix/nix) 16 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)) 23 24(defun system-master (system) 25 (first (str:split "/" system))) 26 27;;;; Nix generation 28 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))))) 38 39(defun nix-string (object) 40 (format nil "\"~a\"" object)) 41 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)))) 50 51 52(defun nix-symbol (object) 53 (nixify-symbol (format nil "~a" object))) 54 55(defun nix-list (&rest things) 56 (format nil "[ ~{~A~^ ~} ]" (mapcar 'nix-eval things))) 57(defvar *nix-attrs-depth* 0) 58 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)))) 74 75(defun nix-funcall (fun &rest args) 76 (format nil "(~a ~{~a~^ ~})" 77 (nixify-symbol fun) 78 (mapcar 'nix-eval args))) 79 80(defun nix-merge (a b) 81 (format nil "(~a // ~b)" 82 (nix-eval a) 83 (nix-eval b)))