aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/package/package-core.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/package/package-core.el')
-rw-r--r--lisp/package/package-core.el927
1 files changed, 927 insertions, 0 deletions
diff --git a/lisp/package/package-core.el b/lisp/package/package-core.el
new file mode 100644
index 00000000000..83a04402705
--- /dev/null
+++ b/lisp/package/package-core.el
@@ -0,0 +1,927 @@
1;;; package-core.el --- Core of the Emacs Package Manager -*- lexical-binding:t -*-
2
3;; Copyright (C) 2007-2025 Free Software Foundation, Inc.
4
5;; Author: Tom Tromey <tromey@redhat.com>
6;; Daniel Hackney <dan@haxney.org>
7;; Created: 10 Mar 2007
8;; Version: 1.1.0
9;; Keywords: tools
10;; Package-Requires: ((tabulated-list "1.0"))
11
12;; This file is part of GNU Emacs.
13
14;; GNU Emacs is free software: you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published by
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
18
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
26
27;;; Commentary:
28
29;; TODO
30
31;;; Code:
32
33(eval-and-compile (require 'cl-lib))
34(eval-when-compile (require 'epg)) ;For setf accessors.
35(eval-when-compile (require 'inline)) ;For `define-inline'
36
37(defvar package--default-summary "No description available.")
38
39(defvar package-list-unversioned nil
40 "If non-nil, include packages that don't have a version in `list-packages'.")
41
42(defvar package-list-unsigned nil
43 "If non-nil, mention in the list which packages were installed without signature.")
44
45(defvar package--emacs-version-list (version-to-list emacs-version)
46 "The value of variable `emacs-version' as a list.")
47
48(define-inline package-vc-p (pkg-desc)
49 "Return non-nil if PKG-DESC is a VC package."
50 (inline-letevals (pkg-desc)
51 (inline-quote (eq (package-desc-kind ,pkg-desc) 'vc))))
52
53(cl-defstruct (package-desc
54 ;; Rename the default constructor from `make-package-desc'.
55 (:constructor package-desc-create)
56 ;; Has the same interface as the old `define-package',
57 ;; which is still used in the "foo-pkg.el" files. Extra
58 ;; options can be supported by adding additional keys.
59 (:constructor
60 package-desc-from-define
61 (name-string version-string &optional summary requirements
62 &rest rest-plist
63 &aux
64 (name (intern name-string))
65 (version (if (eq (car-safe version-string) 'vc)
66 (version-to-list (cdr version-string))
67 (version-to-list version-string)))
68 (reqs (mapcar (lambda (elt)
69 (list (car elt)
70 (version-to-list (cadr elt))))
71 (if (eq 'quote (car requirements))
72 (nth 1 requirements)
73 requirements)))
74 (kind (plist-get rest-plist :kind))
75 (archive (plist-get rest-plist :archive))
76 (extras (let (alist)
77 (while rest-plist
78 (unless (memq (car rest-plist) '(:kind :archive))
79 (let ((value (cadr rest-plist)))
80 (when value
81 (push (cons (car rest-plist)
82 (if (eq (car-safe value) 'quote)
83 (cadr value)
84 value))
85 alist))))
86 (setq rest-plist (cddr rest-plist)))
87 alist)))))
88 "Structure containing information about an individual package.
89Slots:
90
91`name' Name of the package, as a symbol.
92
93`version' Version of the package, as a version list.
94
95`summary' Short description of the package, typically taken from
96 the first line of the file.
97
98`reqs' Requirements of the package. A list of (PACKAGE
99 VERSION-LIST) naming the dependent package and the minimum
100 required version.
101
102`kind' The distribution format of the package. Currently, it is
103 either `single' or `tar'.
104
105`archive' The name of the archive (as a string) whence this
106 package came.
107
108`dir' The directory where the package is installed (if installed),
109 `builtin' if it is built-in, or nil otherwise.
110
111`extras' Optional alist of additional keyword-value pairs.
112
113`signed' Flag to indicate that the package is signed by provider."
114 name
115 version
116 (summary package--default-summary)
117 reqs
118 kind
119 archive
120 dir
121 extras
122 signed)
123
124(cl-defstruct (package--bi-desc
125 (:constructor package-make-builtin (version summary))
126 (:type vector))
127 "Package descriptor format used in finder-inf.el and package--builtins."
128 version
129 reqs
130 summary)
131
132(defun package--from-builtin (bi-desc)
133 "Create a `package-desc' object from BI-DESC.
134BI-DESC should be a `package--bi-desc' object."
135 (package-desc-create :name (pop bi-desc)
136 :version (package--bi-desc-version bi-desc)
137 :summary (package--bi-desc-summary bi-desc)
138 :dir 'builtin))
139
140(defun package-desc--keywords (pkg-desc)
141 "Return keywords of package-desc object PKG-DESC.
142These keywords come from the foo-pkg.el file, and in general
143corresponds to the keywords in the \"Keywords\" header of the
144package."
145 (let ((keywords (cdr (assoc :keywords (package-desc-extras pkg-desc)))))
146 (if (eq (car-safe keywords) 'quote)
147 (nth 1 keywords)
148 keywords)))
149
150(defun package--read-pkg-desc (kind)
151 "Read a `define-package' form in current buffer.
152Return the pkg-desc, with desc-kind set to KIND."
153 (goto-char (point-min))
154 (let* ((pkg-def-parsed (read (current-buffer)))
155 (pkg-desc
156 (when (eq (car pkg-def-parsed) 'define-package)
157 (apply #'package-desc-from-define
158 (append (cdr pkg-def-parsed))))))
159 (when pkg-desc
160 (setf (package-desc-kind pkg-desc) kind)
161 pkg-desc)))
162
163(defgroup package nil
164 "Manager for Emacs Lisp packages."
165 :group 'applications
166 :version "24.1")
167
168
169;;; Customization options
170
171;;;###autoload
172(defcustom package-enable-at-startup t
173 "Whether to make installed packages available when Emacs starts.
174If non-nil, packages are made available before reading the init
175file (but after reading the early init file). This means that if
176you wish to set this variable, you must do so in the early init
177file. Regardless of the value of this variable, packages are not
178made available if `user-init-file' is nil (e.g. Emacs was started
179with \"-q\").
180
181Even if the value is nil, you can type \\[package-initialize] to
182make installed packages available at any time, or you can
183call (package-activate-all) in your init-file.
184
185Note that this variable must be set to a non-default value in
186your early-init file, as the variable's value is used before
187loading the regular init file. Therefore, if you customize it
188via Customize, you should save your customized setting into
189your `early-init-file'."
190 :type 'boolean
191 :version "24.1")
192
193(defcustom package-load-list '(all)
194 "List of packages for `package-activate-all' to make available.
195Each element in this list should be a list (NAME VERSION), or the
196symbol `all'. The symbol `all' says to make available the latest
197installed versions of all packages not specified by other
198elements.
199
200For an element (NAME VERSION), NAME is a package name (a symbol).
201VERSION should be t, a string, or nil.
202If VERSION is t, the most recent version is made available.
203If VERSION is a string, only that version is ever made available.
204 Any other version, even if newer, is silently ignored.
205 Hence, the package is \"held\" at that version.
206If VERSION is nil, the package is not made available (it is \"disabled\")."
207 :type '(repeat (choice (const all)
208 (list :tag "Specific package"
209 (symbol :tag "Package name")
210 (choice :tag "Version"
211 (const :tag "disable" nil)
212 (const :tag "most recent" t)
213 (string :tag "specific version")))))
214 :risky t
215 :version "24.1")
216
217(defcustom package-pinned-packages nil
218 "An alist of packages that are pinned to specific archives.
219This can be useful if you have multiple package archives enabled,
220and want to control which archive a given package gets installed from.
221
222Each element of the alist has the form (PACKAGE . ARCHIVE), where:
223 PACKAGE is a symbol representing a package
224 ARCHIVE is a string representing an archive (it should be the car of
225an element in `package-archives', e.g. \"gnu\").
226
227Adding an entry to this variable means that only ARCHIVE will be
228considered as a source for PACKAGE. If other archives provide PACKAGE,
229they are ignored (for this package). If ARCHIVE does not contain PACKAGE,
230the package will be unavailable."
231 :type '(alist :key-type (symbol :tag "Package")
232 :value-type (string :tag "Archive name"))
233 ;; This could prevent you from receiving updates for a package,
234 ;; via an entry (PACKAGE . NON-EXISTING). Which could be an issue
235 ;; if PACKAGE has a known vulnerability that is fixed in newer versions.
236 :risky t
237 :version "24.4")
238
239;;;###autoload
240(defcustom package-user-dir (locate-user-emacs-file "elpa")
241 "Directory containing the user's Emacs Lisp packages.
242The directory name should be absolute.
243Apart from this directory, Emacs also looks for system-wide
244packages in `package-directory-list'."
245 :type 'directory
246 :initialize #'custom-initialize-delay
247 :risky t
248 :group 'applications
249 :version "24.1")
250
251;;;###autoload
252(defcustom package-directory-list
253 ;; Defaults are subdirs named "elpa" in the site-lisp dirs.
254 (let (result)
255 (dolist (f load-path)
256 (and (stringp f)
257 (equal (file-name-nondirectory f) "site-lisp")
258 (push (expand-file-name "elpa" f) result)))
259 (nreverse result))
260 "List of additional directories containing Emacs Lisp packages.
261Each directory name should be absolute.
262
263These directories contain packages intended for system-wide; in
264contrast, `package-user-dir' contains packages for personal use."
265 :type '(repeat directory)
266 :initialize #'custom-initialize-delay
267 :group 'applications
268 :risky t
269 :version "24.1")
270
271(defcustom package-selected-packages nil
272 "Store here packages installed explicitly by user.
273This variable is fed automatically by Emacs when installing a new package.
274This variable is used by `package-autoremove' to decide
275which packages are no longer needed.
276You can use it to (re)install packages on other machines
277by running `package-install-selected-packages'.
278
279To check if a package is contained in this list here, use
280`package--user-selected-p', as it may populate the variable with
281a sane initial value."
282 :version "25.1"
283 :type '(repeat symbol))
284
285;; Pseudo fields.
286(defun package-version-join (vlist)
287 "Return the version string corresponding to the list VLIST.
288This is, approximately, the inverse of `version-to-list'.
289\(Actually, it returns only one of the possible inverses, since
290`version-to-list' is a many-to-one operation.)"
291 (if (null vlist)
292 ""
293 (let ((str-list (list "." (int-to-string (car vlist)))))
294 (dolist (num (cdr vlist))
295 (cond
296 ((>= num 0)
297 (push (int-to-string num) str-list)
298 (push "." str-list))
299 ((< num -4)
300 (error "Invalid version list `%s'" vlist))
301 (t
302 ;; pre, or beta, or alpha
303 (cond ((equal "." (car str-list))
304 (pop str-list))
305 ((not (string-match "[0-9]+" (car str-list)))
306 (error "Invalid version list `%s'" vlist)))
307 (push (cond ((= num -1) "pre")
308 ((= num -2) "beta")
309 ((= num -3) "alpha")
310 ((= num -4) "snapshot"))
311 str-list))))
312 (if (equal "." (car str-list))
313 (pop str-list))
314 (apply #'concat (nreverse str-list)))))
315
316
317
318;;; Installed packages
319;; The following variables store information about packages present in
320;; the system. The most important of these is `package-alist'. The
321;; command `package-activate-all' is also closely related to this
322;; section.
323
324(defvar package--builtins nil
325 "Alist of built-in packages.
326The actual value is initialized by loading the library
327`finder-inf'; this is not done until it is needed, e.g. by the
328function `package-built-in-p'.
329
330Each element has the form (PKG . PACKAGE-BI-DESC), where PKG is a package
331name (a symbol) and DESC is a `package--bi-desc' structure.")
332(put 'package--builtins 'risky-local-variable t)
333
334(defvar package-alist nil
335 "Alist of all packages available for activation.
336Each element has the form (PKG . DESCS), where PKG is a package
337name (a symbol) and DESCS is a non-empty list of `package-desc'
338structures, sorted by decreasing versions.
339
340This variable is set automatically by `package-load-descriptor',
341called via `package-activate-all'. To change which packages are
342loaded and/or activated, customize `package-load-list'.")
343(put 'package-alist 'risky-local-variable t)
344
345;;;; Public interfaces for accessing built-in package info
346
347(defun package-versioned-builtin-packages ()
348 "Return a list of all the versioned built-in packages.
349The return value is a list of names of built-in packages represented as
350symbols."
351 (mapcar #'car package--builtin-versions))
352
353(defun package-builtin-package-version (package)
354 "Return the version of a built-in PACKAGE given by its symbol.
355The return value is a list of integers representing the version of
356PACKAGE, in the format returned by `version-to-list', or nil if the
357package is built-in but has no version or is not a built-in package."
358 (alist-get package package--builtin-versions))
359
360;;;###autoload
361(defvar package-activated-list nil
362 ;; FIXME: This should implicitly include all builtin packages.
363 "List of the names of currently activated packages.")
364(put 'package-activated-list 'risky-local-variable t)
365
366;;;; Populating `package-alist'.
367
368;; The following functions are called on each installed package by
369;; `package-load-all-descriptors', which ultimately populates the
370;; `package-alist' variable.
371
372(defun package-process-define-package (exp)
373 "Process define-package expression EXP and push it to `package-alist'.
374EXP should be a form read from a foo-pkg.el file.
375Convert EXP into a `package-desc' object using the
376`package-desc-from-define' constructor before pushing it to
377`package-alist'.
378
379If there already exists a package by the same name in
380`package-alist', insert this object there such that the packages
381are sorted with the highest version first."
382 (when (eq (car-safe exp) 'define-package)
383 (let* ((new-pkg-desc (apply #'package-desc-from-define (cdr exp)))
384 (name (package-desc-name new-pkg-desc))
385 (version (package-desc-version new-pkg-desc))
386 (old-pkgs (assq name package-alist)))
387 (if (null old-pkgs)
388 ;; If there's no old package, just add this to `package-alist'.
389 (push (list name new-pkg-desc) package-alist)
390 ;; If there is, insert the new package at the right place in the list.
391 (while
392 (if (and (cdr old-pkgs)
393 (version-list-< version
394 (package-desc-version (cadr old-pkgs))))
395 (setq old-pkgs (cdr old-pkgs))
396 (push new-pkg-desc (cdr old-pkgs))
397 nil)))
398 new-pkg-desc)))
399
400(defun package-load-descriptor (pkg-dir)
401 "Load the package description file in directory PKG-DIR.
402Create a new `package-desc' object, add it to `package-alist' and
403return it."
404 (let ((pkg-file (expand-file-name (package--description-file pkg-dir)
405 pkg-dir))
406 (signed-file (concat pkg-dir ".signed")))
407 (when (file-exists-p pkg-file)
408 (with-temp-buffer
409 (insert-file-contents pkg-file)
410 (goto-char (point-min))
411 (let ((pkg-desc (or (package-process-define-package
412 (read (current-buffer)))
413 (error "Can't find define-package in %s" pkg-file))))
414 (setf (package-desc-dir pkg-desc) pkg-dir)
415 (if (file-exists-p signed-file)
416 (setf (package-desc-signed pkg-desc) t))
417 pkg-desc)))))
418
419(defun package-load-all-descriptors ()
420 "Load descriptors for installed Emacs Lisp packages.
421This looks for package subdirectories in `package-user-dir' and
422`package-directory-list'. The variable `package-load-list'
423controls which package subdirectories may be loaded.
424
425In each valid package subdirectory, this function loads the
426description file containing a call to `define-package', which
427updates `package-alist'."
428 (dolist (dir (cons package-user-dir package-directory-list))
429 (when (file-directory-p dir)
430 (dolist (pkg-dir (directory-files dir t "\\`[^.]"))
431 (when (file-directory-p pkg-dir)
432 (package-load-descriptor pkg-dir))))))
433
434(defun package--alist ()
435 "Return `package-alist', after computing it if needed."
436 (or package-alist
437 (progn (package-load-all-descriptors)
438 package-alist)))
439
440
441;;; Package activation
442;; Section for functions used by `package-activate', which see.
443
444(defun package-disabled-p (pkg-name version)
445 "Return whether PKG-NAME at VERSION can be activated.
446The decision is made according to `package-load-list'.
447Return nil if the package can be activated.
448Return t if the package is completely disabled.
449Return the max version (as a string) if the package is held at a lower version."
450 (let ((force (assq pkg-name package-load-list)))
451 (cond ((null force) (not (memq 'all package-load-list)))
452 ((null (setq force (cadr force))) t) ; disabled
453 ((eq force t) nil)
454 ((stringp force) ; held
455 (unless (version-list-= version (version-to-list force))
456 force))
457 (t (error "Invalid element in `package-load-list'")))))
458
459(defun package-built-in-p (package &optional min-version)
460 "Return non-nil if PACKAGE is built-in to Emacs.
461Optional arg MIN-VERSION, if non-nil, should be a version list
462specifying the minimum acceptable version."
463 (if (package-desc-p package) ;; was built-in and then was converted
464 (eq 'builtin (package-desc-dir package))
465 (let ((bi (assq package package--builtin-versions)))
466 (cond
467 (bi (version-list-<= min-version (cdr bi)))
468 ((remove 0 min-version) nil)
469 (t
470 (require 'finder-inf nil t) ; For `package--builtins'.
471 (assq package package--builtins))))))
472
473(defun package--active-built-in-p (package)
474 "Return non-nil if the built-in version of PACKAGE is used.
475If the built-in version of PACKAGE is used and PACKAGE is
476also available for installation from an archive, it is an
477indication that PACKAGE was never upgraded to any newer
478version from the archive."
479 (and (not (assq (cond
480 ((package-desc-p package)
481 (package-desc-name package))
482 ((stringp package) (intern package))
483 ((symbolp package) package)
484 ((error "Unknown package format: %S" package)))
485 (package--alist)))
486 (package-built-in-p package)))
487
488(defun package--autoloads-file-name (pkg-desc)
489 "Return the absolute name of the autoloads file, sans extension.
490PKG-DESC is a `package-desc' object."
491 (expand-file-name
492 (format "%s-autoloads" (package-desc-name pkg-desc))
493 (package-desc-dir pkg-desc)))
494
495(defvar Info-directory-list)
496(declare-function info-initialize "info" ())
497
498(defvar package--quickstart-pkgs t
499 "If set to a list, we're computing the set of pkgs to activate.")
500
501(defsubst package--library-stem (file)
502 (catch 'done
503 (let (result)
504 (dolist (suffix (get-load-suffixes) file)
505 (setq result (string-trim file nil suffix))
506 (unless (equal file result)
507 (throw 'done result))))))
508
509(defun package--reload-previously-loaded (pkg-desc &optional warn)
510 "Force reimportation of files in PKG-DESC already present in `load-history'.
511New editions of files contain macro definitions and
512redefinitions, the overlooking of which would cause
513byte-compilation of the new package to fail.
514If WARN is a string, display a warning (using WARN as a format string)
515before reloading the files. WARN must have two %-sequences
516corresponding to package name (a symbol) and a list of files loaded (as
517sexps)."
518 (with-demoted-errors "Error in package--load-files-for-activation: %s"
519 (let* (result
520 (dir (package-desc-dir pkg-desc))
521 ;; A previous implementation would skip `dir' itself.
522 ;; However, in normal use reloading from the same directory
523 ;; never happens anyway, while in certain cases external to
524 ;; Emacs a package in the same directory not necessary
525 ;; stays byte-identical, e.g. during development. Just
526 ;; don't special-case `dir'.
527 (effective-path (or (bound-and-true-p find-library-source-path)
528 load-path))
529 (files (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
530 (history (mapcar #'file-truename
531 (cl-remove-if-not #'stringp
532 (mapcar #'car load-history)))))
533 (dolist (file files)
534 (when-let* ((library (package--library-stem
535 (file-relative-name file dir)))
536 (canonical (locate-library library nil effective-path))
537 (truename (file-truename canonical))
538 ;; Normally, all files in a package are compiled by
539 ;; now, but don't assume that. E.g. different
540 ;; versions can add or remove `no-byte-compile'.
541 (altname (if (string-suffix-p ".el" truename)
542 (replace-regexp-in-string
543 "\\.el\\'" ".elc" truename t)
544 (replace-regexp-in-string
545 "\\.elc\\'" ".el" truename t)))
546 (found (or (member truename history)
547 (and (not (string= altname truename))
548 (member altname history))))
549 (recent-index (length found)))
550 (unless (equal (file-name-base library)
551 (format "%s-autoloads" (package-desc-name pkg-desc)))
552 (push (cons (expand-file-name library dir) recent-index) result))))
553 (when (and result warn)
554 (display-warning 'package
555 (format warn (package-desc-name pkg-desc)
556 (mapcar #'car result))))
557 (mapc (lambda (c) (load (car c) nil t))
558 (sort result (lambda (x y) (< (cdr x) (cdr y))))))))
559
560(defun package-desc-full-name (pkg-desc)
561 "Return full name of package-desc object PKG-DESC.
562This is the name of the package with its version appended."
563 (if (package-vc-p pkg-desc)
564 (symbol-name (package-desc-name pkg-desc))
565 (format "%s-%s"
566 (package-desc-name pkg-desc)
567 (package-version-join (package-desc-version pkg-desc)))))
568
569(defun package-activate-1 (pkg-desc &optional reload deps)
570 "Activate package given by PKG-DESC, even if it was already active.
571If DEPS is non-nil, also activate its dependencies (unless they
572are already activated).
573If RELOAD is non-nil, also `load' any files inside the package which
574correspond to previously loaded files."
575 (let* ((name (package-desc-name pkg-desc))
576 (pkg-dir (package-desc-dir pkg-desc)))
577 (unless pkg-dir
578 (error "Internal error: unable to find directory for `%s'"
579 (package-desc-full-name pkg-desc)))
580 (catch 'exit
581 ;; Activate its dependencies recursively.
582 ;; FIXME: This doesn't check whether the activated version is the
583 ;; required version.
584 (when deps
585 (dolist (req (package-desc-reqs pkg-desc))
586 (unless (package-activate (car req))
587 (message "Unable to activate package `%s'.\nRequired package `%s-%s' is unavailable"
588 name (car req) (package-version-join (cadr req)))
589 (throw 'exit nil))))
590 (if (listp package--quickstart-pkgs)
591 ;; We're only collecting the set of packages to activate!
592 (push pkg-desc package--quickstart-pkgs)
593 (when (or reload (assq name package--builtin-versions))
594 (package--reload-previously-loaded
595 pkg-desc (unless reload
596 "Package %S is activated too late.
597The following files have already been loaded: %S")))
598 (with-demoted-errors "Error loading autoloads: %s"
599 (load (package--autoloads-file-name pkg-desc) nil t)))
600 ;; Add info node.
601 (when (file-exists-p (expand-file-name "dir" pkg-dir))
602 ;; FIXME: not the friendliest, but simple.
603 (require 'info)
604 (info-initialize)
605 (add-to-list 'Info-directory-list pkg-dir))
606 (push name package-activated-list)
607 ;; Don't return nil.
608 t)))
609
610;;;; `package-activate'
611
612(defun package--get-activatable-pkg (pkg-name)
613 ;; Is "activatable" a word?
614 (let ((pkg-descs (cdr (assq pkg-name package-alist))))
615 ;; Check if PACKAGE is available in `package-alist'.
616 (while
617 (when pkg-descs
618 (let ((available-version (package-desc-version (car pkg-descs))))
619 (or (package-disabled-p pkg-name available-version)
620 ;; Prefer a builtin package.
621 (package-built-in-p pkg-name available-version))))
622 (setq pkg-descs (cdr pkg-descs)))
623 (car pkg-descs)))
624
625(defvar package--initialized nil
626 "Non-nil if `package-initialize' has been run.")
627
628;; This function activates a newer version of a package if an older
629;; one was already activated. It also loads a features of this
630;; package which were already loaded.
631(defun package-activate (package &optional force)
632 "Activate the package named PACKAGE.
633If FORCE is true, (re-)activate it if it's already activated.
634Newer versions are always activated, regardless of FORCE."
635 (let ((pkg-desc (package--get-activatable-pkg package)))
636 (cond
637 ;; If no such package is found, maybe it's built-in.
638 ((null pkg-desc)
639 (package-built-in-p package))
640 ;; If the package is already activated, just return t.
641 ((and (memq package package-activated-list) (not force))
642 t)
643 ;; Otherwise, proceed with activation.
644 (t (package-activate-1 pkg-desc nil 'deps)))))
645
646
647;;; Installation -- Local operations
648;; This section contains a variety of features regarding installing a
649;; package to/from disk. This includes autoload generation,
650;; unpacking, compiling, as well as defining a package from the
651;; current buffer.
652
653;;;; Unpacking
654
655;;;###autoload
656(defvar package--activated nil
657 "Non-nil if `package-activate-all' has been run.")
658
659(declare-function package-read-all-archive-contents "package-elpa" ())
660
661(defvar package--compatibility-table nil
662 "Hash table connecting package names to their compatibility.
663Each key is a symbol, the name of a package.
664
665The value is either nil, representing an incompatible package, or
666a version list, representing the highest compatible version of
667that package which is available.
668
669A package is considered incompatible if it requires an Emacs
670version higher than the one being used. To check for package
671\(in)compatibility, don't read this table directly, use
672`package--incompatible-p' which also checks dependencies.")
673
674(defun package--add-to-compatibility-table (pkg)
675 "If PKG is compatible (without dependencies), add to the compatibility table.
676PKG is a package-desc object.
677Only adds if its version is higher than what's already stored in
678the table."
679 (unless (package--incompatible-p pkg 'shallow)
680 (let* ((name (package-desc-name pkg))
681 (version (or (package-desc-version pkg) '(0)))
682 (table-version (gethash name package--compatibility-table)))
683 (when (or (not table-version)
684 (version-list-< table-version version))
685 (puthash name version package--compatibility-table)))))
686
687(defun package--mapc (function &optional packages)
688 "Call FUNCTION for all known PACKAGES.
689PACKAGES can be nil or t, which means to display all known
690packages, or a list of packages.
691
692Built-in packages are converted with `package--from-builtin'."
693 (unless packages (setq packages t))
694 (let (name)
695 ;; Installed packages:
696 (dolist (elt package-alist)
697 (setq name (car elt))
698 (when (or (eq packages t) (memq name packages))
699 (mapc function (cdr elt))))
700
701 ;; Built-in packages:
702 (dolist (elt package--builtins)
703 (setq name (car elt))
704 (when (and (not (eq name 'emacs)) ; Hide the `emacs' package.
705 (or package-list-unversioned
706 (package--bi-desc-version (cdr elt)))
707 (or (eq packages t) (memq name packages)))
708 (funcall function (package--from-builtin elt))))
709
710 ;; Available and disabled packages:
711 (dolist (elt (bound-and-true-p package-archive-contents))
712 (setq name (car elt))
713 (when (or (eq packages t) (memq name packages))
714 (dolist (pkg (cdr elt))
715 ;; Hide obsolete packages.
716 (unless (package-installed-p (package-desc-name pkg)
717 (package-desc-version pkg))
718 (funcall function pkg)))))))
719
720(defun package--build-compatibility-table ()
721 "Build `package--compatibility-table' with `package--mapc'."
722 ;; Initialize the list of built-ins.
723 (require 'finder-inf nil t)
724 ;; Build compat table.
725 (setq package--compatibility-table (make-hash-table :test 'eq))
726 (package--mapc #'package--add-to-compatibility-table))
727
728;;;###autoload
729(defun package-initialize (&optional no-activate)
730 "Load Emacs Lisp packages, and activate them.
731The variable `package-load-list' controls which packages to load.
732If optional arg NO-ACTIVATE is non-nil, don't activate packages.
733
734It is not necessary to adjust `load-path' or `require' the
735individual packages after calling `package-initialize' -- this is
736taken care of by `package-initialize'.
737
738If `package-initialize' is called twice during Emacs startup,
739signal a warning, since this is a bad idea except in highly
740advanced use cases. To suppress the warning, remove the
741superfluous call to `package-initialize' from your init-file. If
742you have code which must run before `package-initialize', put
743that code in the early init-file."
744 (interactive)
745 (when (and package--initialized (not after-init-time))
746 (lwarn '(package reinitialization) :warning
747 "Unnecessary call to `package-initialize' in init file"))
748 (setq package-alist nil)
749 (package-load-all-descriptors)
750 (require 'package)
751 (package-read-all-archive-contents)
752 (setq package--initialized t)
753 (unless no-activate
754 (package-activate-all))
755 ;; This uses `package--mapc' so it must be called after
756 ;; `package--initialized' is t.
757 (package--build-compatibility-table))
758
759;;;###autoload
760(progn ;; Make the function usable without loading `package.el'.
761(defun package-activate-all ()
762 "Activate all installed packages.
763The variable `package-load-list' controls which packages to load."
764 (setq package--activated t)
765 (let* ((elc (concat package-quickstart-file "c"))
766 (qs (if (file-readable-p elc) elc
767 (if (file-readable-p package-quickstart-file)
768 package-quickstart-file))))
769 ;; The quickstart file presumes that it has a blank slate,
770 ;; so don't use it if we already activated some packages.
771 (or (and qs (not (bound-and-true-p package-activated-list))
772 ;; Skip `load-source-file-function' which would slow us down by
773 ;; a factor 2 when loading the .el file (this assumes we were
774 ;; careful to save this file so it doesn't need any decoding).
775 (with-demoted-errors "Error during quickstart: %S"
776 (let ((load-source-file-function nil))
777 (unless (boundp 'package-activated-list)
778 (setq package-activated-list nil))
779 (load qs nil 'nomessage)
780 t)))
781 (progn
782 (require 'package)
783 ;; Silence the "unknown function" warning when this is compiled
784 ;; inside `loaddefs.el'.
785 ;; FIXME: We use `with-no-warnings' because the effect of
786 ;; `declare-function' is currently not scoped, so if we use
787 ;; it here, we end up with a redefinition warning instead :-)
788 (with-no-warnings
789 (package--activate-all)))))))
790
791(defun package--activate-all ()
792 (dolist (elt (package--alist))
793 (condition-case err
794 (package-activate (car elt))
795 ;; Don't let failure of activation of a package arbitrarily stop
796 ;; activation of further packages.
797 (error (message "%s" (error-message-string err))))))
798
799(defun package-strip-rcs-id (str)
800 "Strip RCS version ID from the version string STR.
801If the result looks like a dotted numeric version, return it.
802Otherwise return nil."
803 (when str
804 (when (string-match "\\`[ \t]*[$]Revision:[ \t]+" str)
805 (setq str (substring str (match-end 0))))
806 (let ((l (version-to-list str)))
807 ;; Don't return `str' but (package-version-join (version-to-list str))
808 ;; to make sure we use a "canonical name"!
809 (if l (package-version-join l)))))
810
811(defun package--incompatible-p (pkg &optional shallow)
812 "Return non-nil if PKG has no chance of being installable.
813PKG is a `package-desc' object.
814
815If SHALLOW is non-nil, this only checks if PKG depends on a
816higher `emacs-version' than the one being used. Otherwise, also
817checks the viability of dependencies, according to
818`package--compatibility-table'.
819
820If PKG requires an incompatible Emacs version, the return value
821is this version (as a string).
822If PKG requires incompatible packages, the return value is a list
823of these dependencies, similar to the list returned by
824`package-desc-reqs'."
825 (let* ((reqs (package-desc-reqs pkg))
826 (version (cadr (assq 'emacs reqs))))
827 (if (and version (version-list-< package--emacs-version-list version))
828 (package-version-join version)
829 (unless shallow
830 (let (out)
831 (dolist (dep (package-desc-reqs pkg) out)
832 (let ((dep-name (car dep)))
833 (unless (eq 'emacs dep-name)
834 (let ((cv (gethash dep-name package--compatibility-table)))
835 (when (version-list-< (or cv '(0)) (or (cadr dep) '(0)))
836 (push dep out)))))))))))
837
838(defun package--find-non-dependencies ()
839 "Return a list of installed packages which are not dependencies.
840Finds all packages in `package-alist' which are not dependencies
841of any other packages.
842Used to populate `package-selected-packages'."
843 (let ((dep-list
844 (delete-dups
845 (apply #'append
846 (mapcar (lambda (p) (mapcar #'car (package-desc-reqs (cadr p))))
847 package-alist)))))
848 (cl-loop for p in package-alist
849 for name = (car p)
850 unless (memq name dep-list)
851 collect name)))
852
853(defun package--save-selected-packages (&optional value)
854 "Set and save `package-selected-packages' to VALUE."
855 (when (or value after-init-time)
856 ;; It is valid to set it to nil, for example when the last package
857 ;; is uninstalled. But it shouldn't be done at init time, to
858 ;; avoid overwriting configurations that haven't yet been loaded.
859 (setq package-selected-packages (sort value #'string<)))
860 (if after-init-time
861 (customize-save-variable 'package-selected-packages package-selected-packages)
862 (add-hook 'after-init-hook #'package--save-selected-packages)))
863
864(defun package--user-selected-p (pkg)
865 "Return non-nil if PKG is a package was installed by the user.
866PKG is a package name.
867This looks into `package-selected-packages', populating it first
868if it is still empty."
869 (unless (consp package-selected-packages)
870 (package--save-selected-packages (package--find-non-dependencies)))
871 (memq pkg package-selected-packages))
872
873(defun package-desc-status (pkg-desc)
874 "Return the status of `package-desc' object PKG-DESC."
875 (let* ((name (package-desc-name pkg-desc))
876 (dir (package-desc-dir pkg-desc))
877 (lle (assq name package-load-list))
878 (held (cadr lle))
879 (version (package-desc-version pkg-desc))
880 (signed (or (not package-list-unsigned)
881 (package-desc-signed pkg-desc))))
882 (cond
883 ((package-vc-p pkg-desc) "source")
884 ((eq dir 'builtin) "built-in")
885 ((and lle (null held)) "disabled")
886 ((stringp held)
887 (let ((hv (if (stringp held) (version-to-list held))))
888 (cond
889 ((version-list-= version hv) "held")
890 ((version-list-< version hv) "obsolete")
891 (t "disabled"))))
892 (dir ;One of the installed packages.
893 (cond
894 ((not (file-exists-p dir)) "deleted")
895 ;; Not inside `package-user-dir'.
896 ((not (file-in-directory-p dir package-user-dir)) "external")
897 ((eq pkg-desc (cadr (assq name package-alist)))
898 (if (not signed) "unsigned"
899 (if (package--user-selected-p name)
900 "installed" "dependency")))
901 (t "obsolete")))
902 ((package--incompatible-p pkg-desc) "incompat")
903 (t
904 (let* ((ins (cadr (assq name package-alist)))
905 (ins-v (if ins (package-desc-version ins))))
906 (cond
907 ;; Installed obsolete packages are handled in the `dir'
908 ;; clause above. Here we handle available obsolete, which
909 ;; are displayed depending on `package-menu--hide-packages'.
910 ((and ins (version-list-<= version ins-v)) "avail-obso")
911 (t
912 (if (memq name (bound-and-true-p package-menu--new-package-list))
913 "new" "available"))))))))
914
915(defun package--query-desc (&optional alist)
916 "Query the user for a package or return the package at point.
917The optional argument ALIST must consist of elements with the
918form (PKG-NAME PKG-DESC). If not specified, it will default to
919`package-alist'."
920 (or (and (fboundp 'tabulated-list-get-id)
921 (tabulated-list-get-id))
922 (let ((alist (or alist package-alist)))
923 (cadr (assoc (completing-read "Package: " alist nil t)
924 alist #'string=)))))
925
926(provide 'package-core)
927;;; package-core.el ends here