sxhash doesn't guarantee hashes are consistent across Emacs sessions, so
use md5 instead. Also simplifies what's getting hashed;
`system-configuration` is a sufficient substitute for both `system-type`
and what I wanted to glean from changes in
`system-configuration-features`.
Amend: 80e9263b85
Close: #8030
Ref: #8024
Co-authored-by: yaaama <yaaama@users.noreply.github.com>
124 lines
5.2 KiB
EmacsLisp
124 lines
5.2 KiB
EmacsLisp
;;; lisp/cli/sync.el --- synchronize config command -*- lexical-binding: t; -*-
|
|
;;; Commentary:
|
|
;;; Code:
|
|
|
|
(load! "packages")
|
|
|
|
|
|
;;
|
|
;;; Variables
|
|
|
|
(defvar doom-after-sync-hook ()
|
|
"Hooks run after 'doom sync' synchronizes the user's config with Doom.")
|
|
|
|
(defvar doom-before-sync-hook ()
|
|
"Hooks run before 'doom sync' synchronizes the user's config with Doom.")
|
|
|
|
(defvar doom-cli-sync-info-file (file-name-concat doom-profile-data-dir "sync"))
|
|
|
|
|
|
;;
|
|
;;; Commands
|
|
|
|
(defcli! ((sync s))
|
|
((noenvvar? ("-e") "Don't regenerate the envvar file")
|
|
(update? ("-u") "Update all installed packages after syncing")
|
|
(noupdate? ("-U") "Don't update any packages")
|
|
(purge? ("--gc") "Purge orphaned package repos & regraft them")
|
|
(jobs ("-j" "--jobs" num) "How many threads to use for native compilation")
|
|
(rebuild? ("-b" "--rebuild") "Rebuild all installed packages, unconditionally")
|
|
(nobuild? ("-B") "Don't rebuild packages when hostname or Emacs version has changed")
|
|
(aot? ("--aot") "Natively compile packages ahead-of-time (if available)")
|
|
&context context)
|
|
"Synchronize your config with Doom Emacs.
|
|
|
|
This is the equivalent of running autoremove, install, autoloads, then
|
|
recompile. Run this whenever you:
|
|
|
|
1. Modify your `doom!' block,
|
|
2. Add, remove, or modify `package!' blocks to your config,
|
|
3. Add, remove, or modify autoloaded functions in module autoloaded files,
|
|
4. Update Doom manually (e.g. with git),
|
|
5. Move your Doom config (either $EMACSDIR or $DOOMDIR) to a new location.
|
|
6. Up or downgrade Emacs itself (e.g. 29.1 -> 29.4).
|
|
|
|
Sync'ing ensures that unneeded packages are removed, needed packages are
|
|
installed, autoloads files are up-to-date, and no byte-compiled files have gone
|
|
stale.
|
|
|
|
OPTIONS:
|
|
-j, --jobs
|
|
Defaults to the maximum number of threads (or 1, if your CPU's threadcount
|
|
can't be determined).
|
|
--aot
|
|
Will only perform AOT native-compilation for packages updated/installed
|
|
during the execution of this command. Use --rebuild as well to do so for all
|
|
packages."
|
|
:benchmark t
|
|
(when (doom-profiles-bootloadable-p)
|
|
(call! '(profiles sync "--reload")))
|
|
(when aot?
|
|
(after! straight
|
|
(setq straight--native-comp-available t)))
|
|
(when jobs
|
|
(setq native-comp-async-jobs-number (truncate jobs)))
|
|
(run-hooks 'doom-before-sync-hook)
|
|
(add-hook 'kill-emacs-hook #'doom-sync--abort-warning-h)
|
|
(print! (item "Using Emacs %s @ %s") emacs-version (path invocation-directory invocation-name))
|
|
(print! (start "Synchronizing %S profile..." ) (or (car doom-profile) "default"))
|
|
(unwind-protect
|
|
(print-group!
|
|
;; If the user has up/downgraded Emacs since last sync, or copied their
|
|
;; config to a different system, then their packages need to be
|
|
;; recompiled. This is necessary because Emacs byte-code is not
|
|
;; necessarily back/forward compatible across major versions, and many
|
|
;; packages bake in hardcoded data at compile-time.
|
|
(pcase-let ((`(,old-version . ,hash)
|
|
(doom-file-read doom-cli-sync-info-file :by 'read :noerror t))
|
|
(to-rebuild nil))
|
|
(when (and old-version (not (equal old-version emacs-version)))
|
|
(print! (warn "Emacs version has changed since last sync (from %s to %s)") old-version emacs-version)
|
|
(setq to-rebuild t))
|
|
(when (and (stringp hash)
|
|
(not (equal hash (doom-sync--system-hash))))
|
|
(print! (warn "Your system has changed since last sync"))
|
|
(setq to-rebuild t))
|
|
(when (and to-rebuild (not rebuild?) (not (doom-cli-context-suppress-prompts-p context)))
|
|
(cond (nobuild?
|
|
(print! (warn "Packages must be rebuilt, but -B has prevented it. Skipping...")))
|
|
((doom-cli-context-get context 'upgrading)
|
|
(print! (warn "Packages will be rebuilt"))
|
|
(setq rebuild? t))
|
|
((y-or-n-p (format! " %s" "Installed packages must be rebuilt. Do so now?"))
|
|
(setq rebuild? t))
|
|
((exit! 0)))))
|
|
(when (and (not noenvvar?)
|
|
(file-exists-p doom-env-file))
|
|
(call! '(env)))
|
|
(doom-packages-ensure rebuild?)
|
|
(unless noupdate? (doom-packages-update (not update?)))
|
|
(doom-packages-purge purge? purge? purge? purge? purge?)
|
|
(when (doom-profile-generate)
|
|
(print! (item "Restart Emacs or use 'M-x doom/reload' for changes to take effect"))
|
|
(run-hooks 'doom-after-sync-hook))
|
|
(when (or rebuild? (not (file-exists-p doom-cli-sync-info-file)))
|
|
(with-temp-file doom-cli-sync-info-file
|
|
(prin1 (cons emacs-version (doom-sync--system-hash))
|
|
(current-buffer))))
|
|
t)
|
|
(remove-hook 'kill-emacs-hook #'doom-sync--abort-warning-h)))
|
|
|
|
|
|
;;
|
|
;;; Helpers
|
|
|
|
(defun doom-sync--system-hash ()
|
|
(secure-hash
|
|
'md5 (mapconcat #'identity (list doom-local-dir system-configuration))))
|
|
|
|
(defun doom-sync--abort-warning-h ()
|
|
(print! (warn "Script was abruptly aborted, leaving Doom in an incomplete state!"))
|
|
(print! (item "Run 'doom sync' to repair it.")))
|
|
|
|
(provide 'doom-cli-sync)
|
|
;;; sync.el ends here
|