1 (defpackage org.lispbuilds.nix
/database
/sqlite
5 (:import-from
:alexandria
:read-file-into-string
)
6 (:import-from
:alexandria-2
:line-up-first
)
7 (:import-from
:arrow-macros
:-
>>)
9 :org.lispbuilds.nix
/util
12 :org.lispbuilds.nix
/nix
19 :org.lispbuilds.nix
/api
20 :database-
>nix-expression
)
21 (:export
:sqlite-database
:init-db
)
23 (:hydra
:org.lispbuilds.nix
/hydra
)
24 (:json
:com.inuoe.jzon
)))
26 (in-package org.lispbuilds.nix
/database
/sqlite
)
28 (defclass sqlite-database
()
31 :initform
(error "url required"))
32 (init-file :initarg
:init-file
34 :initform
(error "init file required"))))
36 (defun init-db (db init-file
)
37 (let ((statements (->> (read-file-into-string init-file
)
38 (replace-regexes '(".*--.*") '(""))
39 (substitute #\Space
#\Newline
)
40 (str:collapse-whitespaces
)
43 (remove-if #'str
:emptyp
))))
44 (sqlite:with-transaction db
45 (dolist (s statements
)
46 (sqlite:execute-non-query db s
)))))
51 (defparameter prelude
"
52 # This file was auto-generated by nix-quicklisp.lisp
54 { runCommand, pkgs, lib, fetchzip, build-asdf-system, ... }:
58 inherit (builtins) getAttr;
60 # Ensures that every non-slashy `system` exists in a unique .asd file.
61 # (Think cl-async-base being declared in cl-async.asd upstream)
63 # This is required because we're building and loading a system called
64 # `system`, not `asd`, so otherwise `system` would not be loadable
65 # without building and loading `asd` first.
67 createAsd = { url, sha256, asd, system }:
69 src = fetchzip { inherit url sha256; };
73 else runCommand \"source\" {} ''
76 find $out -name \"${asd}.asd\" | while read f; do mv -fv $f $(dirname $f)/${system}.asd || true; done
78 in lib.makeScope pkgs.newScope (self: {")
80 ;; Random compilation errors
81 (defparameter +broken-packages
+
83 ;; no dispatch function defined for #\t
87 ;; Tries to write in $HOME
89 ;; Upstream bad packaging, multiple systems in clml.blas.asd
91 ;; Fails on SBCL due to heap exhaustion
93 ;; Missing dependency on c2ffi cffi extension
95 ;; These require libRmath.so, but I don't know where to get it from
100 (defmethod database->nix-expression
((database sqlite-database
) outfile
)
101 (sqlite:with-open-database
(db (database-url database
))
102 (with-open-file (f outfile
104 :if-exists
:supersede
)
106 ;; Fix known problematic packages before dumping the nix file.
107 (sqlite:execute-non-query db
108 "create temp table fixed_systems as select * from system_view")
110 (sqlite:execute-non-query db
111 "alter table fixed_systems add column systems")
113 (sqlite:execute-non-query db
114 "update fixed_systems set systems = json_array(name)")
116 (sqlite:execute-non-query db
117 "alter table fixed_systems add column asds")
119 (sqlite:execute-non-query db
120 "update fixed_systems set asds = json_array(name)")
122 (sqlite:execute-non-query db
123 "delete from fixed_systems where name in ('asdf', 'uiop')")
125 (sqlite:execute-non-query db
126 "delete from fixed_systems where instr(name, '/')")
130 (dolist (p (sqlite:execute-to-list db
"select * from fixed_systems"))
131 (destructuring-bind (name version asd url sha256 deps systems asds
) p
133 (let ((*nix-attrs-depth
* 1))
137 (nix-eval `(:symbol
,name
))
142 ("pname" (:string
,(make-pname name
)))
143 ("version" (:string
,version
))
145 ,@(mapcar (lambda (asd)
146 `(:string
,(system-master asd
)))
147 (coerce (json:parse asds
) 'list
))))
151 ("url" (:string
,url
))
152 ("sha256" (:string
,sha256
))
153 ("system" (:string
,(system-master name
)))
154 ("asd" (:string
,asd
)))))
156 ,@(mapcar (lambda (sys)
158 (coerce (json:parse systems
) 'list
))))
160 ,@(mapcar (lambda (dep)
163 (:string
,(nixify-symbol dep
))
166 (str:split-omit-nulls
#\
, deps
)
167 (set-difference '("asdf" "uiop") :test
#'string
=)
170 ,@(when (or (find #\
/ name
)
171 (find name
+broken-packages
+ :test
#'string
=))
172 '(("broken" (:symbol
"true"))))
173 ,@(unless (find name hydra
:+allowlist
+ :test
#'string
=)
174 '(("hydraPlatforms" (:list
)))))))))))))
175 (format f
"~%})~%"))))