Refactor autoload generator

- Halves LOC
- Adopts functional paradigm where possible.
- Reduces the filesize of autoloads files by ~10-20%
- Speeds up autoloads generation by ~20%
This commit is contained in:
Henrik Lissner 2019-12-29 21:25:40 -05:00
parent 4808d40736
commit f8ff50565e
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
3 changed files with 264 additions and 396 deletions

View file

@ -1,166 +1,202 @@
;;; core/cli/autoloads.el -*- lexical-binding: t; -*- ;;; core/cli/autoloads.el -*- lexical-binding: t; -*-
(defvar doom-autoload-excluded-packages '("gh") (defvar doom-autoload-excluded-packages '("gh")
"Packages that have silly or destructive autoload files that try to load "What packages whose autoloads file we won't index.
These packages have silly or destructive autoload files that try to load
everyone in the universe and their dog, causing errors that make babies cry. No everyone in the universe and their dog, causing errors that make babies cry. No
one wants that.") one wants that.")
(defvar doom-autoload-cached-vars
'(load-path
auto-mode-alist
Info-directory-list
doom-disabled-packages)
"A list of variables to be cached in `doom-package-autoload-file'.")
;; externs ;; externs
(defvar autoload-timestamps) (defvar autoload-timestamps)
(defvar generated-autoload-load-name) (defvar generated-autoload-load-name)
(defvar generated-autoload-file)
(defun doom-cli-reload-autoloads (&optional type force-p)
;;
;;; Helpers
(defun doom--cli-delete-autoloads-file (file)
"Delete FILE (an autoloads file) and accompanying *.elc file, if any."
(cl-check-type file string)
(when (file-exists-p file)
(when-let (buf (find-buffer-visiting file))
(with-current-buffer buf
(set-buffer-modified-p nil))
(kill-buffer buf))
(delete-file file)
(ignore-errors (delete-file (byte-compile-dest-file file)))
t))
(defun doom--cli-warn-refresh-session-h ()
(message "Restart or reload Doom Emacs for changes to take effect:\n")
(message " M-x doom/restart-and-restore")
(message " M-x doom/restart")
(message " M-x doom/reload"))
(defun doom--cli-byte-compile-file (file)
(let ((byte-compile-warnings (if doom-debug-mode byte-compile-warnings))
(byte-compile-dynamic t)
(byte-compile-dynamic-docstrings t))
(condition-case-unless-debug e
(when (byte-compile-file file)
(unless doom-interactive-mode
(add-hook 'doom-cli-post-success-execute-hook #'doom--cli-warn-refresh-session-h))
(let (noninteractive)
(load file 'noerror 'nomessage 'nosuffix)))
((debug error)
(let ((backup-file (concat file ".bk")))
(print! (warn "Copied backup to %s") (relpath backup-file))
(copy-file file backup-file 'overwrite))
(doom--cli-delete-autoloads-file file)
(signal 'doom-autoload-error (list file e))))))
(defun doom-cli-reload-autoloads (&optional file force-p)
"Reloads FILE (an autoload file), if it needs reloading. "Reloads FILE (an autoload file), if it needs reloading.
FILE should be one of `doom-autoload-file' or `doom-package-autoload-file'. If FILE should be one of `doom-autoload-file' or `doom-package-autoload-file'. If
it is nil, it will try to reload both. If FORCE-P (universal argument) do it it is nil, it will try to reload both. If FORCE-P (universal argument) do it
even if it doesn't need reloading!" even if it doesn't need reloading!"
(or (null file) (if type
(stringp file) (cond ((eq type 'core)
(signal 'wrong-type-argument (list 'stringp file))) (doom-cli-reload-core-autoloads
(if (stringp file) doom-autoload-file force-p))
(cond ((file-equal-p file doom-autoload-file) ((eq type 'package)
(doom-cli-reload-core-autoloads force-p)) (doom-cli-reload-package-autoloads
((file-equal-p file doom-package-autoload-file) doom-package-autoload-file force-p))
(doom-cli-reload-package-autoloads force-p)) ((error "Invalid autoloads file: %s" type)))
((error "Invalid autoloads file: %s" file))) (doom-cli-reload-autoloads 'core force-p)
(doom-cli-reload-core-autoloads force-p) (doom-cli-reload-autoloads 'package force-p)))
(doom-cli-reload-package-autoloads force-p)))
(defun doom-cli-reload-core-autoloads (file &optional force-p)
(cl-check-type file string)
(print! (start "(Re)generating core autoloads..."))
(print-group!
(let ((autoload-files
(cl-loop for dir in (append (list doom-core-dir)
(cdr (doom-module-load-path 'all-p))
(list doom-private-dir))
if (doom-glob dir "autoload.el") collect it
if (doom-glob dir "autoload/*.el") append it)))
(if (or force-p
(not (file-exists-p file))
(file-newer-than-file-p doom-emacs-dir file)
(cl-loop for dir
in (append (doom-glob doom-private-dir "init.el*")
autoload-files)
if (file-newer-than-file-p dir doom-autoload-file)
return t))
(and (print! (start "Generating core autoloads..."))
(doom-cli--write-autoloads
file (doom-cli--generate-autoloads autoload-files 'scan))
(print! (start "Byte-compiling core autoloads file..."))
(doom-cli--byte-compile-file file)
(print! (success "Generated %s")
(relpath (byte-compile-dest-file file)
doom-emacs-dir)))
(print! (success "Core autoloads are up-to-date"))
nil))))
(defun doom-cli-reload-package-autoloads (file &optional force-p)
(cl-check-type file string)
(print! (start "(Re)generating package autoloads..."))
(print-group!
(doom-initialize-packages)
(if (or force-p
(not (file-exists-p file))
(file-newer-than-file-p package-user-dir file)
(cl-loop for dir in (straight--directory-files (straight--build-dir))
if (cl-find-if
(doom-rpartial #'file-newer-than-file-p doom-package-autoload-file)
(doom-glob (straight--build-dir dir) "*.el"))
return t)
(not (cl-loop with doom-modules = (doom-modules)
for key being the hash-keys of doom-modules
for path = (doom-module-path (car key) (cdr key) "packages.el")
if (file-newer-than-file-p path doom-package-autoload-file)
return t)))
(and (print! (start "Generating package autoloads..."))
(doom-cli--write-autoloads
file
(doom-cli--generate-var-cache doom-autoload-cached-vars)
(doom-cli--generate-autoloads
(mapcar #'straight--autoloads-file
(cl-set-difference (hash-table-keys straight--build-cache)
doom-autoload-excluded-packages
:test #'string=))))
(print! (start "Byte-compiling package autoloads file..."))
(doom-cli--byte-compile-file file)
(print! (success "Generated %s")
(relpath (byte-compile-dest-file file)
doom-emacs-dir)))
(print! (success "Package autoloads are up-to-date"))
nil)))
;; ;;
;;; Doom autoloads ;;; Helpers
(defun doom--cli-generate-header (func) (defun doom-cli--write-autoloads (file &rest forms)
(goto-char (point-min)) (make-directory (file-name-directory file) 'parents)
(insert ";; -*- lexical-binding:t; -*-\n" (condition-case-unless-debug e
";; This file is autogenerated by `" (symbol-name func) "', DO NOT EDIT !!\n\n")) (with-temp-file file
(let ((standard-output (current-buffer))
(print-quoted t)
(print-level nil)
(print-length nil))
(insert ";; -*- lexical-binding: t; -*-\n"
";; This file is autogenerated by Doom, DO NOT EDIT IT!!\n")
(dolist (form (delq nil forms))
(mapc #'print form))
t))
(error (delete-file file)
(signal 'doom-autoload-error (list file e)))))
(defun doom--cli-generate-autoloads (targets) (defun doom-cli--byte-compile-file (file)
(let ((n 0)) (condition-case-unless-debug e
(dolist (file targets) (let ((byte-compile-warnings (if doom-debug-mode byte-compile-warnings))
(insert (byte-compile-dynamic t)
(with-temp-buffer (byte-compile-dynamic-docstrings t))
(cond ((not (doom-file-cookie-p file "if" t)) (when (byte-compile-file file)
(print! (debug "Ignoring %s") (relpath file))) (unless doom-interactive-mode
(add-hook 'doom-cli-post-success-execute-hook #'doom-cli--warn-refresh-session-h))
(load (byte-compile-dest-file file) nil t)))
(error
(delete-file (byte-compile-dest-file file))
(signal 'doom-autoload-error (list file e)))))
((let ((generated-autoload-load-name (file-name-sans-extension file)) (defun doom-cli--warn-refresh-session-h ()
;; Prevent `autoload-find-file' from firing file hooks, (print! "Restart or reload Doom Emacs for changes to take effect:")
;; e.g. adding to recentf. (print-group! (print! "M-x doom/restart-and-restore")
find-file-hook (print! "M-x doom/restart")
write-file-functions (print! "M-x doom/reload")))
;; Prevent a possible source of crashes when there's a
;; syntax error in the autoloads file
debug-on-error)
(quiet! (autoload-generate-file-autoloads file (current-buffer))))
(print! (debug "Nothing in %s") (relpath file)))
((cl-incf n) (defun doom-cli--generate-var-cache (vars)
(print! (debug "Scanning %s...") (relpath file)))) `((setq ,@(cl-loop for var in vars
(buffer-string)))) append `(,var ',(symbol-value var))))))
(print! (class (if (> n 0) 'success 'info)
"Scanned %d file(s)")
n)))
(defun doom--cli-expand-autoload-paths (&optional allow-internal-paths) (defun doom-cli--filter-form (form &optional expand)
(let ((load-path (let ((func (car-safe form)))
;; NOTE With `doom-private-dir' in `load-path', Doom autoloads files (cond ((memq func '(provide custom-autoload))
;; will be unable to declare autoloads for the built-in autoload.el nil)
;; Emacs package, should $DOOMDIR/autoload.el exist. Not sure why ((and (eq func 'add-to-list)
;; they'd want to though, so it's an acceptable compromise. (memq (doom-unquote (cadr form))
(append (list doom-private-dir) doom-autoload-cached-vars))
doom-modules-dirs nil)
(straight--directory-files (straight--build-dir) nil t) ((not (eq func 'autoload))
load-path))) form)
((and expand (not (file-name-absolute-p (nth 2 form))))
(defvar doom--autoloads-path-cache nil) (defvar doom--autoloads-path-cache nil)
(while (re-search-forward "^\\s-*(\\(?:custom-\\)?autoload\\s-+'[^ ]+\\s-+\"\\([^\"]*\\)\"" nil t) (setf (nth 2 form)
(let ((path (match-string 1))) (let ((path (nth 2 form)))
(replace-match
(or (cdr (assoc path doom--autoloads-path-cache)) (or (cdr (assoc path doom--autoloads-path-cache))
(when-let* ((libpath (or (and allow-internal-paths (when-let* ((libpath (locate-library path))
(locate-library path nil (cons doom-emacs-dir doom-modules-dirs)))
(locate-library path)))
(libpath (file-name-sans-extension libpath)) (libpath (file-name-sans-extension libpath))
(libpath (abbreviate-file-name libpath))) (libpath (abbreviate-file-name libpath)))
(push (cons path libpath) doom--autoloads-path-cache) (push (cons path libpath) doom--autoloads-path-cache)
libpath) libpath)
path) path)))
t t nil 1))))) form)
(form))))
(defun doom--cli-generate-autodefs-1 (path &optional member-p) (defun doom-cli--generate-autoloads-autodefs (file buffer module &optional module-enabled-p)
(let (forms) (with-current-buffer
(or (get-file-buffer file)
(autoload-find-file file))
(goto-char (point-min))
(while (re-search-forward "^;;;###autodef *\\([^\n]+\\)?\n" nil t) (while (re-search-forward "^;;;###autodef *\\([^\n]+\\)?\n" nil t)
(let* ((sexp (sexp-at-point)) (let* ((standard-output buffer)
(alt-sexp (match-string 1)) (form (read (current-buffer)))
(type (car sexp)) (altform (match-string 1))
(name (doom-unquote (cadr sexp))) (definer (car-safe form))
(origin (doom-module-from-path path))) (symbol (doom-unquote (cadr form))))
(cond (cond ((and (not module-enabled-p) altform)
((and (not member-p) (print (read altform)))
alt-sexp) ((memq definer '(defun defmacro cl-defun cl-defmacro))
(push (read alt-sexp) forms)) (if module-enabled-p
(print (make-autoload form file))
((memq type '(defun defmacro cl-defun cl-defmacro)) (cl-destructuring-bind (_ _ arglist &rest body) form
(cl-destructuring-bind (_ _name arglist &rest body) sexp (print
(appendq! (if altform
forms (read altform)
(list (if member-p
(make-autoload sexp path)
(let ((docstring
(format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
origin
(if (stringp (car body))
(pop body)
"No documentation."))))
(condition-case-unless-debug e
(if alt-sexp
(read alt-sexp)
(append (append
(list (pcase type (list (pcase definer
(`defun 'defmacro) (`defun 'defmacro)
(`cl-defun `cl-defmacro) (`cl-defun `cl-defmacro)
(_ type)) (_ type))
name arglist docstring) symbol arglist
(format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
module
(if (stringp (car body))
(pop body)
"No documentation.")))
(cl-loop for arg in arglist (cl-loop for arg in arglist
if (and (symbolp arg) if (and (symbolp arg)
(not (keywordp arg)) (not (keywordp arg))
@ -168,240 +204,71 @@ even if it doesn't need reloading!"
collect arg into syms collect arg into syms
else if (listp arg) else if (listp arg)
collect (car arg) into syms collect (car arg) into syms
finally return (if syms `((ignore ,@syms)))))) finally return (if syms `((ignore ,@syms)))))))))
('error (print `(put ',symbol 'doom-module ',module)))
(print! "- Ignoring autodef %s (%s)" name e) ((eq definer 'defalias)
nil)))) (cl-destructuring-bind (_ _ target &optional docstring) form
`(put ',name 'doom-module ',origin))))) (unless module-enabled-p
((eq type 'defalias)
(cl-destructuring-bind (_type name target &optional docstring) sexp
(let ((name (doom-unquote name))
(target (doom-unquote target)))
(unless member-p
(setq target #'ignore (setq target #'ignore
docstring docstring
(format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s" (format "THIS FUNCTION DOES NOTHING BECAUSE %s IS DISABLED\n\n%s"
origin docstring))) module docstring)))
(appendq! forms `((put ',name 'doom-module ',origin) (print `(put ',symbol 'doom-module ',module))
(defalias ',name #',target ,docstring)))))) (print `(defalias ',symbol #',(doom-unquote target) ,docstring))))
(module-enabled-p (print form)))))))
(member-p (push sexp forms)))))
forms))
(defun doom--cli-generate-autodefs (targets enabled-targets)
(goto-char (point-max))
(search-backward ";;;***" nil t)
(save-excursion (insert "\n"))
(dolist (path targets)
(insert
(with-temp-buffer
(insert-file-contents path)
(if-let (forms (doom--cli-generate-autodefs-1 path (member path enabled-targets)))
(concat (mapconcat #'prin1-to-string (nreverse forms) "\n")
"\n")
"")))))
(defun doom--cli-cleanup-autoloads ()
(goto-char (point-min))
(when (re-search-forward "^;;\\(;[^\n]*\\| no-byte-compile: t\\)\n" nil t)
(replace-match "" t t)))
(defun doom-cli-reload-core-autoloads (&optional force-p)
"Refreshes `doom-autoload-file', if necessary (or if FORCE-P is non-nil).
It scans and reads autoload cookies (;;;###autoload) in core/autoload/*.el,
modules/*/*/autoload.el and modules/*/*/autoload/*.el, and generates
`doom-autoload-file'.
Run this whenever your `doom!' block, or a module autoload file, is modified."
(require 'autoload)
(let* ((default-directory doom-emacs-dir)
(doom-modules (doom-modules))
(defun doom-cli--generate-autoloads-buffer (file)
(when (doom-file-cookie-p file "if" t)
(let* (;; Prevent `autoload-find-file' from firing file hooks, e.g. adding
;; to recentf.
find-file-hook
write-file-functions
;; Prevent a possible source of crashes when there's a syntax error
;; in the autoloads file
debug-on-error
;; The following bindings are in `package-generate-autoloads'. ;; The following bindings are in `package-generate-autoloads'.
;; Presumably for a good reason, so I just copied them ;; Presumably for a good reason, so I just copied them
(backup-inhibited t) (backup-inhibited t)
(version-control 'never) (version-control 'never)
(case-fold-search nil) ; reduce magic case-fold-search ; reduce magic
(autoload-timestamps nil) autoload-timestamps ; reduce noise in generated files
;; Needed for `autoload-generate-file-autoloads'
;; Where we'll store the files we'll scan for autoloads. This should (generated-autoload-load-name (file-name-sans-extension file))
;; contain *all* autoload files, even in disabled modules, so we can (target-buffer (current-buffer))
;; scan those for autodefs. We start with the core libraries. (module (doom-module-from-path file))
(targets (doom-glob doom-core-dir "autoload/*.el")) (module-enabled-p (or (memq (car module) '(:core :private))
;; A subset of `targets' in enabled modules (doom-module-p (car module) (cdr module)))))
(active-targets (copy-sequence targets)))
(dolist (path (doom-module-load-path 'all-p))
(when-let* ((files (cons (doom-glob path "autoload.el")
(doom-files-in (doom-path path "autoload")
:match "\\.el$")))
(files (delq nil files)))
(appendq! targets files)
(when (or (doom-module-from-path path 'enabled-only)
(file-equal-p path doom-private-dir))
(appendq! active-targets files))))
(print! (start "Checking core autoloads file"))
(print-group!
(if (and (not force-p)
(file-exists-p doom-autoload-file)
(not (file-newer-than-file-p doom-emacs-dir doom-autoload-file))
(not (cl-loop for dir
in (append (doom-glob doom-private-dir "init.el*")
targets)
if (file-newer-than-file-p dir doom-autoload-file)
return t)))
(ignore
(print! (success "Skipping core autoloads, they are up-to-date"))
(doom-load-autoloads-file doom-autoload-file))
(if (doom--cli-delete-autoloads-file doom-autoload-file)
(print! (success "Deleted old %s") (filename doom-autoload-file))
(make-directory (file-name-directory doom-autoload-file) t))
(print! (start "Regenerating core autoloads file"))
(print-group!
(with-temp-file doom-autoload-file
(doom--cli-generate-header 'doom-cli-reload-core-autoloads)
(save-excursion (save-excursion
(doom--cli-generate-autoloads active-targets) (when module-enabled-p
(print! (success "Generated new autoloads.el"))) (quiet! (autoload-generate-file-autoloads file target-buffer)))
;; Replace autoload paths (only for module autoloads) with absolute (doom-cli--generate-autoloads-autodefs
;; paths for faster resolution during load and simpler `load-path' file target-buffer module module-enabled-p)))))
(save-excursion
(doom--cli-expand-autoload-paths 'allow-internal-paths)
(print! (success "Expanded module autoload paths")))
;; Generates stub definitions for functions/macros defined in disabled
;; modules, so that you will never get a void-function when you use
;; them.
(save-excursion
(doom--cli-generate-autodefs targets (reverse active-targets))
(print! (success "Generated autodefs")))
;; Remove byte-compile-inhibiting file variables so we can byte-compile
;; the file, and autoload comments.
(doom--cli-cleanup-autoloads)
(print! (success "Cleaned up autoloads"))))
;; Byte compile it to give the file a chance to reveal errors (and buy us a
;; few marginal performance boosts)
(print! "> Byte-compiling %s..." (relpath doom-autoload-file))
(when (doom--cli-byte-compile-file doom-autoload-file)
(print-group!
(print! (success "Compiled %s") (relpath doom-autoload-file)))))
t)))
(defun doom-cli--generate-autoloads (files &optional scan)
;;
;;; Package autoloads
(defun doom--generate-package-autoloads ()
"Concatenates package autoload files, let-binds `load-file-name' around
them,and remove unnecessary `provide' statements or blank links."
(dolist (pkg (hash-table-keys straight--build-cache))
(unless (member pkg doom-autoload-excluded-packages)
(let ((file (straight--autoloads-file pkg)))
(when (file-exists-p file)
(insert-file-contents file)
(save-excursion
(while (re-search-forward "\\(?:\\_<load-file-name\\|#\\$\\)\\_>" nil t)
;; `load-file-name' is meaningless in a concatenated
;; mega-autoloads file, so we replace references to it and #$ with
;; the file they came from.
(unless (doom-point-in-string-or-comment-p)
(replace-match (prin1-to-string (abbreviate-file-name file))
t t))))
(while (re-search-forward "^\\(?:;;\\(.*\n\\)\\|\n\\|(provide '[^\n]+\\)" nil t)
(unless (doom-point-in-string-p)
(replace-match "" t t)))
(unless (bolp) (insert "\n")))))))
(defun doom--generate-var-cache ()
"Print a `setq' form for expensive-to-initialize variables, so we can cache
them in Doom's autoloads file."
(doom-initialize-packages)
(prin1 `(setq load-path ',load-path
auto-mode-alist ',auto-mode-alist
Info-directory-list ',Info-directory-list
doom-disabled-packages ',doom-disabled-packages)
(current-buffer)))
(defun doom--cleanup-package-autoloads ()
"Remove (some) forms that modify `load-path' or `auto-mode-alist'.
These variables are cached all at once and at later, so these removed statements
served no purpose but to waste cycles."
(while (re-search-forward "^\\s-*\\((\\(?:add-to-list\\|\\(?:when\\|if\\) (boundp\\)\\s-+'\\(?:load-path\\|auto-mode-alist\\)\\)" nil t)
(goto-char (match-beginning 1))
(kill-sexp)))
(defun doom-cli-reload-package-autoloads (&optional force-p)
"Compiles `doom-package-autoload-file' from the autoloads files of all
installed packages. It also caches `load-path', `Info-directory-list',
`doom-disabled-packages', `package-activated-list' and `auto-mode-alist'.
Will do nothing if none of your installed packages have been modified. If
FORCE-P (universal argument) is non-nil, regenerate it anyway.
This should be run whenever your `doom!' block or update your packages."
(require 'autoload) (require 'autoload)
(print! (start "Checking package autoloads file")) (let (autoloads)
(print-group! (dolist (file files (delq nil (nreverse autoloads)))
(if (and (not force-p) (and (file-readable-p file)
(file-exists-p doom-package-autoload-file) (with-temp-buffer
(not (file-newer-than-file-p package-user-dir doom-package-autoload-file))
(not (cl-loop for dir in (straight--directory-files (straight--build-dir))
if (cl-find-if
(lambda (dir)
(file-newer-than-file-p dir doom-package-autoload-file))
(doom-glob (straight--build-dir dir) "*.el"))
return t))
(not (cl-loop with doom-modules = (doom-modules)
for key being the hash-keys of doom-modules
for path = (doom-module-path (car key) (cdr key) "packages.el")
if (file-newer-than-file-p path doom-package-autoload-file)
return t)))
(ignore
(print! (success "Skipping package autoloads, they are up-to-date"))
(doom-load-autoloads-file doom-package-autoload-file))
(let (;; The following bindings are in `package-generate-autoloads'.
;; Presumably for a good reason, so I just copied them
(backup-inhibited t)
(version-control 'never)
(case-fold-search nil) ; reduce magic
(autoload-timestamps nil))
(if (doom--cli-delete-autoloads-file doom-package-autoload-file)
(print! (success "Deleted old %s") (filename doom-package-autoload-file))
(make-directory (file-name-directory doom-autoload-file) t))
(print! (start "Regenerating package autoloads file"))
(print-group!
(with-temp-file doom-package-autoload-file
(doom--cli-generate-header 'doom-cli-reload-package-autoloads)
(save-excursion (save-excursion
;; Cache important and expensive-to-initialize state here. (if scan
(doom--generate-var-cache) (doom-cli--generate-autoloads-buffer file)
(print! (success "Cached package state")) (insert-file-contents-literally file)))
;; Concatenate the autoloads of all installed packages.
(doom--generate-package-autoloads)
(print! (success "Package autoloads included")))
;; Replace autoload paths (only for module autoloads) with absolute
;; paths for faster resolution during load and simpler `load-path'
(save-excursion (save-excursion
(doom--cli-expand-autoload-paths) (let ((filestr (prin1-to-string file)))
(print! (success "Expanded module autoload paths"))) (while (re-search-forward "\\_<load-file-name\\_>" nil t)
;; `load-file-name' is meaningless in a concatenated
;; Remove `load-path' and `auto-mode-alist' modifications (most of them, ;; mega-autoloads file, so we replace references to it with the
;; at least); they are cached later, so all those membership checks are ;; file they came from.
;; unnecessary overhead. (replace-match filestr t t))))
(doom--cleanup-package-autoloads) (let ((load-file-name file)
(print! (success "Removed load-path/auto-mode-alist entries")))) (load-path
;; Byte compile it to give the file a chance to reveal errors (and buy us a (append (list doom-private-dir)
;; few marginal performance boosts) doom-modules-dirs
(print! (start "Byte-compiling %s...") (relpath doom-package-autoload-file)) load-path)))
(when (doom--cli-byte-compile-file doom-package-autoload-file) (condition-case _
(print-group! (while t
(print! (success "Compiled %s") (relpath doom-package-autoload-file)))))) (push (doom-cli--filter-form (read (current-buffer))
t)) scan)
autoloads))
(end-of-file))))))))

View file

@ -10,9 +10,9 @@ between HEAD and FETCH_HEAD. This can take a while.
This excludes packages whose `package!' declaration contains a non-nil :freeze This excludes packages whose `package!' declaration contains a non-nil :freeze
or :ignore property." or :ignore property."
(straight-check-all) (straight-check-all)
(doom-cli-reload-core-autoloads) (doom-cli-reload-autoloads 'core)
(when (doom-cli-packages-update) (when (doom-cli-packages-update)
(doom-cli-reload-package-autoloads 'force-p)) (doom-cli-reload-autoloads 'package 'force))
t) t)
(defcli! (build b) (defcli! (build b)
@ -23,7 +23,7 @@ This ensures that all needed files are symlinked from their package repo and
their elisp files are byte-compiled. This is especially necessary if you upgrade their elisp files are byte-compiled. This is especially necessary if you upgrade
Emacs (as byte-code is generally not forward-compatible)." Emacs (as byte-code is generally not forward-compatible)."
(when (doom-cli-packages-build (not rebuild-p)) (when (doom-cli-packages-build (not rebuild-p))
(doom-cli-reload-package-autoloads 'force-p)) (doom-cli-reload-autoloads 'package 'force))
t) t)
(defcli! (purge p) (defcli! (purge p)
@ -46,7 +46,7 @@ list remains lean."
(not norepos-p) (not norepos-p)
(not nobuilds-p) (not nobuilds-p)
regraft-p) regraft-p)
(doom-cli-reload-package-autoloads 'force-p)) (doom-cli-reload-autoloads 'package 'force))
t) t)
;; (defcli! rollback () ; TODO doom rollback ;; (defcli! rollback () ; TODO doom rollback
@ -310,7 +310,7 @@ a `package!' declaration) or isn't depended on by another primary package.
If BUILDS-P, include straight package builds. If BUILDS-P, include straight package builds.
If REPOS-P, include straight repos. If REPOS-P, include straight repos.
If ELPA-P, include packages installed with package.el (M-x package-install)." If ELPA-P, include packages installed with package.el (M-x package-install)."
(print! (start "Searching for orphaned packages to purge (for the emperor)...")) (print! (start "Purging orphaned packages (for the emperor)..."))
(cl-destructuring-bind (&optional builds-to-purge repos-to-purge repos-to-regraft) (cl-destructuring-bind (&optional builds-to-purge repos-to-purge repos-to-regraft)
(let ((rdirs (straight--directory-files (straight--repos-dir) nil nil 'sort)) (let ((rdirs (straight--directory-files (straight--repos-dir) nil nil 'sort))
(bdirs (straight--directory-files (straight--build-dir) nil nil 'sort))) (bdirs (straight--directory-files (straight--build-dir) nil nil 'sort)))

View file

@ -248,13 +248,14 @@ stale."
;; Ensures that no pre-existing state pollutes the generation of the new ;; Ensures that no pre-existing state pollutes the generation of the new
;; autoloads files. ;; autoloads files.
(mapc #'doom--cli-delete-autoloads-file (dolist (file (list doom-autoload-file doom-package-autoload-file))
(list doom-autoload-file (delete-file file)
doom-package-autoload-file)) (delete-file (byte-compile-dest-file file)))
(doom-initialize 'force 'noerror) (doom-initialize 'force 'noerror)
(doom-initialize-modules) (doom-initialize-modules)
(doom-cli-reload-core-autoloads (not if-necessary-p)) (doom-cli-reload-autoloads 'core (not if-necessary-p))
(unwind-protect (unwind-protect
(progn (progn
(and (doom-cli-packages-install) (and (doom-cli-packages-install)
@ -263,7 +264,7 @@ stale."
(setq success t)) (setq success t))
(and (doom-cli-packages-purge prune-p 'builds-p prune-p prune-p) (and (doom-cli-packages-purge prune-p 'builds-p prune-p prune-p)
(setq success t))) (setq success t)))
(doom-cli-reload-package-autoloads (or success (not if-necessary-p))) (doom-cli-reload-autoloads 'package (or success (not if-necessary-p)))
(doom-cli-byte-compile nil 'recompile)) (doom-cli-byte-compile nil 'recompile))
t))) t)))