diff options
Diffstat (limited to 'lisp/emacs-lisp/package.el')
-rw-r--r-- | lisp/emacs-lisp/package.el | 112 |
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 |