-
Notifications
You must be signed in to change notification settings - Fork 2
/
freeze.lisp
97 lines (81 loc) · 2.53 KB
/
freeze.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
;; Freezing the state of the Lisp image.
(defpackage :overlord/freeze
(:use :cl :alexandria :serapeum
:overlord/redo
:overlord/db
:overlord/types
:overlord/message)
(:import-from :overlord/specials
:*suppress-phonies*)
(:import-from :overlord/kernel
:end-meta-kernel)
(:export
:freeze :freeze-policy
:unfreeze
:check-not-frozen
:frozen?
:*before-hard-freeze-hook*))
(in-package :overlord/freeze)
(deftype freeze-policy ()
'(member t nil :hard))
(defparameter *freeze-policy* t)
(declaim (type freeze-policy *freeze-policy*))
(defvar *before-hard-freeze-hook* nil)
(defun freeze-policy ()
"Get or set the current freeze policy.
The freeze policy determines what Overlord does when saving an image.
A freeze policy of `t' (the default) disables module loading, but can
be reversed with `overlord:unfreeze'.
A freeze policy of `nil` does nothing. This should only be used for
local development.
A freeze policy of `:hard' does the same thing as `t', but cannot be
reversed. This should be used when the image is intended to be
distributed."
*freeze-policy*)
(defun (setf freeze-policy) (value)
(setf *freeze-policy* (assure freeze-policy value)))
(defvar *frozen* nil
"Is the build system frozen?")
(defun frozen? ()
*frozen*)
(defparameter *freeze-fmakunbound-hit-list*
'(unfreeze
redo
redo-ifchange
redo-ifcreate
redo-always
redo-stamp
dynamic-require-as))
(defun freeze ()
;; NB. You should be able to load an image and save it again.
(unless (frozen?)
(labels ((freeze ()
(message "Freezing image...")
(redo)
;; The DB can still be reloaded, but is not in memory.
(unload-db)
(setf *frozen* t))
(hard-freeze ()
(freeze)
(message "Hard freeze...")
(fmakunbound 'unfreeze)
(run-hooks '*before-hard-freeze-hook*)
;; The DB will not be reloaded.
(deactivate-db)
(dolist (fn *freeze-fmakunbound-hit-list*)
(fmakunbound fn))))
(let ((*suppress-phonies* t))
(ecase-of freeze-policy *freeze-policy*
((nil))
((t) (freeze))
(:hard (hard-freeze)))))))
(uiop:register-image-dump-hook 'freeze)
(defun unfreeze ()
(setf *frozen* nil))
(defun check-not-frozen ()
(when *frozen*
(restart-case
(error* "The build system is frozen.")
(unfreeze ()
:report "Unfreeze the build system."
(setf *frozen* nil)))))