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:
parent
b3c27ebe60
commit
6641e26283
4 changed files with 272 additions and 162 deletions
|
@ -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))
|
||||||
|
|
|
@ -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)))))
|
||||||
|
|
|
@ -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!"))
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue