fix: package autoload order

This is an old issue that's haunted Doom for a while. I had initially
planned to wait until the switch to Elpaca, but I decided to just sit
down and solve this.

This ensures package autoloads are always written in depth-first
dependency order to Doom's profile init file, preventing load-order
issues like the notorious void-function geiser-activate-implementation
error. `geiser` needs to be built before any `geiser-*` plugins, since
its plugins reference variables/functions in geiser's own autoloads, but
there's no way to enforce package order in `straight--build-cache`
currently, and subsequent package updates (or just deleting package
directories by hand) can change the order of straight's build-cache in
subtle ways.

Fix: #7693
Fix: #7472
This commit is contained in:
Henrik Lissner
2024-11-07 00:11:51 -05:00
parent bcd399d1c3
commit 6a8c09f012

View File

@ -410,9 +410,19 @@ caches them in `doom--profiles'. If RELOAD? is non-nil, refresh the cache."
`((defun doom--startup-loaddefs-packages ()
(let ((load-in-progress t))
,@(doom-autoloads--scan
(mapcar #'straight--autoloads-file
(nreverse (seq-difference (hash-table-keys straight--build-cache)
doom-autoloads-excluded-packages)))
;; Create a list of packages starting with the Nth-most dependencies
;; by walking the package dependency tree depth-first. This ensures
;; any load-order constraints in package autoloads are always met.
(let (packages)
(letf! (defun* walk-packages (pkglist)
(cond ((null pkglist) nil)
((stringp pkglist)
(walk-packages (nth 1 (gethash pkglist straight--build-cache)))
(cl-pushnew pkglist packages :test #'equal))
((listp pkglist)
(mapc #'walk-packages (reverse pkglist)))))
(walk-packages (mapcar #'symbol-name (mapcar #'car doom-packages))))
(mapcar #'straight--autoloads-file (nreverse packages)))
doom-autoloads-excluded-files
'literal))
,@(when-let* ((info-dirs