:ensure can be a list; correct handling of multiple :ensure keywords

Fixes https://github.com/jwiegley/use-package/issues/539
This commit is contained in:
John Wiegley 2017-12-04 11:26:19 -08:00
parent 101dc9793b
commit 01c3d75606
2 changed files with 71 additions and 53 deletions

View file

@ -33,6 +33,7 @@
;;; Code: ;;; Code:
(require 'cl-lib)
(require 'up-core) (require 'up-core)
(defgroup use-package-ensure nil (defgroup use-package-ensure nil
@ -58,9 +59,9 @@ See also `use-package-defaults', which uses this value."
(defcustom use-package-ensure-function 'use-package-ensure-elpa (defcustom use-package-ensure-function 'use-package-ensure-elpa
"Function that ensures a package is installed. "Function that ensures a package is installed.
This function is called with three arguments: the name of the This function is called with three arguments: the name of the
package declared in the `use-package' form; the argument passed package declared in the `use-package' form; the arguments passed
to `:ensure'; and the current `state' plist created by previous to all `:ensure' keywords (always a list, even if only one); and
handlers. the current `state' plist created by previous handlers.
Note that this function is called whenever `:ensure' is provided, Note that this function is called whenever `:ensure' is provided,
even if it is nil. It is up to the function to decide on the even if it is nil. It is up to the function to decide on the
@ -136,13 +137,18 @@ manually updated package."
t t
(use-package-only-one (symbol-name keyword) args (use-package-only-one (symbol-name keyword) args
#'(lambda (label arg) #'(lambda (label arg)
(if (symbolp arg) (cond
arg ((symbolp arg)
(list arg))
((and (listp arg) (cl-every #'symbolp arg))
arg)
(t
(use-package-error (use-package-error
(concat ":ensure wants an optional package name " (concat ":ensure wants an optional package name "
"(an unquoted symbol name)"))))))) "(an unquoted symbol name)"))))))))
(defun use-package-ensure-elpa (name ensure state &optional no-refresh) (defun use-package-ensure-elpa (name args state &optional no-refresh)
(dolist (ensure args)
(let ((package (let ((package
(or (and (eq ensure t) (use-package-as-symbol name)) (or (and (eq ensure t) (use-package-as-symbol name))
ensure))) ensure)))
@ -167,7 +173,7 @@ manually updated package."
(display-warning 'use-package (display-warning 'use-package
(format "Failed to install %s: %s" (format "Failed to install %s: %s"
name (error-message-string err)) name (error-message-string err))
:error)))))))) :error)))))))))
(defun use-package-handler/:ensure (name keyword ensure rest state) (defun use-package-handler/:ensure (name keyword ensure rest state)
(let* ((body (use-package-process-keywords name rest state))) (let* ((body (use-package-process-keywords name rest state)))
@ -184,7 +190,7 @@ manually updated package."
body)) body))
(add-to-list 'use-package-defaults (add-to-list 'use-package-defaults
'(:ensure use-package-always-ensure '(:ensure (list use-package-always-ensure)
(lambda (args) (lambda (args)
(and use-package-always-ensure (and use-package-always-ensure
(not (plist-member args :load-path))))) t) (not (plist-member args :load-path))))) t)

View file

@ -219,9 +219,9 @@
(flet ((norm (&rest args) (flet ((norm (&rest args)
(apply #'use-package-normalize/:ensure (apply #'use-package-normalize/:ensure
'foopkg :ensure args))) 'foopkg :ensure args)))
(should (equal (norm '(t)) t)) (should (equal (norm '(t)) '(t)))
(should (equal (norm '(nil)) nil)) (should (equal (norm '(nil)) '(nil)))
(should (equal (norm '(sym)) 'sym)) (should (equal (norm '(sym)) '(sym)))
(should-error (norm '(1))) (should-error (norm '(1)))
(should-error (norm '("Hello"))))) (should-error (norm '("Hello")))))
@ -230,7 +230,7 @@
(match-expansion (match-expansion
(use-package foo :ensure t) (use-package foo :ensure t)
`(progn `(progn
(use-package-ensure-elpa 'foo 't 'nil) (use-package-ensure-elpa 'foo '(t) 'nil)
(require 'foo nil nil))))) (require 'foo nil nil)))))
(ert-deftest use-package-test/:ensure-2 () (ert-deftest use-package-test/:ensure-2 ()
@ -238,7 +238,7 @@
(match-expansion (match-expansion
(use-package foo :ensure t) (use-package foo :ensure t)
`(progn `(progn
(use-package-ensure-elpa 'foo 't 'nil) (use-package-ensure-elpa 'foo '(t) 'nil)
(require 'foo nil nil))))) (require 'foo nil nil)))))
(ert-deftest use-package-test/:ensure-3 () (ert-deftest use-package-test/:ensure-3 ()
@ -246,7 +246,7 @@
(match-expansion (match-expansion
(use-package foo :ensure nil) (use-package foo :ensure nil)
`(progn `(progn
(use-package-ensure-elpa 'foo 'nil 'nil) (use-package-ensure-elpa 'foo '(nil) 'nil)
(require 'foo nil nil))))) (require 'foo nil nil)))))
(ert-deftest use-package-test/:ensure-4 () (ert-deftest use-package-test/:ensure-4 ()
@ -254,7 +254,7 @@
(match-expansion (match-expansion
(use-package foo :ensure nil) (use-package foo :ensure nil)
`(progn `(progn
(use-package-ensure-elpa 'foo 'nil 'nil) (use-package-ensure-elpa 'foo '(nil) 'nil)
(require 'foo nil nil))))) (require 'foo nil nil)))))
(ert-deftest use-package-test/:ensure-5 () (ert-deftest use-package-test/:ensure-5 ()
@ -280,7 +280,7 @@
(match-expansion (match-expansion
(use-package foo :ensure nil :load-path "foo") (use-package foo :ensure nil :load-path "foo")
`(progn `(progn
(use-package-ensure-elpa 'foo 'nil 'nil) (use-package-ensure-elpa 'foo '(nil) 'nil)
(eval-and-compile (eval-and-compile
(add-to-list 'load-path ,(pred stringp))) (add-to-list 'load-path ,(pred stringp)))
(require 'foo nil nil))))) (require 'foo nil nil)))))
@ -290,7 +290,7 @@
(match-expansion (match-expansion
(use-package foo :ensure nil :load-path "foo") (use-package foo :ensure nil :load-path "foo")
`(progn `(progn
(use-package-ensure-elpa 'foo 'nil 'nil) (use-package-ensure-elpa 'foo '(nil) 'nil)
(eval-and-compile (eval-and-compile
(add-to-list 'load-path ,(pred stringp))) (add-to-list 'load-path ,(pred stringp)))
(require 'foo nil nil))))) (require 'foo nil nil)))))
@ -300,7 +300,7 @@
(match-expansion (match-expansion
(use-package foo :ensure t :load-path "foo") (use-package foo :ensure t :load-path "foo")
`(progn `(progn
(use-package-ensure-elpa 'foo 't 'nil) (use-package-ensure-elpa 'foo '(t) 'nil)
(eval-and-compile (eval-and-compile
(add-to-list 'load-path ,(pred stringp))) (add-to-list 'load-path ,(pred stringp)))
(require 'foo nil nil))))) (require 'foo nil nil)))))
@ -310,7 +310,7 @@
(match-expansion (match-expansion
(use-package foo :ensure t :load-path "foo") (use-package foo :ensure t :load-path "foo")
`(progn `(progn
(use-package-ensure-elpa 'foo 't 'nil) (use-package-ensure-elpa 'foo '(t) 'nil)
(eval-and-compile (eval-and-compile
(add-to-list 'load-path ,(pred stringp))) (add-to-list 'load-path ,(pred stringp)))
(require 'foo nil nil))))) (require 'foo nil nil)))))
@ -325,6 +325,30 @@
(use-package foo :ensure t) (use-package foo :ensure t)
(should (eq tried-to-install 'foo))))) (should (eq tried-to-install 'foo)))))
(ert-deftest use-package-test/:ensure-12 ()
(let ((use-package-always-ensure t))
(match-expansion
(use-package foo :ensure bar)
`(progn
(use-package-ensure-elpa 'foo '(bar) 'nil)
(require 'foo nil nil)))))
(ert-deftest use-package-test/:ensure-13 ()
(let ((use-package-always-ensure t))
(match-expansion
(use-package foo :ensure bar :ensure quux)
`(progn
(use-package-ensure-elpa 'foo '(bar quux) 'nil)
(require 'foo nil nil)))))
(ert-deftest use-package-test/:ensure-14 ()
(let ((use-package-always-ensure t))
(match-expansion
(use-package foo :ensure bar :ensure (quux bow))
`(progn
(use-package-ensure-elpa 'foo '(bar quux bow) 'nil)
(require 'foo nil nil)))))
(ert-deftest use-package-test/:if-1 () (ert-deftest use-package-test/:if-1 ()
(match-expansion (match-expansion
(use-package foo :if t) (use-package foo :if t)
@ -1319,18 +1343,6 @@
(bind-keys :package mu4e (bind-keys :package mu4e
("<f9>" . mu4e)))))) ("<f9>" . mu4e))))))
(ert-deftest use-package-test/539 ()
(match-expansion
(use-package foo
:requires bar
:after quux
:ensure bow)
`(progn
(use-package-ensure-elpa 'foo 'bow 'nil)
(when (featurep 'bar)
(eval-after-load 'quux
'(require 'foo nil nil))))))
;; Local Variables: ;; Local Variables:
;; indent-tabs-mode: nil ;; indent-tabs-mode: nil
;; no-byte-compile: t ;; no-byte-compile: t