Fix double-rebuilding & lingering stale elc files

This update addresses two evasive issues:

1. Packages updated with `doom update` would not rebuild correctly,
   requiring a `doom refresh` afterwards,
2. Packages would fail to rebuild even if their byte-compiled files were
   stale. The result: "*.el is newer than *.elc" warnings at startup.
This commit is contained in:
Henrik Lissner 2019-07-26 20:04:53 +02:00
parent f8c4d075a5
commit a10693886e
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -6,7 +6,6 @@
(doom-reload-core-autoloads) (doom-reload-core-autoloads)
(when (progn ,@body) (when (progn ,@body)
(doom-reload-package-autoloads 'force-p)) (doom-reload-package-autoloads 'force-p))
(doom--finalize-straight)
t)) t))
@ -20,9 +19,7 @@ This excludes packages whose `package!' declaration contains a non-nil :freeze
or :ignore property." or :ignore property."
(doom--ensure-autoloads-while (doom--ensure-autoloads-while
(straight-check-all) (straight-check-all)
(when (doom-packages-update doom-auto-accept) (doom-packages-update doom-auto-accept)))
(doom-packages-rebuild doom-auto-accept)
t)))
(def-command! (rebuild b) (&rest args) (def-command! (rebuild b) (&rest args)
"Rebuilds all installed packages. "Rebuilds all installed packages.
@ -96,24 +93,25 @@ a list of packages that will be installed."
;; REVIEW We do these modification checks manually because ;; REVIEW We do these modification checks manually because
;; Straight's checks seem to miss stale elc files. Need ;; Straight's checks seem to miss stale elc files. Need
;; more tests to confirm this. ;; more tests to confirm this.
(when (or (gethash package straight--cached-package-modifications) (when (or (ignore-errors
(file-newer-than-file-p (straight--repos-dir local-repo) (gethash package straight--packages-to-rebuild))
(straight--build-dir package)) (gethash package straight--cached-package-modifications)
(cl-loop for file (not (file-directory-p (straight--build-dir package))))
in (doom-files-in (straight--build-dir package)
:match "\\.el$"
:full t)
for elc-file = (byte-compile-dest-file file)
if (and (file-exists-p elc-file)
(file-newer-than-file-p file elc-file))
return t))
(print! (info "Rebuilding %s") package) (print! (info "Rebuilding %s") package)
;; REVIEW `straight-rebuild-package' alone wasn't enough. Why? (straight-rebuild-package package 'recursive)
(delete-directory (straight--build-dir package) 'recursive) (when (cl-loop for file
(straight-rebuild-package package) in (doom-files-in (straight--build-dir package)
:match "\\.el$"
:full t)
for elc-file = (byte-compile-dest-file file)
if (and (file-exists-p elc-file)
(file-newer-than-file-p file elc-file))
return t)
(straight--byte-compile-package recipe))
(cl-incf n))))))) (cl-incf n)))))))
(if (= n 0) (if (= n 0)
(ignore (print! (success "No packages need rebuilding"))) (ignore (print! (success "No packages need rebuilding")))
(doom--finalize-straight)
(print! (success "Rebuilt %d package(s)" n)) (print! (success "Rebuilt %d package(s)" n))
t)))) t))))
@ -159,12 +157,16 @@ a list of packages that will be updated."
(condition-case e (condition-case e
(let* ((default-directory (straight--repos-dir local-repo)) (let* ((default-directory (straight--repos-dir local-repo))
(n (string-to-number (n (string-to-number
(shell-command-to-string "git rev-list --right-only --count HEAD..@'{u}'"))) (straight--get-call "git" "rev-list" "--right-only" "--count" "HEAD..@{u}")))
(pretime (pretime
(string-to-number (string-to-number
(shell-command-to-string "git log -1 --format=%at HEAD"))) (shell-command-to-string "git log -1 --format=%at HEAD")))
(time (time
(string-to-number (string-to-number
;; HACK `straight--get-call' has a higher
;; failure rate when querying FETCH_HEAD; not
;; sure why. Doing this manually, with
;; `shell-command-to-string' works fine.
(shell-command-to-string "git log -1 --format=%at FETCH_HEAD")))) (shell-command-to-string "git log -1 --format=%at FETCH_HEAD"))))
(with-current-buffer (straight--process-get-buffer) (with-current-buffer (straight--process-get-buffer)
(with-silent-modifications (with-silent-modifications
@ -219,30 +221,36 @@ a list of packages that will be updated."
(ignore (print! (info "Aborted update"))) (ignore (print! (info "Aborted update")))
(terpri) (terpri)
(straight--make-package-modifications-available) (straight--make-package-modifications-available)
(dolist (spec specs t) (let ((straight--packages-to-rebuild (make-hash-table :test #'equal))
(cl-destructuring-bind (n pretime time recipe) spec (straight--packages-not-to-rebuild (make-hash-table :test #'equal)))
(straight--with-plist recipe (local-repo package) (dolist (spec specs)
(let ((default-directory (straight--repos-dir local-repo))) (cl-destructuring-bind (n pretime time recipe) spec
(print! (start "Updating %S") package) (straight--with-plist recipe (local-repo package)
;; HACK `straight' assumes it won't be used in a (let ((default-directory (straight--repos-dir local-repo)))
;; noninteractive session, but here we are. If the repo (print! (start "Updating %S") package)
;; is dirty, the command will lock up, waiting for ;; HACK `straight' assumes it won't be used in a
;; interaction that will never come, so discard all ;; noninteractive session, but here we are. If the repo
;; local changes. Doom doesn't want you modifying those ;; is dirty, the command will lock up, waiting for
;; anyway. ;; interaction that will never come, so discard all
(and (straight--get-call "git" "reset" "--hard") ;; local changes. Doom doesn't want you modifying those
(straight--get-call "git" "clean" "-ffd")) ;; anyway.
(straight-merge-package package) (and (straight--get-call "git" "reset" "--hard")
;; HACK `straight-rebuild-package' doesn't pick up (straight--get-call "git" "clean" "-ffd"))
;; that this package has changed, so we do it (straight-merge-package package)
;; manually. Is there a better way? ;; HACK `straight-rebuild-package' doesn't pick up that
(straight-register-repo-modification local-repo) ;; this package has changed, so we do it manually. Is
(puthash local-repo t straight--cached-package-modifications) ;; there a better way?
(cl-incf n)) (ignore-errors
(with-current-buffer (straight--process-get-buffer) (delete-directory (straight--build-dir package) 'recursive))
(with-silent-modifications (puthash package t straight--packages-to-rebuild)
(print! (debug (autofill "%s") (indent 2 (buffer-string)))) (cl-incf n))
(erase-buffer))))))) (with-current-buffer (straight--process-get-buffer)
(with-silent-modifications
(print! (debug (autofill "%s") (indent 2 (buffer-string))))
(erase-buffer))))))
(doom--finalize-straight)
(doom-packages-rebuild auto-accept-p))
t)
(print! (success "No packages to update")) (print! (success "No packages to update"))
nil)) nil))
(error (error
@ -296,6 +304,7 @@ a list of packages that will be updated."
(if (= n 0) (if (= n 0)
(ignore (print! (warn "Didn't prune any %s(s) for some reason" label))) (ignore (print! (warn "Didn't prune any %s(s) for some reason" label)))
(print! (success "Pruned %d %s(s)" n label)) (print! (success "Pruned %d %s(s)" n label))
(doom--finalize-straight)
t))))))) t)))))))
(defun doom-packages-purge (&optional elpa-p builds-p repos-p auto-accept-p) (defun doom-packages-purge (&optional elpa-p builds-p repos-p auto-accept-p)