Fix and refactor 'doom upgrade' #1607
Now accepts the -f/--force switches to discard local changes to the .emacs.d directory.
This commit is contained in:
parent
26f9e2cdeb
commit
a9c1986a68
1 changed files with 79 additions and 66 deletions
|
@ -1,88 +1,101 @@
|
||||||
;;; core/cli/upgrade.el -*- lexical-binding: t; -*-
|
;;; core/cli/upgrade.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(defcli! (upgrade up) ()
|
(defcli! (upgrade up) (&rest args)
|
||||||
"Updates Doom and packages.
|
"Updates Doom and packages.
|
||||||
|
|
||||||
This requires that ~/.emacs.d is a git repo, and is the equivalent of the
|
This requires that ~/.emacs.d is a git repo, and is the equivalent of the
|
||||||
following shell commands:
|
following shell commands:
|
||||||
|
|
||||||
cd ~/.emacs.d
|
cd ~/.emacs.d
|
||||||
git pull
|
git pull --rebase
|
||||||
bin/doom clean
|
bin/doom clean
|
||||||
bin/doom refresh
|
bin/doom refresh
|
||||||
bin/doom update"
|
bin/doom update"
|
||||||
(doom-upgrade))
|
(doom-upgrade (or (member "-f" args)
|
||||||
|
(member "--force" args))))
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Quality of Life Commands
|
;;; Library
|
||||||
|
|
||||||
(defvar doom-repo-url "https://github.com/hlissner/doom-emacs"
|
(defvar doom-repo-url "https://github.com/hlissner/doom-emacs"
|
||||||
"TODO")
|
"The git repo url for Doom Emacs.")
|
||||||
(defvar doom-repo-remote "_upgrade"
|
(defvar doom-repo-remote "_upgrade"
|
||||||
"TODO")
|
"The name to use as our staging remote.")
|
||||||
|
|
||||||
|
(defun doom--sh (command &rest args)
|
||||||
|
(let ((output (get-buffer-create "*doom-sh-output*")))
|
||||||
|
(unwind-protect
|
||||||
|
(cons (zerop (or (apply #'call-process command nil output nil args)
|
||||||
|
-1))
|
||||||
|
(with-current-buffer output
|
||||||
|
(string-trim (buffer-string))))
|
||||||
|
(kill-buffer output))))
|
||||||
|
|
||||||
(defun doom--working-tree-dirty-p (dir)
|
(defun doom--working-tree-dirty-p (dir)
|
||||||
(with-temp-buffer
|
(cl-destructuring-bind (code . stdout)
|
||||||
(let ((default-directory dir))
|
(doom--sh "git" "status" "--porcelain" "-uno")
|
||||||
(if (zerop (process-file "git" nil (current-buffer) nil
|
(if (zerop code)
|
||||||
"status" "--porcelain" "-uno"))
|
(string-match-p "[^ \t\n]" (buffer-string))
|
||||||
(string-match-p "[^ \t\n]" (buffer-string))
|
(error "Failed to check working tree in %s" dir))))
|
||||||
(error "Failed to check working tree in %s" dir)))))
|
|
||||||
|
|
||||||
(defun doom-upgrade ()
|
|
||||||
|
(defun doom-upgrade (&optional force-p)
|
||||||
"Upgrade Doom to the latest version non-destructively."
|
"Upgrade Doom to the latest version non-destructively."
|
||||||
(require 'vc-git)
|
(require 'vc-git)
|
||||||
(let* ((gitdir (expand-file-name ".git" doom-emacs-dir))
|
(let ((default-directory doom-emacs-dir)
|
||||||
(branch (vc-git--symbolic-ref doom-emacs-dir))
|
process-file-side-effects)
|
||||||
(default-directory doom-emacs-dir))
|
(print! (start "Preparing to upgrade Doom Emacs and its packages..."))
|
||||||
(unless (file-exists-p gitdir)
|
|
||||||
(error "Couldn't find %s. Was Doom cloned properly?"
|
(let ((branch (cdr (doom--sh "git" "symbolic-ref" "HEAD")))
|
||||||
(abbreviate-file-name gitdir)))
|
(target-remote (format "%s/%s" doom-repo-remote branch)))
|
||||||
(unless branch
|
(unless branch
|
||||||
(error "Couldn't detect what branch you're using. Is Doom detached?"))
|
(error! (if (file-exists-p! ".git" doom-emacs-dir)
|
||||||
(when (doom--working-tree-dirty-p doom-emacs-dir)
|
"Couldn't find Doom's .git directory. Was Doom cloned properly?"
|
||||||
(user-error "Refusing to upgrade because %S has been modified. Stash or undo your changes"
|
"Couldn't detect what branch you're on. Is Doom detached?")))
|
||||||
(abbreviate-file-name doom-emacs-dir)))
|
|
||||||
(with-temp-buffer
|
;; We assume that a dirty .emacs.d is intentional and abort
|
||||||
(let ((buf (current-buffer)))
|
(when (doom--working-tree-dirty-p default-directory)
|
||||||
(condition-case-unless-debug e
|
(if (not force-p)
|
||||||
(progn
|
(user-error! "%s\n\n%s"
|
||||||
(process-file "git" nil buf nil "remote" "remove" doom-repo-remote)
|
(format "Refusing to upgrade because %S has been modified." (path doom-emacs-dir))
|
||||||
(unless (zerop (process-file "git" nil buf nil "remote" "add"
|
"Either stash/undo your changes or run 'doom upgrade -f' to discard local changes.")
|
||||||
doom-repo-remote doom-repo-url))
|
(print! (info "You have local modifications in Doom's source. Discarding them..."))
|
||||||
(error "Failed to add %s to remotes" doom-repo-remote))
|
(doom--sh "git" "reset" "--hard" (format "origin/%s" branch))
|
||||||
(unless (zerop (process-file "git" nil buf nil "fetch" "--tags"
|
(doom--sh "git" "clean" "-ffd")))
|
||||||
doom-repo-remote branch))
|
|
||||||
(error "Failed to fetch from upstream"))
|
(doom--sh "git" "remote" "remove" doom-repo-remote)
|
||||||
(let ((current-rev (vc-git-working-revision doom-emacs-dir))
|
(or (car (doom--sh "git" "remote" "add" doom-repo-remote doom-repo-url))
|
||||||
(rev (string-trim (shell-command-to-string (format "git rev-parse %s/%s" doom-repo-remote branch)))))
|
(error "Failed to add %s to remotes" doom-repo-remote))
|
||||||
(unless rev
|
(or (car (doom--sh "git" "fetch" "--tags" doom-repo-remote branch))
|
||||||
(error "Couldn't detect Doom's version. Is %s a repo?"
|
(error "Failed to fetch from upstream"))
|
||||||
(abbreviate-file-name doom-emacs-dir)))
|
|
||||||
(if (equal current-rev rev)
|
(let ((this-rev (vc-git--rev-parse "HEAD"))
|
||||||
(message "Doom is up to date!")
|
(new-rev (vc-git--rev-parse target-remote)))
|
||||||
(message "Updates for Doom are available!\n\n Old revision: %s\n New revision: %s\n"
|
(if (equal this-rev new-rev)
|
||||||
current-rev rev)
|
(print! (success "Doom is already up-to-date!"))
|
||||||
(message "Comparision diff: https://github.com/hlissner/doom-emacs/compare/%s...%s\n"
|
(print! (info "Updates are available!\n\n Old revision: %s (%s)\n\n New revision: %s (%s)\n\n"
|
||||||
(substring current-rev 0 10) (substring rev 0 10))
|
(substring this-rev 0 10)
|
||||||
;; TODO Display newsletter diff
|
(cdr (doom--sh "git" "log" "-1" "--format=%cr" "HEAD"))
|
||||||
(unless (or doom-auto-accept (y-or-n-p "Proceed?"))
|
(substring new-rev 0 10)
|
||||||
(user-error "Aborted"))
|
(cdr (doom--sh "git" "log" "-1" "--format=%cr" target-remote))))
|
||||||
(message "Removing byte-compiled files from your config (if any)")
|
|
||||||
(doom-clean-byte-compiled-files)
|
(when (y-or-n-p "View the comparison diff in your browser?")
|
||||||
(unless (zerop (process-file "git" nil buf nil "reset" "--hard"
|
(print! (info "Opened github in your browser."))
|
||||||
(format "%s/%s" doom-repo-remote branch)))
|
(browse-url (format "https://github.com/hlissner/doom-emacs/compare/%s...%s"
|
||||||
(error "An error occurred while checking out the latest commit\n\n%s"
|
this-rev
|
||||||
(buffer-string)))
|
new-rev)))
|
||||||
(unless (equal (vc-git-working-revision doom-emacs-dir) rev)
|
(or (y-or-n-p "Proceed with upgrade?")
|
||||||
(error "Failed to checkout latest commit.\n\n%s" (buffer-string))))
|
(user-error "Aborted"))
|
||||||
(doom-cli-refresh 'force-p)
|
|
||||||
(when (doom-packages-update doom-auto-accept)
|
(print! (start "Upgrading Doom Emacs..."))
|
||||||
(doom-reload-package-autoloads))
|
(print-group!
|
||||||
(message "Done! Please restart Emacs for changes to take effect")))
|
(doom-clean-byte-compiled-files)
|
||||||
(user-error
|
(unless (and (car (doom--sh "git" "reset" "--hard" target-remote))
|
||||||
(message "%s Aborting." (error-message-string e)))
|
(equal (vc-git--rev-parse "HEAD") new-rev))
|
||||||
(error
|
(error "Failed to check out %s" (substring new-rev 0 10)))
|
||||||
(message "There was an unexpected error.\n\n%s\n\nOutput:\n%s"
|
(doom-delete-autoloads-file doom-autoload-file)
|
||||||
e (buffer-string))))))))
|
(doom-cli-refresh)
|
||||||
|
(when (doom-packages-update doom-auto-accept)
|
||||||
|
(doom-reload-package-autoloads 'force-p))
|
||||||
|
(print! (success "Done! Restart Emacs for changes to take effect."))))))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue