Refactor package management API

Sets out to solve a number of issues with the package management
process. Namely:

- To-be-removed packages that are simply being removed are no longer
  incorrectly labeled "quelpa->elpa", but "removed" instead.
- A backend (elpa vs quelpa) column was added to the package listing
  confirmation when running `doom update`.
- Doom now correctly recognizes that packages installed with a psuedonym
  are installed, and will not endlessly attempt to uninstall and
  reinstall them on every `doom refresh`.
- Packages declared with :built-in will no longer lose their built-in
  marking if said package is not actually present in Emacs' site load
  paths. i.e. if you say it's built in, Doom won't question it.
- package!'s :ignore property is now treated as a form whose evaluated
  result will be used as its value.
This commit is contained in:
Henrik Lissner 2019-06-11 08:01:42 +02:00
parent b3c27ebe60
commit 6641e26283
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
4 changed files with 272 additions and 162 deletions

View file

@ -370,7 +370,7 @@
(load packages-file 'noerror 'nomessage) (load packages-file 'noerror 'nomessage)
(mapcar #'car doom-packages)) (mapcar #'car doom-packages))
unless (or (doom-package-prop name :disable) unless (or (doom-package-prop name :disable)
(doom-package-prop name :ignore t) (eval (doom-package-prop name :ignore))
(package-built-in-p name) (package-built-in-p name)
(package-installed-p name)) (package-installed-p name))
do (error! "%s is not installed" name)) do (error! "%s is not installed" name))

View file

@ -1,11 +1,12 @@
;;; core/autoload/packages.el -*- lexical-binding: t; -*- ;;; core/autoload/packages.el -*- lexical-binding: t; -*-
(load! "cache") (require 'core-packages)
(load! "cache") ; in case autoloads haven't been generated yet
;;; Private functions
(defun doom--packages-choose (prompt) (defun doom--packages-choose (prompt)
(let ((table (cl-loop for pkg in package-alist (let ((table (cl-loop for pkg in package-alist
unless (package-built-in-p (cdr pkg)) unless (doom-package-built-in-p (cdr pkg))
collect (cons (package-desc-full-name (cdr pkg)) collect (cons (package-desc-full-name (cdr pkg))
(cdr pkg))))) (cdr pkg)))))
(cdr (assoc (completing-read prompt (cdr (assoc (completing-read prompt
@ -18,10 +19,6 @@
(setq doom--refreshed-p nil) (setq doom--refreshed-p nil)
(doom-cache-set 'last-pkg-refresh nil)) (doom-cache-set 'last-pkg-refresh nil))
;;
;; Library
;;;###autoload ;;;###autoload
(defun doom-refresh-packages-maybe (&optional force-p) (defun doom-refresh-packages-maybe (&optional force-p)
"Refresh ELPA packages, if it hasn't been refreshed recently." "Refresh ELPA packages, if it hasn't been refreshed recently."
@ -38,36 +35,185 @@
(doom--refresh-pkg-cache) (doom--refresh-pkg-cache)
(signal 'doom-error e))))) (signal 'doom-error e)))))
;;;###autoload
(defun doom-package-backend (name &optional noerror) ;;
"Get which backend the package NAME was installed with. Can either be elpa, ;;; Package metadata
quelpa or emacs (built-in). Throws an error if NOERROR is nil and the package
isn't installed."
(cl-check-type name symbol)
(cond ((assq name quelpa-cache) 'quelpa)
((assq name package-alist) 'elpa)
((package-built-in-p name) 'emacs)
((not noerror) (error "%s package is not installed" name))))
;;;###autoload ;;;###autoload
(defun doom-package-outdated-p (name) (defun doom-package-plist (package)
"Determine whether NAME (a symbol) is outdated or not. If outdated, returns a "Returns PACKAGE's `package!' recipe from `doom-packages'."
list, whose car is NAME, and cdr the current version list and latest version (cdr (assq package doom-packages)))
list of the package."
;;;###autoload
(defun doom-package-desc (package)
"Returns PACKAGE's desc struct from `package-alist'."
(cadr (assq (or (car (doom-package-prop package :recipe))
package)
package-alist)))
;;;###autoload
(defun doom-package-true-name (package)
"Return PACKAGE's true name.
It is possible for quelpa packages to be given a psuedonym (the first argument
of `package!'). Its real name is the car of package's :recipe. e.g.
(package! X :recipe (Y :fetcher github :repo \"abc/def\"))
X's real name is Y."
(let ((sym (car (doom-package-prop package :recipe))))
(or (and (symbolp sym)
(not (keywordp sym))
sym)
package)))
;;;###autoload
(defun doom-package-psuedo-name (package)
"TODO"
(or (cl-loop for (package . plist) in doom-packages
for recipe-name = (car (plist-get plist :recipe))
if (eq recipe-name package)
return recipe-name)
package))
;;;###autoload
(defun doom-package-backend (package &optional noerror)
"Return backend that PACKAGE was installed with.
Can either be elpa, quelpa or emacs (built-in). Throws an error if NOERROR is
nil and the package isn't installed.
See `doom-package-recipe-backend' to get the backend PACKAGE is registered with
\(as opposed to what it is was installed with)."
(cl-check-type package symbol)
(let ((package-truename (doom-package-true-name package)))
(cond ((assq package-truename quelpa-cache) 'quelpa)
((assq package-truename package-alist) 'elpa)
((doom-package-built-in-p package) 'emacs)
((not noerror) (error "%s package is not installed" package)))))
;;;###autoload
(defun doom-package-recipe-backend (package &optional noerror)
"Return backend that PACKAGE is registered with.
See `doom-package-backend' to get backend for currently installed package."
(cl-check-type package symbol)
(cond ((not (doom-package-registered-p package))
(unless noerror
(error "%s package is not registered" package)))
((eval (doom-package-prop package :built-in))
'emacs)
((doom-package-prop package :recipe)
'quelpa)
('elpa)))
;;;###autoload
(defun doom-package-prop (package prop &optional nil-value)
"Return PROPerty in PACKAGE's plist.
Otherwise returns NIL-VALUE if package isn't registered or PROP doesn't
exist/isn't specified."
(cl-check-type package symbol)
(cl-check-type prop keyword)
(if-let (plist (doom-package-plist package))
(if (plist-member plist prop)
(plist-get plist prop)
nil-value)
nil-value))
;;
;;; Predicate functions
;;;###autoload
(defun doom-package-built-in-p (package)
"Return non-nil if PACKAGE (a symbol) is built-in."
(unless (doom-package-installed-p package)
(or (package-built-in-p (doom-package-true-name package))
(locate-library (symbol-name package) nil doom-site-load-path))))
;;;###autoload
(defun doom-package-installed-p (package)
"Return non-nil if PACKAGE (a symbol) is installed."
(when-let (desc (doom-package-desc package))
(and (package-installed-p desc)
(file-directory-p (package-desc-dir desc)))))
;;;###autoload
(defun doom-package-registered-p (package)
"Return non-nil if PACKAGE (a symbol) has been registered with `package!'.
Excludes packages that have a non-nil :built-in property."
(let ((package (or (cl-loop for (pkg . plist) in doom-packages
for newname = (car (plist-get plist :recipe))
if (and (symbolp newname)
(eq newname package))
return pkg)
package)))
(when-let (plist (doom-package-plist package))
(not (eval (plist-get plist :ignore))))))
;;;###autoload
(defun doom-package-private-p (package)
"Return non-nil if PACKAGE was installed by the user's private config."
(doom-package-prop package :private))
;;;###autoload
(defun doom-package-protected-p (package)
"Return non-nil if PACKAGE is protected.
A protected package cannot be deleted and will be auto-installed if missing."
(memq (doom-package-true-name package) doom-core-packages))
;;;###autoload
(defun doom-package-core-p (package)
"Return non-nil if PACKAGE is a core Doom package."
(or (doom-package-protected-p package)
(assq :core (doom-package-prop package :modules))))
;;;###autoload
(defun doom-package-different-backend-p (package)
"Return t if a PACKAGE (a symbol) has a new backend than what it was installed
with. Returns nil otherwise, or if package isn't installed."
(cl-check-type package symbol)
(and (doom-package-installed-p package)
(not (doom-get-depending-on package)) ; not a dependency
(not (eq (doom-package-backend package 'noerror)
(doom-package-recipe-backend package 'noerror)))))
;;;###autoload
(defun doom-package-different-recipe-p (name)
"Return t if a package named NAME (a symbol) has a different recipe than it
was installed with."
(cl-check-type name symbol) (cl-check-type name symbol)
(when-let* ((desc (cadr (assq name package-alist)))) (when (doom-package-installed-p name)
(let ((package-truename (doom-package-true-name name)))
(when-let* ((quelpa-recipe (assq package-truename quelpa-cache))
(doom-recipe (assq package-truename doom-packages)))
(not (equal (cdr quelpa-recipe)
(cdr (plist-get (cdr doom-recipe) :recipe))))))))
(defvar quelpa-upgrade-p)
;;;###autoload
(defun doom-package-outdated-p (name)
"Determine whether NAME (a symbol) is outdated or not.
If outdated, returns a list, whose car is NAME, and cdr the current version list
and latest version list of the package."
(cl-check-type name symbol)
(when-let (desc (doom-package-desc name))
(let* ((old-version (package-desc-version desc)) (let* ((old-version (package-desc-version desc))
(new-version (new-version
(pcase (doom-package-backend name) (pcase (doom-package-backend name)
('quelpa (`quelpa
(let ((recipe (plist-get (cdr (assq name doom-packages)) :recipe)) (let ((recipe (doom-package-prop name :recipe))
(dir (expand-file-name (symbol-name name) quelpa-build-dir)) (dir (expand-file-name (symbol-name name) quelpa-build-dir))
(inhibit-message (not doom-debug-mode)) (inhibit-message (not doom-debug-mode))
(quelpa-upgrade-p t)) (quelpa-upgrade-p t))
(if-let* ((ver (quelpa-checkout recipe dir))) (if-let (ver (quelpa-checkout recipe dir))
(version-to-list ver) (version-to-list ver)
old-version))) old-version)))
('elpa (`elpa
(let ((desc (cadr (assq name package-archive-contents)))) (let ((desc (cadr (assq name package-archive-contents))))
(when (package-desc-p desc) (when (package-desc-p desc)
(package-desc-version desc))))))) (package-desc-version desc)))))))
@ -76,43 +222,9 @@ list of the package."
(when (version-list-< old-version new-version) (when (version-list-< old-version new-version)
(list name old-version new-version))))) (list name old-version new-version)))))
;;;###autoload
(defun doom-package-installed-p (name)
"TODO"
(and (package-installed-p name)
(when-let* ((desc (cadr (assq name package-alist))))
(let ((dir (package-desc-dir desc)))
(file-directory-p dir)))))
;;;###autoload ;;
(defun doom-package-prop (name prop &optional eval) ;;; Package list getters
"Return PROPerty in NAME's plist."
(cl-check-type name symbol)
(cl-check-type prop keyword)
(let ((value (plist-get (cdr (assq name doom-packages)) prop)))
(if eval (eval value) value)))
;;;###autoload
(defun doom-package-different-backend-p (name)
"Return t if a package named NAME (a symbol) has a new backend than what it
was installed with. Returns nil otherwise, or if package isn't installed."
(cl-check-type name symbol)
(and (package-installed-p name)
(let* ((plist (cdr (assq name doom-packages)))
(old-backend (doom-package-backend name 'noerror))
(new-backend (if (plist-get plist :recipe) 'quelpa 'elpa)))
(not (eq old-backend new-backend)))))
;;;###autoload
(defun doom-package-different-recipe-p (name)
"Return t if a package named NAME (a symbol) has a different recipe than it
was installed with."
(cl-check-type name symbol)
(and (package-installed-p name)
(when-let* ((quelpa-recipe (assq name quelpa-cache))
(doom-recipe (assq name doom-packages)))
(not (equal (cdr quelpa-recipe)
(cdr (plist-get (cdr doom-recipe) :recipe)))))))
;;;###autoload ;;;###autoload
(cl-defun doom-find-packages (&key (installed 'any) (cl-defun doom-find-packages (&key (installed 'any)
@ -121,8 +233,7 @@ was installed with."
(pinned 'any) (pinned 'any)
(ignored 'any) (ignored 'any)
(core 'any) (core 'any)
sort _changed
changed
backend backend
deps) deps)
"Retrieves a list of primary packages (i.e. non-dependencies). Each element is "Retrieves a list of primary packages (i.e. non-dependencies). Each element is
@ -156,54 +267,49 @@ properties:
:deps BOOL :deps BOOL
Includes the package's dependencies (t) or not (nil). Includes the package's dependencies (t) or not (nil).
The resulting list is sorted unless :sort nil is passed to this function.
Warning: this function is expensive, as it re-evaluates your all packages.el Warning: this function is expensive, as it re-evaluates your all packages.el
files." files."
(cl-loop with packages = doom-packages (delete-dups
for (sym . plist) (cl-loop for (sym . plist) in doom-packages
in (if sort if (and (or (not backend)
(cl-sort (copy-sequence doom-packages) #'string-lessp :key #'car) (eq (doom-package-backend sym 'noerror) backend))
packages) (or (eq ignored 'any)
if (and (or (not backend) (let* ((form (plist-get plist :ignore))
(eq (doom-package-backend sym t) backend)) (value (eval form)))
(or (eq ignored 'any) (if ignored value (not value))))
(let* ((form (plist-get plist :ignore)) (or (eq disabled 'any)
(value (eval form))) (if disabled
(if ignored value (not value)))) (plist-get plist :disable)
(or (eq disabled 'any) (not (plist-get plist :disable))))
(if disabled (or (eq installed 'any)
(plist-get plist :disable) (if installed
(not (plist-get plist :disable)))) (doom-package-installed-p sym)
(or (eq installed 'any) (not (doom-package-installed-p sym))))
(if installed (or (eq private 'any)
(doom-package-installed-p sym) (let ((modules (plist-get plist :modules)))
(not (doom-package-installed-p sym)))) (if private
(or (eq private 'any) (assq :private modules)
(let ((modules (plist-get plist :modules))) (not (assq :private modules)))))
(if private (or (eq core 'any)
(assq :private modules) (let ((modules (plist-get plist :modules)))
(not (assq :private modules))))) (if core
(or (eq core 'any) (assq :core modules)
(let ((modules (plist-get plist :modules))) (not (assq :core modules)))))
(if core (or (eq pinned 'any)
(assq :core modules) (cond ((eq pinned 't)
(not (assq :core modules))))) (plist-get plist :pin))
(or (eq pinned 'any) ((null pinned)
(cond ((eq pinned 't) (not (plist-get plist :pin)))
(plist-get plist :pin)) ((equal (plist-get plist :pin) pinned)))))
((null pinned) collect (cons sym plist)
(not (plist-get plist :pin))) and if (and deps (not (doom-package-built-in-p sym)))
((equal (plist-get plist :pin) pinned))))) nconc
collect (cons sym plist) (cl-loop for pkg in (doom-get-dependencies-for sym 'recursive 'noerror)
and if (and deps (not (package-built-in-p sym))) if (or (eq installed 'any)
nconc (if installed
(cl-loop for pkg in (doom-get-dependencies-for sym 'recursive 'noerror) (doom-package-installed-p pkg)
if (or (eq installed 'any) (not (doom-package-installed-p pkg))))
(if installed collect (cons pkg (cdr (assq pkg doom-packages)))))))
(doom-package-installed-p pkg)
(not (doom-package-installed-p pkg))))
collect (cons pkg (cdr (assq pkg doom-packages))))))
(defun doom--read-module-packages-file (file &optional raw noerror) (defun doom--read-module-packages-file (file &optional raw noerror)
(with-temp-buffer ; prevent buffer-local settings from propagating (with-temp-buffer ; prevent buffer-local settings from propagating
@ -284,8 +390,9 @@ objects, in the order of their `package! blocks.'"
(defun doom-get-depending-on (name &optional noerror) (defun doom-get-depending-on (name &optional noerror)
"Return a list of packages that depend on the package named NAME." "Return a list of packages that depend on the package named NAME."
(cl-check-type name symbol) (cl-check-type name symbol)
(unless (package-built-in-p name) (setq name (or (car (doom-package-prop name :recipe)) name))
(if-let* ((desc (cadr (assq name package-alist)))) (unless (doom-package-built-in-p name)
(if-let (desc (cadr (assq name package-alist)))
(mapcar #'package-desc-name (package--used-elsewhere-p desc nil t)) (mapcar #'package-desc-name (package--used-elsewhere-p desc nil t))
(unless noerror (unless noerror
(error "Couldn't find %s, is it installed?" name))))) (error "Couldn't find %s, is it installed?" name)))))
@ -295,10 +402,10 @@ objects, in the order of their `package! blocks.'"
"Return a list of dependencies for a package." "Return a list of dependencies for a package."
(cl-check-type name symbol) (cl-check-type name symbol)
;; can't get dependencies for built-in packages ;; can't get dependencies for built-in packages
(unless (package-built-in-p name) (unless (doom-package-built-in-p name)
(if-let* ((desc (cadr (assq name package-alist)))) (if-let (desc (doom-package-desc name))
(let* ((deps (mapcar #'car (package-desc-reqs desc))) (let* ((deps (mapcar #'car (package-desc-reqs desc)))
(deps (cl-remove-if #'package-built-in-p deps))) (deps (cl-remove-if #'doom-package-built-in-p deps)))
(if recursive (if recursive
(nconc deps (mapcan (lambda (dep) (doom-get-dependencies-for dep t t)) (nconc deps (mapcan (lambda (dep) (doom-get-dependencies-for dep t t))
deps)) deps))
@ -316,9 +423,9 @@ If INCLUDE-FROZEN-P is non-nil, check frozen packages as well.
Used by `doom-packages-update'." Used by `doom-packages-update'."
(doom-refresh-packages-maybe doom-debug-mode) (doom-refresh-packages-maybe doom-debug-mode)
(cl-loop for package in (mapcar #'car package-alist) (cl-loop for package in (mapcar #'car package-alist)
when (and (or (not (doom-package-prop package :freeze 'eval)) when (and (or (not (eval (doom-package-prop package :freeze)))
include-frozen-p) include-frozen-p)
(not (doom-package-prop package :ignore 'eval)) (not (eval (doom-package-prop package :ignore)))
(not (doom-package-different-backend-p package)) (not (doom-package-different-backend-p package))
(doom-package-outdated-p package)) (doom-package-outdated-p package))
collect it)) collect it))
@ -331,10 +438,10 @@ depended on.
Used by `doom-packages-autoremove'." Used by `doom-packages-autoremove'."
(let ((package-selected-packages (let ((package-selected-packages
(mapcar #'car (doom-find-packages :ignored nil :disabled nil)))) (mapcar #'car (doom-find-packages :ignored nil :disabled nil))))
(append (package--removable-packages) (append (cl-remove-if #'doom-package-registered-p (package--removable-packages))
(cl-loop for pkg in package-selected-packages (cl-loop for pkg in package-selected-packages
if (and (doom-package-different-backend-p pkg) if (and (doom-package-different-backend-p pkg)
(not (package-built-in-p pkg))) (not (doom-package-built-in-p pkg)))
collect pkg)))) collect pkg))))
;;;###autoload ;;;###autoload
@ -349,8 +456,10 @@ Used by `doom-packages-install'."
in (doom-find-packages :ignored nil in (doom-find-packages :ignored nil
:disabled nil :disabled nil
:deps t) :deps t)
if (and (or (plist-get plist :pin) if (and (equal (plist-get plist :pin)
(not (package-built-in-p name))) (ignore-errors
(package-desc-archive
(cadr (assq name package-alist)))))
(or (not (doom-package-installed-p name)) (or (not (doom-package-installed-p name))
(doom-package-different-backend-p name) (doom-package-different-backend-p name)
(doom-package-different-recipe-p name))) (doom-package-different-recipe-p name)))
@ -373,15 +482,15 @@ Used by `doom-packages-install'."
"Installs package NAME with optional quelpa RECIPE (see `quelpa-recipe' for an "Installs package NAME with optional quelpa RECIPE (see `quelpa-recipe' for an
example; the package name can be omitted)." example; the package name can be omitted)."
(cl-check-type name symbol) (cl-check-type name symbol)
(when (and (package-installed-p name) (when (and (doom-package-installed-p name)
(not (package-built-in-p name))) (not (doom-package-built-in-p name)))
(if (or (doom-package-different-backend-p name) (if (or (doom-package-different-backend-p name)
(doom-package-different-recipe-p name)) (doom-package-different-recipe-p name))
(doom-delete-package name t) (doom-delete-package name t)
(user-error "%s is already installed" name))) (user-error "%s is already installed" name)))
(let* ((inhibit-message (not doom-debug-mode)) (let* ((inhibit-message (not doom-debug-mode))
(plist (or plist (cdr (assq name doom-packages))))) (plist (or plist (doom-package-plist name))))
(if-let* ((recipe (plist-get plist :recipe))) (if-let (recipe (plist-get plist :recipe))
(condition-case e (condition-case e
(let (quelpa-upgrade-p) (let (quelpa-upgrade-p)
(quelpa recipe)) (quelpa recipe))
@ -389,7 +498,7 @@ example; the package name can be omitted)."
(doom--delete-package-files name) (doom--delete-package-files name)
(signal (car e) (cdr e)))) (signal (car e) (cdr e))))
(package-install name)) (package-install name))
(if (not (package-installed-p name)) (if (not (doom-package-installed-p name))
(doom--delete-package-files name) (doom--delete-package-files name)
(add-to-list 'package-selected-packages name nil 'eq) (add-to-list 'package-selected-packages name nil 'eq)
(setf (alist-get name doom-packages) plist) (setf (alist-get name doom-packages) plist)
@ -400,21 +509,22 @@ example; the package name can be omitted)."
"Updates package NAME (a symbol) if it is out of date, using quelpa or "Updates package NAME (a symbol) if it is out of date, using quelpa or
package.el as appropriate." package.el as appropriate."
(cl-check-type name symbol) (cl-check-type name symbol)
(unless (package-installed-p name) (unless (doom-package-installed-p name)
(error "%s isn't installed" name)) (error "%s isn't installed" name))
(when (doom-package-different-backend-p name) (when (doom-package-different-backend-p name)
(user-error "%s's backend has changed and must be uninstalled first" name)) (user-error "%s's backend has changed and must be uninstalled first" name))
(when (or force-p (doom-package-outdated-p name)) (when (or force-p (doom-package-outdated-p name))
(let ((inhibit-message (not doom-debug-mode)) (let ((inhibit-message (not doom-debug-mode))
(desc (cadr (assq name package-alist)))) (desc (doom-package-desc name)))
(pcase (doom-package-backend name) (pcase (doom-package-backend name)
(`quelpa (`quelpa
(condition-case e (let ((name (doom-package-true-name name)))
(let ((quelpa-upgrade-p t)) (condition-case e
(quelpa (assq name quelpa-cache))) (let ((quelpa-upgrade-p t))
((debug error) (quelpa (assq name quelpa-cache)))
(doom--delete-package-files name) ((debug error)
(signal (car e) (cdr e))))) (doom--delete-package-files name)
(signal (car e) (cdr e))))))
(`elpa (`elpa
(let* ((archive (cadr (assq name package-archive-contents))) (let* ((archive (cadr (assq name package-archive-contents)))
(packages (packages
@ -430,18 +540,16 @@ package.el as appropriate."
(defun doom-delete-package (name &optional force-p) (defun doom-delete-package (name &optional force-p)
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'." "Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
(cl-check-type name symbol) (cl-check-type name symbol)
(unless (package-installed-p name) (unless (doom-package-installed-p name)
(user-error "%s isn't installed" name)) (user-error "%s isn't installed" name))
(let ((inhibit-message (not doom-debug-mode)) (let ((inhibit-message (not doom-debug-mode))
(spec (assq name quelpa-cache)) (name (doom-package-true-name name)))
quelpa-p) (when-let (spec (assq name quelpa-cache))
(when spec (delq! spec quelpa-cache)
(setq quelpa-cache (delq spec quelpa-cache)) (quelpa-save-cache))
(quelpa-save-cache) (package-delete (doom-package-desc name) force-p)
(setq quelpa-p t))
(package-delete (cadr (assq name package-alist)) force-p)
(doom--delete-package-files name) (doom--delete-package-files name)
(not (package-installed-p name)))) (not (doom-package-installed-p name))))
;; ;;
@ -473,7 +581,7 @@ calls."
(user-error "'%s' is already up-to-date" selection)) (user-error "'%s' is already up-to-date" selection))
(list (assq name packages)))) (list (assq name packages))))
(cl-destructuring-bind (package old-version new-version) pkg (cl-destructuring-bind (package old-version new-version) pkg
(if-let* ((desc (doom-package-outdated-p package))) (if-let (desc (doom-package-outdated-p package))
(let ((old-v-str (package-version-join old-version)) (let ((old-v-str (package-version-join old-version))
(new-v-str (package-version-join new-version))) (new-v-str (package-version-join new-version)))
(if (y-or-n-p (format "%s will be updated from %s to %s. Update?" (if (y-or-n-p (format "%s will be updated from %s to %s. Update?"
@ -492,8 +600,8 @@ calls."
(defun doom*package-delete (desc &rest _) (defun doom*package-delete (desc &rest _)
"Update `quelpa-cache' upon a successful `package-delete'." "Update `quelpa-cache' upon a successful `package-delete'."
(let ((name (package-desc-name desc))) (let ((name (package-desc-name desc)))
(unless (package-installed-p name) (unless (doom-package-installed-p name)
(when-let* ((spec (assq name quelpa-cache))) (when-let (spec (assq name quelpa-cache))
(setq quelpa-cache (delq spec quelpa-cache)) (setq quelpa-cache (delq spec quelpa-cache))
(quelpa-save-cache) (quelpa-save-cache)
(doom--delete-package-files name))))) (doom--delete-package-files name)))))

View file

@ -55,12 +55,12 @@
(cond ((doom-package-different-recipe-p (car pkg)) (cond ((doom-package-different-recipe-p (car pkg))
"new recipe") "new recipe")
((doom-package-different-backend-p (car pkg)) ((doom-package-different-backend-p (car pkg))
(if (plist-get (cdr pkg) :recipe) (format "%s -> %s"
"ELPA->QUELPA" (doom-package-backend (car pkg) 'noerror)
"QUELPA->ELPA")) (doom-package-recipe-backend (car pkg) 'noerror)))
((plist-get (cdr pkg) :recipe) ((plist-get (cdr pkg) :recipe)
"QUELPA") "quelpa")
("ELPA")))) ("elpa"))))
(cl-sort (cl-copy-list packages) #'string-lessp (cl-sort (cl-copy-list packages) #'string-lessp
:key #'car) :key #'car)
"\n"))))) "\n")))))
@ -114,8 +114,10 @@
10))) 10)))
(mapconcat (mapconcat
(lambda (pkg) (lambda (pkg)
(format (format "+ %%-%ds %%-%ds -> %%s" (+ max-len 2) 14) (format (format "+ %%-%ds (%%s) %%-%ds -> %%s"
(+ max-len 2) 14)
(symbol-name (car pkg)) (symbol-name (car pkg))
(doom-package-backend (car pkg))
(package-version-join (cadr pkg)) (package-version-join (cadr pkg))
(package-version-join (cl-caddr pkg)))) (package-version-join (cl-caddr pkg))))
packages packages
@ -152,14 +154,14 @@
(length packages) (length packages)
(mapconcat (mapconcat
(lambda (sym) (lambda (sym)
(let ((backend (doom-package-backend sym))) (let ((old-backend (doom-package-backend sym 'noerror))
(new-backend (doom-package-recipe-backend sym 'noerror)))
(format "+ %s (%s)" sym (format "+ %s (%s)" sym
(if (doom-package-different-backend-p sym) (cond ((null new-backend)
(pcase backend "removed")
(`quelpa "QUELPA->ELPA") ((eq old-backend new-backend)
(`elpa "ELPA->QUELPA") (symbol-name new-backend))
(_ "removed")) ((format "%s -> %s" old-backend new-backend))))))
(upcase (symbol-name backend))))))
(sort (cl-copy-list packages) #'string-lessp) (sort (cl-copy-list packages) #'string-lessp)
"\n"))))) "\n")))))
(user-error "Aborted!")) (user-error "Aborted!"))

View file

@ -197,9 +197,9 @@ elsewhere."
(unless (member module module-list) (unless (member module module-list)
(setq module-list (append module-list (list module) nil) (setq module-list (append module-list (list module) nil)
plist (plist-put plist :modules module-list)))) plist (plist-put plist :modules module-list))))
(when (and built-in (locate-library (symbol-name name) nil doom-site-load-path)) (when built-in
(doom-log "Ignoring built-in package '%s'" name) (doom-log "Ignoring built-in package '%s'" name)
(setq plist (plist-put plist :ignore t))) (setq plist (plist-put plist :ignore built-in)))
(while plist (while plist
(unless (null (cadr plist)) (unless (null (cadr plist))
(setq old-plist (plist-put old-plist (car plist) (cadr plist)))) (setq old-plist (plist-put old-plist (car plist) (cadr plist))))