summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/package.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/package.el')
-rw-r--r--lisp/emacs-lisp/package.el112
1 files changed, 65 insertions, 47 deletions
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 8d5fac96cfb..4245294457f 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -194,14 +194,16 @@ If VERSION is nil, the package is not loaded (it is \"disabled\")."
:risky t
:version "24.1")
-(defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/"))
+(defcustom package-archives `(("gnu" .
+ ,(format "http%s://elpa.gnu.org/packages/"
+ (if (gnutls-available-p) "s" ""))))
"An alist of archives from which to fetch.
The default value points to the GNU Emacs package repository.
Each element has the form (ID . LOCATION).
ID is an archive name, as a string.
LOCATION specifies the base location for the archive.
- If it starts with \"http:\", it is treated as a HTTP URL;
+ If it starts with \"http(s):\", it is treated as an HTTP(S) URL;
otherwise it should be an absolute directory name.
(Other types of URL are currently not supported.)
@@ -210,7 +212,7 @@ a package can run arbitrary code."
:type '(alist :key-type (string :tag "Archive name")
:value-type (string :tag "URL or directory name"))
:risky t
- :version "24.1")
+ :version "26.1") ; gnutls test
(defcustom package-menu-hide-low-priority 'archive
"If non-nil, hide low priority packages from the packages menu.
@@ -305,6 +307,23 @@ contrast, `package-user-dir' contains packages for personal use."
(declare-function epg-find-configuration "epg-config"
(protocol &optional no-cache program-alist))
+(defcustom package-gnupghome-dir (expand-file-name "gnupg" package-user-dir)
+ "Directory containing GnuPG keyring or nil.
+This variable specifies the GnuPG home directory used by package.
+That directory is passed via the option \"--homedir\" to GnuPG.
+If nil, do not use the option \"--homedir\", but stick with GnuPG's
+default directory."
+ :type `(choice
+ (const
+ :tag "Default Emacs package management GnuPG home directory"
+ ,(expand-file-name "gnupg" package-user-dir))
+ (const
+ :tag "Default GnuPG directory (GnuPG option --homedir not used)"
+ nil)
+ (directory :tag "A specific GnuPG --homedir"))
+ :risky t
+ :version "26.1")
+
(defcustom package-check-signature
(if (and (require 'epg-config)
(epg-find-configuration 'OpenPGP))
@@ -619,7 +638,7 @@ Return the max version (as a string) if the package is held at a lower version."
(t (error "Invalid element in `package-load-list'")))))
(defun package-built-in-p (package &optional min-version)
- "Return true if PACKAGE is built-in to Emacs.
+ "Return non-nil if PACKAGE is built-in to Emacs.
Optional arg MIN-VERSION, if non-nil, should be a version list
specifying the minimum acceptable version."
(if (package-desc-p package) ;; was built-in and then was converted
@@ -886,25 +905,13 @@ untar into a directory named DIR; otherwise, signal an error."
nil pkg-file nil 'silent))))
;;;; Autoload
-;; From Emacs 22, but changed so it adds to load-path.
+(declare-function autoload-rubric "autoload" (file &optional type feature))
+
(defun package-autoload-ensure-default-file (file)
"Make sure that the autoload file FILE exists and if not create it."
(unless (file-exists-p file)
- (write-region
- (concat ";;; " (file-name-nondirectory file)
- " --- automatically extracted autoloads\n"
- ";;\n"
- ";;; Code:\n"
- ;; `load-path' should contain only directory names
- "(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))\n"
- " \n;; Local Variables:\n"
- ";; version-control: never\n"
- ";; no-byte-compile: t\n"
- ";; no-update-autoloads: t\n"
- ";; End:\n"
- ";;; " (file-name-nondirectory file)
- " ends here\n")
- nil file nil 'silent))
+ (require 'autoload)
+ (write-region (autoload-rubric file "package" nil) nil file nil 'silent))
file)
(defvar generated-autoload-file)
@@ -1207,9 +1214,9 @@ errors signaled by ERROR-FORM or by BODY).
"Check signature CONTENT against STRING.
SIG-FILE is the name of the signature file, used when signaling
errors."
- (let* ((context (epg-make-context 'OpenPGP))
- (homedir (expand-file-name "gnupg" package-user-dir)))
- (setf (epg-context-home-directory context) homedir)
+ (let ((context (epg-make-context 'OpenPGP)))
+ (when package-gnupghome-dir
+ (setf (epg-context-home-directory context) package-gnupghome-dir))
(condition-case error
(epg-verify-string context content string)
(error (package--display-verify-error context sig-file)
@@ -1236,7 +1243,7 @@ errors."
"Check signature of the current buffer.
Download the signature file from LOCATION by appending \".sig\"
to FILE.
-GnuPG keyring is located under \"gnupg\" in `package-user-dir'.
+GnuPG keyring location depends on `package-gnupghome-dir'.
STRING is the string to verify, it defaults to `buffer-string'.
If ASYNC is non-nil, the download of the signature file is
done asynchronously.
@@ -1476,11 +1483,11 @@ taken care of by `package-initialize'."
"Import keys from FILE."
(interactive "fFile: ")
(setq file (expand-file-name file))
- (let ((context (epg-make-context 'OpenPGP))
- (homedir (expand-file-name "gnupg" package-user-dir)))
- (with-file-modes 448
- (make-directory homedir t))
- (setf (epg-context-home-directory context) homedir)
+ (let ((context (epg-make-context 'OpenPGP)))
+ (when package-gnupghome-dir
+ (with-file-modes 448
+ (make-directory package-gnupghome-dir t))
+ (setf (epg-context-home-directory context) package-gnupghome-dir))
(message "Importing %s..." (file-name-nondirectory file))
(epg-import-keys-from-file context file)
(message "Importing %s...done" (file-name-nondirectory file))))
@@ -1522,7 +1529,7 @@ similar to an entry in `package-alist'. Save the cached copy to
(when (listp (read-from-string content))
(make-directory dir t)
(if (or (not package-check-signature)
- (member archive package-unsigned-archives))
+ (member name package-unsigned-archives))
;; If we don't care about the signature, save the file and
;; we're done.
(progn (write-region content nil local-file nil 'silent)
@@ -1769,7 +1776,7 @@ destructively set to nil in ONLY."
That is, any element of the returned list is guaranteed to not
directly depend on any elements that come before it.
-PACKAGE-LIST is a list of package-desc objects.
+PACKAGE-LIST is a list of `package-desc' objects.
Indirect dependencies are guaranteed to be returned in order only
if all the in-between dependencies are also in PACKAGE-LIST."
(let ((alist (mapcar (lambda (p) (cons (package-desc-name p) p)) package-list))
@@ -1838,11 +1845,11 @@ if all the in-between dependencies are also in PACKAGE-LIST."
(setf (package-desc-signed (car pkg-descs)) t))))))))))
(defun package-installed-p (package &optional min-version)
- "Return true if PACKAGE, of MIN-VERSION or newer, is installed.
+ "Return non-nil if PACKAGE, of MIN-VERSION or newer, is installed.
If PACKAGE is a symbol, it is the package name and MIN-VERSION
should be a version list.
-If PACKAGE is a package-desc object, MIN-VERSION is ignored."
+If PACKAGE is a `package-desc' object, MIN-VERSION is ignored."
(unless package--initialized (error "package.el is not yet initialized!"))
(if (package-desc-p package)
(let ((dir (package-desc-dir package)))
@@ -1858,7 +1865,7 @@ If PACKAGE is a package-desc object, MIN-VERSION is ignored."
(defun package-download-transaction (packages)
"Download and install all the packages in PACKAGES.
-PACKAGES should be a list of package-desc.
+PACKAGES should be a list of `package-desc'.
This function assumes that all package requirements in
PACKAGES are satisfied, i.e. that PACKAGES is computed
using `package-compute-transaction'."
@@ -1925,13 +1932,13 @@ add a call to it along with some explanatory comments."
;;;###autoload
(defun package-install (pkg &optional dont-select)
"Install the package PKG.
-PKG can be a package-desc or a symbol naming one of the available packages
+PKG can be a `package-desc' or a symbol naming one of the available packages
in an archive in `package-archives'. Interactively, prompt for its name.
If called interactively or if DONT-SELECT nil, add PKG to
`package-selected-packages'.
-If PKG is a package-desc and it is already installed, don't try
+If PKG is a `package-desc' and it is already installed, don't try
to install it but still mark it as selected."
(interactive
(progn
@@ -2060,7 +2067,7 @@ If some packages are not installed propose to install them."
;;; Package Deletion
(defun package--newest-p (pkg)
- "Return t if PKG is the newest package with its name."
+ "Return non-nil if PKG is the newest package with its name."
(equal (cadr (assq (package-desc-name pkg) package-alist))
pkg))
@@ -2120,11 +2127,16 @@ If NOSAVE is non-nil, the package is not removed from
(package-desc-name pkg-used-elsewhere-by)))
(t
(add-hook 'post-command-hook #'package-menu--post-refresh)
- (delete-directory dir t t)
- ;; Remove NAME-VERSION.signed file.
- (let ((signed-file (concat dir ".signed")))
- (if (file-exists-p signed-file)
- (delete-file signed-file)))
+ (delete-directory dir t)
+ ;; Remove NAME-VERSION.signed and NAME-readme.txt files.
+ (dolist (suffix '(".signed" "readme.txt"))
+ (let* ((version (package-version-join (package-desc-version pkg-desc)))
+ (file (concat (if (string= suffix ".signed")
+ dir
+ (substring dir 0 (- (length version))))
+ suffix)))
+ (when (file-exists-p file)
+ (delete-file file))))
;; Update package-alist.
(let ((pkgs (assq name package-alist)))
(delete pkg-desc pkgs)
@@ -2135,7 +2147,7 @@ If NOSAVE is non-nil, the package is not removed from
;;;###autoload
(defun package-reinstall (pkg)
"Reinstall package PKG.
-PKG should be either a symbol, the package name, or a package-desc
+PKG should be either a symbol, the package name, or a `package-desc'
object."
(interactive (list (intern (completing-read
"Reinstall package: "
@@ -2352,6 +2364,12 @@ Otherwise no newline is inserted."
(package-desc-name pkg))))
(insert "\n")))
(when homepage
+ ;; Prefer https for the homepage of packages on gnu.org.
+ (if (string-match-p "^http://\\(elpa\\|www\\)\\.gnu\\.org/" homepage)
+ (let ((gnu (cdr (assoc "gnu" package-archives))))
+ (and gnu (string-match-p "^https" gnu)
+ (setq homepage
+ (replace-regexp-in-string "^http" "https" homepage)))))
(package--print-help-section "Homepage")
(help-insert-xref-button homepage 'help-url homepage)
(insert "\n"))
@@ -2554,7 +2572,7 @@ package PKG-DESC, add one. The alist is keyed with PKG-DESC."
(defun package--incompatible-p (pkg &optional shallow)
"Return non-nil if PKG has no chance of being installable.
-PKG is a package-desc object.
+PKG is a `package-desc' object.
If SHALLOW is non-nil, this only checks if PKG depends on a
higher `emacs-version' than the one being used. Otherwise, also
@@ -2638,7 +2656,7 @@ Installed obsolete packages are always displayed.")
(defun package--remove-hidden (pkg-list)
"Filter PKG-LIST according to `package-archive-priorities'.
-PKG-LIST must be a list of package-desc objects, all with the
+PKG-LIST must be a list of `package-desc' objects, all with the
same name, sorted by decreasing `package-desc-priority-version'.
Return a list of packages tied for the highest priority according
to their archives."
@@ -2879,7 +2897,7 @@ Return (PKG-DESC [NAME VERSION STATUS DOC])."
:version "25.1")
(defface package-status-incompat
- '((t :inherit font-lock-comment-face))
+ '((t :inherit error))
"Face used on the status and version of incompat packages."
:version "25.1")
@@ -2892,7 +2910,7 @@ Return (PKG-DESC [NAME VERSION STATUS DOC])."
;;; Package menu printing
(defun package-menu--print-info-simple (pkg)
"Return a package entry suitable for `tabulated-list-entries'.
-PKG is a package-desc object.
+PKG is a `package-desc' object.
Return (PKG-DESC [NAME VERSION STATUS DOC])."
(let* ((status (package-desc-status pkg))
(face (pcase status