about summary refs log tree commit diff
path: root/pkgs/development/lisp-modules-obsolete/quicklisp-to-nix/system-info.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/lisp-modules-obsolete/quicklisp-to-nix/system-info.lisp')
-rw-r--r--pkgs/development/lisp-modules-obsolete/quicklisp-to-nix/system-info.lisp493
1 files changed, 0 insertions, 493 deletions
diff --git a/pkgs/development/lisp-modules-obsolete/quicklisp-to-nix/system-info.lisp b/pkgs/development/lisp-modules-obsolete/quicklisp-to-nix/system-info.lisp
deleted file mode 100644
index af8d450272c05..0000000000000
--- a/pkgs/development/lisp-modules-obsolete/quicklisp-to-nix/system-info.lisp
+++ /dev/null
@@ -1,493 +0,0 @@
-(unless (find-package :ql-to-nix-util)
-  (load "util.lisp"))
-(unless (find-package :ql-to-nix-quicklisp-bootstrap)
-  (load "quicklisp-bootstrap.lisp"))
-(defpackage :ql-to-nix-system-info
-  (:use :common-lisp :ql-to-nix-quicklisp-bootstrap :ql-to-nix-util)
-  (:export #:dump-image))
-(in-package :ql-to-nix-system-info)
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  (defparameter *implementation-systems*
-    (append
-      #+sbcl(list :sb-posix :sb-bsd-sockets :sb-rotate-byte :sb-cltl2
-                  :sb-introspect :sb-rt :sb-concurrency)))
-  (mapcar (function require) *implementation-systems*))
-
-(declaim (optimize (debug 3) (speed 0) (space 0) (compilation-speed 0) (safety 3)))
-
-;; This file cannot have any dependencies beyond quicklisp and asdf.
-;; Otherwise, we'll miss some dependencies!
-
-;; (Implementation-provided dependencies are special, though)
-
-;; We can't load quicklisp until runtime (at which point we'll create
-;; an isolated quicklisp installation).  These wrapper functions are
-;; nicer than funcalling intern'd symbols every time we want to talk
-;; to quicklisp.
-(wrap :ql apply-load-strategy)
-(wrap :ql compute-load-strategy)
-(wrap :ql show-load-strategy)
-(wrap :ql quicklisp-systems)
-(wrap :ql ensure-installed)
-(wrap :ql quicklisp-releases)
-(wrap :ql-dist archive-md5)
-(wrap :ql-dist archive-url)
-(wrap :ql-dist ensure-local-archive-file)
-(wrap :ql-dist find-system)
-(wrap :ql-dist local-archive-file)
-(wrap :ql-dist name)
-(wrap :ql-dist provided-systems)
-(wrap :ql-dist release)
-(wrap :ql-dist short-description)
-(wrap :ql-dist system-file-name)
-(wrap :ql-impl-util call-with-quiet-compilation)
-
-(defvar *version* (uiop:getenv "version")
-  "The version number of this program")
-
-(defvar *main-system* nil
-  "The name of the system we're trying to extract info from.")
-
-(defvar *found-parasites* (make-hash-table :test #'equalp)
-  "Names of systems which have been identified as parasites.
-
-A system is parasitic if its name doesn't match the name of the file
-it is defined in.  So, for example, if foo and foo-bar are both
-defined in a file named foo.asd, foo would be the host system and
-foo-bar would be a parasitic system.
-
-Parasitic systems are not generally loaded without loading the host
-system first.
-
-Keys are system names.  Values are unspecified.")
-
-(defvar *found-dependencies* (make-hash-table :test #'equalp)
-  "Hash table containing the set of dependencies discovered while installing a system.
-
-Keys are system names.  Values are unspecified.")
-
-(defun decode-asdf-dependency (name)
-  "Translates an asdf system dependency description into a system name.
-
-For example, translates (:version :foo \"1.0\") into \"foo\"."
-  (etypecase name
-    (symbol
-     (setf name (symbol-name name)))
-    (string)
-    (cons
-     (ecase (first name)
-       (:version
-        (warn "Discarding version information ~A" name)
-        ;; There's nothing we can do about this.  If the version we
-        ;; have around is good enough, then we're golden.  If it isn't
-        ;; good enough, then we'll error out and let a human figure it
-        ;; out.
-        (setf name (second name))
-        (return-from decode-asdf-dependency
-          (decode-asdf-dependency name)))
-
-       (:feature
-        (if (find (second name) *features*)
-            (return-from decode-asdf-dependency
-              (decode-asdf-dependency (third name)))
-            (progn
-              (warn "Dropping dependency due to missing feature: ~A" name)
-              (return-from decode-asdf-dependency nil))))
-
-       (:require
-        ;; This probably isn't a dependency we can satisfy using
-        ;; quicklisp, but we might as well try anyway.
-        (return-from decode-asdf-dependency
-          (decode-asdf-dependency (second name)))))))
-  (string-downcase name))
-
-(defun found-new-parasite (system-name)
-  "Record that the given system has been identified as a parasite."
-  (setf system-name (decode-asdf-dependency system-name))
-  (setf (gethash system-name *found-parasites*) t)
-  (when (nth-value 1 (gethash system-name *found-dependencies*))
-    (error "Found dependency on parasite")))
-
-(defun known-parasite-p (system-name)
-  "Have we previously identified this system as a parasite?"
-  (nth-value 1 (gethash system-name *found-parasites*)))
-
-(defun found-parasites ()
-  "Return a vector containing all identified parasites."
-  (let ((systems (make-array (hash-table-size *found-parasites*) :fill-pointer 0)))
-    (loop :for system :being :the :hash-keys :of *found-parasites* :do
-       (vector-push system systems))
-    systems))
-
-(defvar *track-dependencies* nil
-  "When this variable is nil, found-new-dependency will not record
-depdendencies.")
-
-(defun parasitic-relationship-p (potential-host potential-parasite)
-  "Returns t if potential-host and potential-parasite have a parasitic relationship.
-
-See `*found-parasites*'."
-  (let ((host-ql-system (find-system potential-host))
-        (parasite-ql-system (find-system potential-parasite)))
-    (and host-ql-system parasite-ql-system
-         (not (equal (name host-ql-system)
-                     (name parasite-ql-system)))
-         (equal (system-file-name host-ql-system)
-                (system-file-name parasite-ql-system)))))
-
-(defun found-new-dependency (name)
-  "Record that the given system has been identified as a dependency.
-
-The named system may not be recorded as a dependency.  It may be left
-out for any number of reasons.  For example, if `*track-dependencies*'
-is nil then this function does nothing.  If the named system isn't a
-quicklisp system, this function does nothing."
-  (setf name (decode-asdf-dependency name))
-  (unless name
-    (return-from found-new-dependency))
-  (unless *track-dependencies*
-    (return-from found-new-dependency))
-  (when (known-parasite-p name)
-    (return-from found-new-dependency))
-  (when (parasitic-relationship-p *main-system* name)
-    (found-new-parasite name)
-    (return-from found-new-dependency))
-  (unless (find-system name)
-    (return-from found-new-dependency))
-  (setf (gethash name *found-dependencies*) t))
-
-(defun forget-dependency (name)
-  "Whoops.  Did I say that was a dependency?  My bad.
-
-Be very careful using this function!  You can remove a system from the
-dependency list, but you can't remove other effects associated with
-this system.  For example, transitive dependencies might still be in
-the dependency list."
-  (setf name (decode-asdf-dependency name))
-  (remhash name *found-dependencies*))
-
-(defun found-dependencies ()
-  "Return a vector containing all identified dependencies."
-  (let ((systems (make-array (hash-table-size *found-dependencies*) :fill-pointer 0)))
-    (loop :for system :being :the :hash-keys :of *found-dependencies* :do
-       (vector-push system systems))
-    systems))
-
-(defun host-system (system-name)
-  "If the given system is a parasite, return the name of the system that is its host.
-
-See `*found-parasites*'."
-  (let* ((system (find-system system-name))
-         (host-file (system-file-name system)))
-    (unless (equalp host-file system-name)
-      host-file)))
-
-(defun get-loaded (system)
-  "Try to load the named system using quicklisp and record any
-dependencies quicklisp is aware of.
-
-Unlike `our-quickload', this function doesn't attempt to install
-missing dependencies."
-  ;; Let's get this party started!
-  (let* ((strategy (compute-load-strategy system))
-         (ql-systems (quicklisp-systems strategy)))
-    (dolist (dep ql-systems)
-      (found-new-dependency (name dep)))
-    (show-load-strategy strategy)
-    (labels
-        ((make-go ()
-           (apply-load-strategy strategy)))
-      (call-with-quiet-compilation #'make-go)
-      (let ((asdf-system (asdf:find-system system)))
-        ;; If ASDF says that it needed a system, then we should
-        ;; probably track that.
-        (dolist (asdf-dep (asdf:component-sideway-dependencies asdf-system))
-          (found-new-dependency asdf-dep))
-        (dolist (asdf-dep (asdf:system-defsystem-depends-on asdf-system))
-          (found-new-dependency asdf-dep))))))
-
-(defun our-quickload (system)
-  "Attempt to install a package like quicklisp would, but record any
-dependencies that are detected during the install."
-  (setf system (string-downcase system))
-  ;; Load it quickly, but do it OUR way.  Turns out our way is very
-  ;; similar to the quicklisp way...
-  (let ((already-tried (make-hash-table :test #'equalp))) ;; Case insensitive
-    (tagbody
-     retry
-       (handler-case
-           (get-loaded system)
-         (asdf/find-component:missing-dependency (e)
-           (let ((required-by (asdf/find-component:missing-required-by e))
-                 (missing (asdf/find-component:missing-requires e)))
-             (unless (typep required-by 'asdf:system)
-               (error e))
-             (when (gethash missing already-tried)
-               (error "Dependency loop? ~A" missing))
-             (setf (gethash missing already-tried) t)
-             (let ((parasitic-p (parasitic-relationship-p *main-system* missing)))
-               (if parasitic-p
-                   (found-new-parasite missing)
-                   (found-new-dependency missing))
-               ;; We always want to track the dependencies of systems
-               ;; that share an asd file with the main system.  The
-               ;; whole asd file should be loadable.  Otherwise, we
-               ;; don't want to include transitive dependencies.
-               (let ((*track-dependencies* parasitic-p))
-                 (our-quickload missing)))
-             (format t "Attempting to load ~A again~%" system)
-             (go retry)))))))
-
-(defvar *blacklisted-parasites*
-  #("hu.dwim.stefil/documentation" ;; This system depends on :hu.dwim.stefil.test, but it should depend on hu.dwim.stefil/test
-    "named-readtables/doc" ;; Dependency cycle between named-readtabes and mgl-pax
-    "symbol-munger-test" ;; Dependency cycle between lisp-unit2 and symbol-munger
-    "cl-postgres-simple-date-tests" ;; Dependency cycle between cl-postgres and simple-date
-    "cl-containers/with-variates" ;; Symbol conflict between cl-variates:next-element, metabang.utilities:next-element
-    "serapeum/docs" ;; Weird issue with FUN-INFO redefinition
-    "spinneret/cl-markdown" ;; Weird issue with FUN-INFO redefinition
-    "spinneret/ps" ;; Weird issue with FUN-INFO redefinition
-    "spinneret/tests") ;; Weird issue with FUN-INFO redefinition
-  "A vector of systems that shouldn't be loaded by `quickload-parasitic-systems'.
-
-These systems are known to be troublemakers.  In some sense, all
-parasites are troublemakers (you shouldn't define parasitic systems!).
-However, these systems prevent us from generating nix packages and are
-thus doubly evil.")
-
-(defvar *blacklisted-parasites-table*
-  (let ((ht (make-hash-table :test #'equalp)))
-    (loop :for system :across *blacklisted-parasites* :do
-       (setf (gethash system ht) t))
-    ht)
-  "A hash table where each entry in `*blacklisted-parasites*' is an
-entry in the table.")
-
-(defun blacklisted-parasite-p (system-name)
-  "Returns non-nil if the named system is blacklisted"
-  (nth-value 1 (gethash system-name *blacklisted-parasites-table*)))
-
-(defun quickload-parasitic-systems (system)
-  "Attempt to load all the systems defined in the same asd as the named system.
-
-Blacklisted systems are skipped.  Dependencies of the identified
-parasitic systems will be tracked."
-  (let* ((asdf-system (asdf:find-system system))
-         (source-file (asdf:system-source-file asdf-system)))
-    (cond
-      (source-file
-       (loop :for system-name :being :the :hash-keys :of asdf/find-system::*registered-systems* :do
-             ; for an unclear reason, a literal 0 which is not a key in the hash table gets observed
-          (when (and (gethash system-name asdf/find-system::*registered-systems*)
-                     (parasitic-relationship-p system system-name)
-                     (not (blacklisted-parasite-p system-name)))
-            (found-new-parasite system-name)
-            (let ((*track-dependencies* t))
-              (our-quickload system-name)))))
-      (t
-       (unless (or (equal "uiop" system)
-                   (equal "asdf" system))
-         (warn "No source file for system ~A.  Can't identify parasites." system))))))
-
-(defun determine-dependencies (system)
-  "Load the named system and return a sorted vector containing all the
-quicklisp systems that were loaded to satisfy dependencies.
-
-This function should probably only be called once per process!
-Subsequent calls will miss dependencies identified by earlier calls."
-  (tagbody
-   retry
-     (restart-case
-         (let ((*standard-output* (make-broadcast-stream))
-               (*trace-output* (make-broadcast-stream))
-               (*main-system* system)
-               (*track-dependencies* t))
-           (our-quickload system)
-           (quickload-parasitic-systems system))
-       (try-again ()
-         :report "Start the quickload over again"
-         (go retry))
-       (die ()
-         :report "Just give up and die"
-         (uiop:quit 1))))
-
-  ;; Systems can't depend on themselves!
-  (forget-dependency system)
-  (values))
-
-(defun parasitic-system-data (parasite-system)
-  "Return a plist of information about the given known-parastic system.
-
-Sometimes we are asked to provide information about a system that is
-actually a parasite.  The only correct response is to point them
-toward the host system.  The nix package for the host system should
-have all the dependencies for this parasite already recorded.
-
-The plist is only meant to be consumed by other parts of
-quicklisp-to-nix."
-  (let ((host-system (host-system parasite-system)))
-    (list
-     :system parasite-system
-     :host host-system
-     :name (string-downcase (format nil "~a" parasite-system))
-     :host-name (string-downcase (format nil "~a" host-system)))))
-
-(defun system-data (system)
-  "Produce a plist describing a system.
-
-The plist is only meant to be consumed by other parts of
-quicklisp-to-nix."
-  (when (host-system system)
-    (return-from system-data
-      (parasitic-system-data system)))
-
-  (determine-dependencies system)
-  (let*
-      ((dependencies (sort (found-dependencies) #'string<))
-       (parasites (coerce (sort (found-parasites) #'string<) 'list))
-       (ql-system (find-system system))
-       (ql-release (release ql-system))
-       (ql-sibling-systems (provided-systems ql-release))
-       (url (archive-url ql-release))
-       (local-archive (local-archive-file ql-release))
-       (local-url (format nil "file://~a" (pathname local-archive)))
-       (archive-data
-        (progn
-          (ensure-local-archive-file ql-release)
-          ;; Stuff this archive into the nix store.  It was almost
-          ;; certainly going to end up there anyway (since it will
-          ;; probably be fetchurl'd for a nix package).  Also, putting
-          ;; it into the store also gives us the SHA we need.
-          (nix-prefetch-url local-url)))
-       (ideal-md5 (archive-md5 ql-release))
-       (raw-dependencies (coerce dependencies 'list))
-       (name (string-downcase (format nil "~a" system)))
-       (ql-sibling-names
-        (remove name (mapcar 'name ql-sibling-systems)
-                :test 'equal))
-       (dependencies raw-dependencies)
-       (description
-         (or
-           (ignore-errors (asdf:system-description (asdf:find-system system)))
-           "System lacks description"))
-       (release-name (short-description ql-release)))
-    (list
-     :system system
-     :description description
-     :sha256 (getf archive-data :sha256)
-     :url url
-     :md5 ideal-md5
-     :name name
-     :dependencies dependencies
-     :siblings ql-sibling-names
-     :release-name release-name
-     :parasites parasites)))
-
-(defvar *error-escape-valve* *error-output*
-  "When `*error-output*' is rebound to inhibit spew, this stream will
-still produce output.")
-
-(defun print-usage-and-quit ()
-  "Describe how to use this program... and then exit."
-  (format *error-output* "Usage:
-    ~A [--cacheDir <dir>] [--silent] [--debug] [--help|-h] <system-name>
-Arguments:
-    --cacheDir Store (and look for) compiled lisp files in the given directory
-    --verbose Show compilation output
-    --debug Enter the debugger when a fatal error is encountered
-    --help Print usage and exit
-    <system-name> The quicklisp system to examine
-" (or (uiop:argv0) "quicklisp-to-nix-system-info"))
-  (uiop:quit 2))
-
-(defun main ()
-  "Make it go."
-  (let ((argv (uiop:command-line-arguments))
-        cache-dir
-        target-system
-        verbose-p
-        debug-p)
-    (handler-bind
-        ((warning
-          (lambda (w)
-            (format *error-escape-valve* "~A~%" w)))
-         (error
-          (lambda (e)
-            (if debug-p
-                (invoke-debugger e)
-                (progn
-                  (format *error-escape-valve* "~
-Failed to extract system info. Details are below. ~
-Run with --debug and/or --verbose for more info.
-~A~%" e)
-                  (uiop:quit 1))))))
-      (loop :while argv :do
-         (cond
-           ((equal "--cacheDir" (first argv))
-            (pop argv)
-            (unless argv
-              (error "--cacheDir expects an argument"))
-            (setf cache-dir (first argv))
-            (pop argv))
-
-           ((equal "--verbose" (first argv))
-            (setf verbose-p t)
-            (pop argv))
-
-           ((equal "--debug" (first argv))
-            (setf debug-p t)
-            (pop argv))
-
-           ((or (equal "--help" (first argv))
-                (equal "-h" (first argv)))
-            (print-usage-and-quit))
-
-           (t
-            (setf target-system (pop argv))
-            (when argv
-              (error "Can only operate on one system")))))
-
-      (unless target-system
-        (print-usage-and-quit))
-
-      (when cache-dir
-        (setf cache-dir (pathname-as-directory (parse-namestring cache-dir))))
-
-      (mapcar (function require) *implementation-systems*)
-
-      (with-quicklisp (dir) (:cache-dir (or cache-dir :temp))
-        (declare (ignore dir))
-
-        (let (system-data)
-          (let ((*error-output* (if verbose-p
-                                    *error-output*
-                                    (make-broadcast-stream)))
-                (*standard-output* (if verbose-p
-                                       *standard-output*
-                                       (make-broadcast-stream)))
-                (*trace-output* (if verbose-p
-                                    *trace-output*
-                                    (make-broadcast-stream))))
-            (format *error-output*
-                    "quicklisp-to-nix-system-info ~A~%ASDF ~A~%Quicklisp ~A~%Compiler ~A ~A~%"
-                    *version*
-                    (asdf:asdf-version)
-                    (funcall (intern "CLIENT-VERSION" :ql))
-                    (lisp-implementation-type)
-                    (lisp-implementation-version))
-            (setf system-data (system-data target-system)))
-
-          (cond
-            (system-data
-             (format t "~W~%" system-data)
-             (uiop:quit 0))
-            (t
-             (format *error-output* "Failed to determine system data~%")
-             (uiop:quit 1))))))))
-
-(defun dump-image ()
-  "Make an executable"
-  (setf uiop:*image-entry-point* #'main)
-  (setf uiop:*lisp-interaction* nil)
-  (uiop:dump-image "quicklisp-to-nix-system-info" :executable t))