commit ac9e13b1831b6b9fe5185054c06307129af3463a Spenser Truex <web@spensertruex.com> 2019-11-03 20:03:12 -0800 Rename the project. Add gitattributes.
.gitattributes | 1 + CONFIG-ASDF.lisp | 7 --- CONFIG-QUICKLISP.lisp | 4 -- README.md | 41 --------------- README.org | 66 +++++++++++++++++++++++ TODO.org | 18 +++++++ sbcl-librarian.asd => clapt.asd | 5 +- code/defaults.lisp | 2 +- code/install.lisp | 113 +++++++++++++++++++--------------------- code/save.lisp | 2 +- code/util.lisp | 40 +++++++++++++- package.lisp | 3 +- tests/cp.lisp | 3 ++ 13 files changed, 187 insertions(+), 118 deletions(-)
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b1ea0a5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +tests/* export-ignore diff --git a/CONFIG-ASDF.lisp b/CONFIG-ASDF.lisp deleted file mode 100644 index e411864..0000000 --- a/CONFIG-ASDF.lisp +++ /dev/null @@ -1,7 +0,0 @@ -(in-package #:sbcl-librarian) -(defparameter *asdf-packages* - '( - ;; Example: - ;; utils my-custom-frobber - ) - "User configured Packages for ASDF. Edit this!") diff --git a/CONFIG-QUICKLISP.lisp b/CONFIG-QUICKLISP.lisp deleted file mode 100644 index d23baf8..0000000 --- a/CONFIG-QUICKLISP.lisp +++ /dev/null @@ -1,4 +0,0 @@ -(in-package #:sbcl-librarian) -(defparameter *quicklisp-packages* - '() - "user configured Packages for Quicklisp. Edit this!") diff --git a/README.md b/README.md deleted file mode 100644 index dad35a9..0000000 --- a/README.md +++ /dev/null @@ -1,41 +0,0 @@ -;;;;; -title: Librarian -format: md -date: 2019-11-02 -tags: articles -excerpt: Faster SBCL startup with libraries. -image: /static/librarian.png -;;;;; - -[Official webpage](https://spensertruex.com/librarian) - - - -# sbcl-librarian - -Instant SBCL startup with any number of ASDF libraries by loading the and -dumping a core once. - -## Install - -We need to know which packages are needed, and whether they are from quicklisp. - -1. Modify `CONFIG-ASDF.lisp` and/or `CONFIG-QUICKLISP.lisp` with the desired - packages. Alternatively, set the `sbcl-librarian:*asdf-packages*` and/or - `sbcl-librarian:*quicklisp-packges*` in your `.sbclrc` file. -2. Load the package: `(asdf:load-system :sbcl-librarian)` -3. Install: `(sbcl-librarian:install)`. SBCL will save and die. - -By default sbcl-librarian will try to overwrite your installed core file. This -may require root access on your system; alternatively, try -`(sbcl-librarian:install :core "path-to-your-core")` for a different core. - -## Updating packages - - `(sbcl-librarian:update)`. SBCL will save and die again. - -## License - -GNU GPL v3 - -### _Spenser Truex <web@spensertruex.com>_ diff --git a/README.org b/README.org new file mode 100644 index 0000000..320d425 --- /dev/null +++ b/README.org @@ -0,0 +1,66 @@ +;;;;; +title: Clapt +format: org +date: 2019-11-02 +tags: articles +excerpt: Keep a list of packages efficiently installed. +image: /static/librarian.png +;;;;; +#+EMAIL: web@spensertruex.com +[[https://spensertruex.com/librarian][Official webpage]] +#+OPTIONS: email:t toc:2 +#+VERSION: 0.0.2 + +#+caption: Librarian icon +[[file:https://spensertruex.com/static/librarian-mini.png]] + +#+begin_quote +Clapt, having been clapt into existence, is the apt CL package manager. +#+end_quote + +* Clapt +A package managing /client/. Keep a list of packages efficiently installed. +* Install +We need to know which packages are needed, and whether they are from quicklisp. +1. =(asdf:load-system :clapt)= +2. =(clapt:install)=. SBCL will save and die. +By default clapt will try to overwrite your installed core file. This +may require root access on your system; alternatively, try +=(clapt:install :core "path-to-your-core")= for a different core. +* Adding packages +Call =clapt:add= with the manager and packages. Current managers are =:asdf= and +=:quicklisp=. +* Updating packages +#+begin_src common-lisp :tangle no +(clapt:update) +#+end_src + +* Rationale +Loading a lot of packages from a script is slow, and having to reload the image +manually on every update is too laborious. A simple package manager +* Alternatives +- Just write an init script for your lisp like: +#+begin_src common-lisp :tangle no +(ql:quickload :petalisp) +(qul:quickload :coleslaw) +;;; ... etc. +#+end_src +This is fine if the number of packages is low. Eventually it can start to take +too long. +- Store your core manually. + 1. Write a script like the one above. + 2. =load= it. + 3. Save your core. SBCL has =sb-ext:save-lisp-and-die= for this. + 4. Start your lisp with =sbcl --core "path/to/core"= or similar. +This is essentially what this script does, but lacks backups and needs to be +done every time the lisp is updated. +- clpm is another attempt at the same, and has the benefit of removing itself + from the core. It has dependencies, and is a bit involved to use. + +* Supported Systems +Looking to increase the number of items here: +- SBCL +- Clisp +- CCL +* License +GNU GPL v3 diff --git a/TODO.org b/TODO.org new file mode 100644 index 0000000..7a35b97 --- /dev/null +++ b/TODO.org @@ -0,0 +1,18 @@ +#+TITLE: TODO list +#+AUTHOR: Spenser Truex +#+EMAIL: web@spensertruex.com + +- [0%] Support non-sbcl systems. + - [ ] Those with core image dumps. + - [ ] Those lacking such :: Just use an init script. +- [0%] Error checking and clean continuations + - [0/2] Package failures :: Offer to modify init, or try another source. + - [ ] Non-existent packages. + - [ ] Packages failing to load. + - [0/2] Core image checks :: Revert safely. + - [ ] Core backup failed. + - [ ] Check for dirty core image. + +- [X] Rename. equwal 2019-11-03 +- [ ] Add to quicklisp. +- [ ] Continuous integration tests for dev. Use multiple lisps for support. diff --git a/sbcl-librarian.asd b/clapt.asd similarity index 73% rename from sbcl-librarian.asd rename to clapt.asd index 1f8852a..95f8a53 100644 --- a/sbcl-librarian.asd +++ b/clapt.asd @@ -1,12 +1,11 @@ -(asdf:defsystem #:sbcl-librarian +(asdf:defsystem #:clapt :description "Load up projects and dump the core somewhere." :author "Spenser Truex <web@spensertruex.com>" :license "GNU GPL v3" :version "0.0.2" :serial t :components ((:file "package") - (:file "CONFIG-ASDF") - (:file "CONFIG-QUICKLISP") + (:file "code/util") (:file "code/defaults") (:file "code/save") (:file "code/install"))) diff --git a/code/defaults.lisp b/code/defaults.lisp index 8e0709e..400a9b7 100644 --- a/code/defaults.lisp +++ b/code/defaults.lisp @@ -1,4 +1,4 @@ -(in-package #:sbcl-librarian) +(in-package #:clapt) (defparameter *core-path* sb-ext:*core-pathname* "The default place to store the library core.") diff --git a/code/install.lisp b/code/install.lisp index 42e51a5..a12fe0b 100644 --- a/code/install.lisp +++ b/code/install.lisp @@ -1,44 +1,25 @@ -(in-package #:sbcl-librarian) +(in-package #:clapt) (defparameter *installed* ";;; Leave this line for sbcl-librarian!") -(defun write-array (array stream) - "Write a binary array to the unsigned-byte stream." - (loop for x across array - do (write-byte x stream))) +(eval-when (:compile-toplevel :load-toplevel :execute) + (defun packages-doc (manager) + (format + nil + "~A~A~A" + "User configured Packages for " + (string-downcase (symbol-name manager)) + ". `clapt:add' is a convenience wrapper for it."))) +#+5am (packages-doc :quicklisp) -(defun copy-stream (from to size buffer loc) - "Copy an unsigned-byte stream to another one, somewhat efficiently." - (if (< loc size) - (let ((byte (read-byte from nil nil))) - (if byte - (copy-stream from to size - (progn (setf (aref buffer loc) byte) buffer) - (1+ loc)) - (write-array (subseq buffer 0 loc) to))) - (progn (write-array buffer to) - (copy-stream from to size buffer 0)))) -(defun copy-file (from to &optional (buffer-size 1024)) - (with-open-file (fr from - :element-type 'unsigned-byte - :if-does-not-exist nil) - (if fr - (with-open-file (to to :direction :output - :if-exists nil ;Want it to stay ORIGINAL. - :if-does-not-exist :create - :element-type 'unsigned-byte) - (when to - (copy-stream fr to buffer-size - (make-array buffer-size :element-type 'unsigned-byte) - 0))) - (warn "~%~%The core does not exist, sbcl will have to be started with the --core ~S option to enable the sbcl-librarian libraries core.~%~%" from)))) - -(defun until (stream match) - (let ((line (read-line stream nil nil))) - (when line - (when (not (search match line :test #'string=)) - (until stream match))))) +(defun install (&key (sbclrc *sbclrc-path*) (core *core-path*) + (add '(:quicklisp :asdf))) + "Install clapt." + (when (not (installedp sbclrc)) + (write-to-init-file sbclrc core add)) + (backup-core core (merge-pathnames #P".core.bak" sbclrc)) + (update core)) (defun installedp (sbclrc-path) "Determine if sbcl-librarian is installed in the .sbclrc." @@ -47,28 +28,44 @@ :if-does-not-exist nil) (when sbclrc (until sbclrc *installed*)))) -(defun write-to-init-file (sbclrc-path core-path) - (with-open-file (sbclrc sbclrc-path - :direction :output - :if-exists :append - :if-does-not-exist :create) - (when (not (installedp sbclrc-path)) - (format sbclrc "~%~A~%" *installed*) - (prin1 `(progn - (when (probe-file ,core-path)) - (pushnew :sblibr *features*)) - sbclrc) - (format sbclrc "~%~A~%" "#-sblibr") - (prin1 '(asdf:load-system :sbcl-librarian) sbclrc) - (format sbclrc "~%~A~%" "#-sblibr") - (prin1 '(sbcl-librarian:update) sbclrc) - (format sbclrc "~%")))) - (defun backup-core (core backup) + "Save original core image." (copy-file core backup (* 1024 1024))) -(defun install (&key (sbclrc *sbclrc-path*) (core *core-path*)) - (when (not (installedp sbclrc)) - (write-to-init-file sbclrc core)) - (backup-core core (merge-pathnames #P".core.bak" sbclrc)) - (update core)) +(defun write-to-init-file (sbclrc core systema) + "Common Lisp code in the init file for cl-apt to install itself if not +installed. Provides persistence even when a new version is built." + (with-open-file (s sbclrc + :direction :output + :if-exists :append + :if-does-not-exist :create) + (when (not (installedp sbclrc)) + (parameterize s systema) + (self-install s core)))) + +(defun package-parameter (packages manager) + `(defvar ,(intern (symbol-name manager) + (find-package :keyword)) + ',packages + ,(packages-doc manager))) +#+5am (package-parameter '(petalisp) :quicklisp) + +(defun self-install (sbclrc core) + (declare (stream sbclrc)) + (declare (pathname core)) + (format sbclrc "~%~A~%" *installed*) + (prin1 `(progn + (when (probe-file ,core)) + (pushnew :clapt *features*)) + sbclrc) + (format sbclrc "~%~A~%" "#-clapt") + (prin1 '(asdf:load-system :clapt) sbclrc) + (format sbclrc "~%~A~%" "#-clapt") + (prin1 '(clapt:update) sbclrc) + (format sbclrc "~%")) + +(defun parameterize (sbclrc systema) + (declare (stream sbclrc)) + (mapcar #'(lambda (code) (prin1 code sbclrc)) + (loop for s in systema + collect (package-parameter systema s)))) diff --git a/code/save.lisp b/code/save.lisp index 7f405cf..628a9f4 100644 --- a/code/save.lisp +++ b/code/save.lisp @@ -1,4 +1,4 @@ -(in-package #:sbcl-librarian) +(in-package #:clapt) (defun update (&optional (core *core-path*)) (load-configs) diff --git a/code/util.lisp b/code/util.lisp index 9891772..65e0783 100644 --- a/code/util.lisp +++ b/code/util.lisp @@ -1 +1,39 @@ -(in-package #:sbcl-librarian) +(in-package #:clapt) + +(defun write-array (array stream) + "Write a binary array to the unsigned-byte stream." + (loop for x across array + do (write-byte x stream))) + +(defun copy-stream (from to size buffer loc) + "Copy an unsigned-byte stream to another one, somewhat efficiently." + (if (< loc size) + (let ((byte (read-byte from nil nil))) + (if byte + (copy-stream from to size + (progn (setf (aref buffer loc) byte) buffer) + (1+ loc)) + (write-array (subseq buffer 0 loc) to))) + (progn (write-array buffer to) + (copy-stream from to size buffer 0)))) + +(defun copy-file (from to &optional (buffer-size 1024)) + (with-open-file (fr from + :element-type 'unsigned-byte + :if-does-not-exist nil) + (if fr + (with-open-file (to to :direction :output + :if-exists nil ;Want it to stay ORIGINAL. + :if-does-not-exist :create + :element-type 'unsigned-byte) + (when to + (copy-stream fr to buffer-size + (make-array buffer-size :element-type 'unsigned-byte) + 0))) + (warn "~%~%The core does not exist, sbcl will have to be started with the --core ~S option to enable the sbcl-librarian libraries core.~%~%" from)))) + +(defun until (stream match) + (let ((line (read-line stream nil nil))) + (when line + (when (not (search match line :test #'string=)) + (until stream match))))) diff --git a/package.lisp b/package.lisp index 852edf8..df0aae4 100644 --- a/package.lisp +++ b/package.lisp @@ -1,4 +1,3 @@ -(defpackage #:sbcl-librarian +(defpackage #:clapt (:use #:cl) - (:nicknames #:sblibr) (:export #:update #:install)) diff --git a/tests/cp.lisp b/tests/cp.lisp new file mode 100644 index 0000000..3761810 --- /dev/null +++ b/tests/cp.lisp @@ -0,0 +1,3 @@ +(in-package #:clapt) + +()