aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/package/package-install.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/package/package-install.el')
-rw-r--r--lisp/package/package-install.el1053
1 files changed, 1053 insertions, 0 deletions
diff --git a/lisp/package/package-install.el b/lisp/package/package-install.el
new file mode 100644
index 00000000000..5a96fedd528
--- /dev/null
+++ b/lisp/package/package-install.el
@@ -0,0 +1,1053 @@
1;;; package-install.el --- Physical Package Management -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2025 Philip Kaludercic
4
5;; Author: Philip Kaludercic <philipk@posteo.net>
6;; Keywords:
7
8;; This program is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation, either version 3 of the License, or
11;; (at your option) any later version.
12
13;; This program is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21;;; Commentary:
22
23;;
24
25;;; Code:
26
27(require 'package-core)
28(require 'package-misc)
29(require 'package-elpa)
30(require 'package-compile)
31(require 'package-quickstart)
32
33(require 'epg)
34(require 'tar-mode)
35(require 'lisp-mnt)
36
37(defcustom package-install-upgrade-built-in nil
38 "Non-nil means that built-in packages can be upgraded via a package archive.
39If disabled, then `package-install' will not suggest to replace a
40built-in package with a (possibly newer) version from a package archive."
41 :type 'boolean
42 :version "29.1"
43 :group 'package)
44
45(defun package-compute-transaction (packages requirements &optional seen)
46 "Return a list of packages to be installed, including PACKAGES.
47PACKAGES should be a list of `package-desc'.
48
49REQUIREMENTS should be a list of additional requirements; each
50element in this list should have the form (PACKAGE VERSION-LIST),
51where PACKAGE is a package name and VERSION-LIST is the required
52version of that package.
53
54This function recursively computes the requirements of the
55packages in REQUIREMENTS, and returns a list of all the packages
56that must be installed. Packages that are already installed are
57not included in this list.
58
59SEEN is used internally to detect infinite recursion."
60 ;; FIXME: We really should use backtracking to explore the whole
61 ;; search space (e.g. if foo require bar-1.3, and bar-1.4 requires toto-1.1
62 ;; whereas bar-1.3 requires toto-1.0 and the user has put a hold on toto-1.0:
63 ;; the current code might fail to see that it could install foo by using the
64 ;; older bar-1.3).
65 (dolist (elt requirements)
66 (let* ((next-pkg (car elt))
67 (next-version (cadr elt))
68 (already ()))
69 (dolist (pkg packages)
70 (if (eq next-pkg (package-desc-name pkg))
71 (setq already pkg)))
72 (when already
73 (if (version-list-<= next-version (package-desc-version already))
74 ;; `next-pkg' is already in `packages', but its position there
75 ;; means it might be installed too late: remove it from there, so
76 ;; we re-add it (along with its dependencies) at an earlier place
77 ;; below (bug#16994).
78 (if (memq already seen) ;Avoid inf-loop on dependency cycles.
79 (message "Dependency cycle going through %S"
80 (package-desc-full-name already))
81 (setq packages (delq already packages))
82 (setq already nil))
83 (error "Need package `%s-%s', but only %s is being installed"
84 next-pkg (package-version-join next-version)
85 (package-version-join (package-desc-version already)))))
86 (cond
87 (already nil)
88 ((package-installed-p next-pkg next-version) nil)
89
90 (t
91 ;; A package is required, but not installed. It might also be
92 ;; blocked via `package-load-list'.
93 (let ((pkg-descs (cdr (assq next-pkg package-archive-contents)))
94 (found nil)
95 (found-something nil)
96 (problem nil))
97 (while (and pkg-descs (not found))
98 (let* ((pkg-desc (pop pkg-descs))
99 (version (package-desc-version pkg-desc))
100 (disabled (package-disabled-p next-pkg version)))
101 (cond
102 ((version-list-< version next-version)
103 ;; pkg-descs is sorted by priority, not version, so
104 ;; don't error just yet.
105 (unless found-something
106 (setq found-something (package-version-join version))))
107 (disabled
108 (unless problem
109 (setq problem
110 (if (stringp disabled)
111 (format-message
112 "Package `%s' held at version %s, but version %s required"
113 next-pkg disabled
114 (package-version-join next-version))
115 (format-message "Required package `%s' is disabled"
116 next-pkg)))))
117 (t (setq found pkg-desc)))))
118 (unless found
119 (cond
120 (problem (error "%s" problem))
121 (found-something
122 (error "Need package `%s-%s', but only %s is available"
123 next-pkg (package-version-join next-version)
124 found-something))
125 (t
126 (if (eq next-pkg 'emacs)
127 (error "This package requires Emacs version %s"
128 (package-version-join next-version))
129 (error (if (not next-version)
130 (format "Package `%s' is unavailable" next-pkg)
131 (format "Package `%s' (version %s) is unavailable"
132 next-pkg (package-version-join next-version))))))))
133 (setq packages
134 (package-compute-transaction (cons found packages)
135 (package-desc-reqs found)
136 (cons found seen))))))))
137 packages)
138
139(defun package--get-deps (pkgs)
140 (let ((seen '()))
141 (while pkgs
142 (let ((pkg (pop pkgs)))
143 (if (memq pkg seen)
144 nil ;; Done already!
145 (let ((pkg-desc (cadr (assq pkg package-alist))))
146 (when pkg-desc
147 (push pkg seen)
148 (setq pkgs (append (mapcar #'car (package-desc-reqs pkg-desc))
149 pkgs)))))))
150 seen))
151
152(defun package--user-installed-p (package)
153 "Return non-nil if PACKAGE is a user-installed package.
154PACKAGE is the package name, a symbol. Check whether the package
155was installed into `package-user-dir' where we assume to have
156control over."
157 (let* ((pkg-desc (cadr (assq package package-alist)))
158 (dir (package-desc-dir pkg-desc)))
159 (file-in-directory-p dir package-user-dir)))
160
161(defun package--removable-packages ()
162 "Return a list of names of packages no longer needed.
163These are packages which are neither contained in
164`package-selected-packages' nor a dependency of one that is."
165 (let ((needed (package--get-deps package-selected-packages)))
166 (cl-loop for p in (mapcar #'car package-alist)
167 unless (or (memq p needed)
168 ;; Do not auto-remove external packages.
169 (not (package--user-installed-p p)))
170 collect p)))
171
172(defun package--used-elsewhere-p (pkg-desc &optional pkg-list all)
173 "Non-nil if PKG-DESC is a dependency of a package in PKG-LIST.
174Return the first package found in PKG-LIST of which PKG is a
175dependency. If ALL is non-nil, return all such packages instead.
176
177When not specified, PKG-LIST defaults to `package-alist'
178with PKG-DESC entry removed."
179 (unless (string= (package-desc-status pkg-desc) "obsolete")
180 (let* ((pkg (package-desc-name pkg-desc))
181 (alist (or pkg-list
182 (remove (assq pkg package-alist)
183 package-alist))))
184 (if all
185 (cl-loop for p in alist
186 if (assq pkg (package-desc-reqs (cadr p)))
187 collect (cadr p))
188 (cl-loop for p in alist thereis
189 (and (assq pkg (package-desc-reqs (cadr p)))
190 (cadr p)))))))
191
192(defun package--sort-deps-in-alist (package only)
193 "Return a list of dependencies for PACKAGE sorted by dependency.
194PACKAGE is included as the first element of the returned list.
195ONLY is an alist associating package names to package objects.
196Only these packages will be in the return value and their cdrs are
197destructively set to nil in ONLY."
198 (let ((out))
199 (dolist (dep (package-desc-reqs package))
200 (when-let* ((cell (assq (car dep) only))
201 (dep-package (cdr-safe cell)))
202 (setcdr cell nil)
203 (setq out (append (package--sort-deps-in-alist dep-package only)
204 out))))
205 (cons package out)))
206
207(defun package--sort-by-dependence (package-list)
208 "Return PACKAGE-LIST sorted by dependence.
209That is, any element of the returned list is guaranteed to not
210directly depend on any elements that come before it.
211
212PACKAGE-LIST is a list of `package-desc' objects.
213Indirect dependencies are guaranteed to be returned in order only
214if all the in-between dependencies are also in PACKAGE-LIST."
215 (let ((alist (mapcar (lambda (p) (cons (package-desc-name p) p)) package-list))
216 out-list)
217 (dolist (cell alist out-list)
218 ;; `package--sort-deps-in-alist' destructively changes alist, so
219 ;; some cells might already be empty. We check this here.
220 (when-let* ((pkg-desc (cdr cell)))
221 (setcdr cell nil)
222 (setq out-list
223 (append (package--sort-deps-in-alist pkg-desc alist)
224 out-list))))))
225
226
227;;; Installation Functions
228;; As opposed to the previous section (which listed some underlying
229;; functions necessary for installation), this one contains the actual
230;; functions that install packages. The package itself can be
231;; installed in a variety of ways (archives, buffer, file), but
232;; requirements (dependencies) are always satisfied by looking in
233;; `package-archive-contents'.
234
235(defun package-archive-base (desc)
236 "Return the package described by DESC."
237 (cdr (assoc (package-desc-archive desc) package-archives)))
238
239(defun package-desc-suffix (pkg-desc)
240 "Return file-name extension of package-desc object PKG-DESC.
241Depending on the `package-desc-kind' of PKG-DESC, this is one of:
242
243 \\='single - \".el\"
244 \\='tar - \".tar\"
245 \\='dir - \"\"
246
247Signal an error if the kind is none of the above."
248 (pcase (package-desc-kind pkg-desc)
249 ('single ".el")
250 ('tar ".tar")
251 ('dir "")
252 (kind (error "Unknown package kind: %s" kind))))
253
254(defun package-install-from-archive (pkg-desc)
255 "Download and install a package defined by PKG-DESC."
256 ;; This won't happen, unless the archive is doing something wrong.
257 (when (eq (package-desc-kind pkg-desc) 'dir)
258 (error "Can't install directory package from archive"))
259 (let* ((location (package-archive-base pkg-desc))
260 (file (concat (package-desc-full-name pkg-desc)
261 (package-desc-suffix pkg-desc))))
262 (package--with-response-buffer location :file file
263 (if (or (not (package-check-signature))
264 (member (package-desc-archive pkg-desc)
265 package-unsigned-archives))
266 ;; If we don't care about the signature, unpack and we're
267 ;; done.
268 (let ((save-silently t))
269 (package-unpack pkg-desc))
270 ;; If we care, check it and *then* write the file.
271 (let ((content (buffer-string)))
272 (package--check-signature
273 location file content nil
274 ;; This function will be called after signature checking.
275 (lambda (&optional good-sigs)
276 ;; Signature checked, unpack now.
277 (with-temp-buffer ;FIXME: Just use the previous current-buffer.
278 (set-buffer-multibyte nil)
279 (cl-assert (not (multibyte-string-p content)))
280 (insert content)
281 (let ((save-silently t))
282 (package-unpack pkg-desc)))
283 ;; Here the package has been installed successfully, mark it as
284 ;; signed if appropriate.
285 (when good-sigs
286 ;; Write out good signatures into NAME-VERSION.signed file.
287 (write-region (mapconcat #'epg-signature-to-string good-sigs "\n")
288 nil
289 (expand-file-name
290 (concat (package-desc-full-name pkg-desc) ".signed")
291 package-user-dir)
292 nil 'silent)
293 ;; Update the old pkg-desc which will be shown on the description buffer.
294 (setf (package-desc-signed pkg-desc) t)
295 ;; Update the new (activated) pkg-desc as well.
296 (when-let* ((pkg-descs (cdr (assq (package-desc-name pkg-desc)
297 package-alist))))
298 (setf (package-desc-signed (car pkg-descs)) t))))))))))
299
300;;;###autoload
301(defun package-installed-p (package &optional min-version)
302 "Return non-nil if PACKAGE, of MIN-VERSION or newer, is installed.
303If PACKAGE is a symbol, it is the package name and MIN-VERSION
304should be a version list.
305
306If PACKAGE is a `package-desc' object, MIN-VERSION is ignored."
307 (cond
308 ((package-desc-p package)
309 (let ((dir (package-desc-dir package)))
310 (and (stringp dir)
311 (file-exists-p dir))))
312 ((and (not package--initialized)
313 (null min-version)
314 package-activated-list)
315 ;; We used the quickstart: make it possible to use package-installed-p
316 ;; even before package is fully initialized.
317 (or
318 (memq package package-activated-list)
319 ;; Also check built-in packages.
320 (package-built-in-p package min-version)))
321 (t
322 (or
323 (let ((pkg-descs (cdr (assq package (package--alist)))))
324 (and pkg-descs
325 (version-list-<= min-version
326 (package-desc-version (car pkg-descs)))))
327 ;; Also check built-in packages.
328 (package-built-in-p package min-version)))))
329
330(defun package-download-transaction (packages)
331 "Download and install all the packages in PACKAGES.
332PACKAGES should be a list of `package-desc'.
333This function assumes that all package requirements in
334PACKAGES are satisfied, i.e. that PACKAGES is computed
335using `package-compute-transaction'."
336 (mapc #'package-install-from-archive packages))
337
338;;;###autoload
339(defun package-install (pkg &optional dont-select)
340 "Install the package PKG.
341
342PKG can be a `package-desc', or a symbol naming one of the available
343packages in an archive in `package-archives'.
344
345Mark the installed package as selected by adding it to
346`package-selected-packages'.
347
348When called from Lisp and optional argument DONT-SELECT is
349non-nil, install the package but do not add it to
350`package-selected-packages'.
351
352If PKG is a `package-desc' and it is already installed, don't try
353to install it but still mark it as selected.
354
355If the command is invoked with a prefix argument, it will allow
356upgrading of built-in packages, as if `package-install-upgrade-built-in'
357had been enabled."
358 (interactive
359 (progn
360 ;; Initialize the package system to get the list of package
361 ;; symbols for completion.
362 (package--archives-initialize)
363 (list (intern (completing-read
364 "Install package: "
365 (mapcan
366 (lambda (elt)
367 (and (or (and (or current-prefix-arg
368 package-install-upgrade-built-in)
369 (package--active-built-in-p (car elt)))
370 (not (package-installed-p (car elt))))
371 (list (symbol-name (car elt)))))
372 package-archive-contents)
373 nil t))
374 nil)))
375 (cl-check-type pkg (or symbol package-desc))
376 (package--archives-initialize)
377 (when (fboundp 'package-menu--post-refresh)
378 (add-hook 'post-command-hook #'package-menu--post-refresh))
379 (let ((name (if (package-desc-p pkg)
380 (package-desc-name pkg)
381 pkg)))
382 (unless (or dont-select (package--user-selected-p name))
383 (package--save-selected-packages
384 (cons name package-selected-packages)))
385 (when (and (or current-prefix-arg package-install-upgrade-built-in)
386 (package--active-built-in-p pkg))
387 (setq pkg (or (cadr (assq name package-archive-contents)) pkg)))
388 (if-let* ((transaction
389 (if (package-desc-p pkg)
390 (unless (package-installed-p pkg)
391 (package-compute-transaction (list pkg)
392 (package-desc-reqs pkg)))
393 (package-compute-transaction () (list (list pkg))))))
394 (progn
395 (package-download-transaction transaction)
396 (package--quickstart-maybe-refresh)
397 (message "Package `%s' installed." name))
398 (message "`%s' is already installed" name))))
399
400(declare-function package-vc-upgrade "package-vc" (pkg))
401
402;;;###autoload
403(defun package-upgrade (name)
404 "Upgrade package NAME if a newer version exists.
405
406NAME should be a symbol."
407 (interactive
408 (list (intern (completing-read
409 "Upgrade package: "
410 (package--upgradeable-packages t) nil t))))
411 (cl-check-type name symbol)
412 (let* ((pkg-desc (cadr (assq name package-alist)))
413 (package-install-upgrade-built-in (not pkg-desc)))
414 ;; `pkg-desc' will be nil when the package is an "active built-in".
415 (if (and pkg-desc (package-vc-p pkg-desc))
416 (package-vc-upgrade pkg-desc)
417 (when pkg-desc
418 (package-delete pkg-desc 'force 'dont-unselect))
419 (package-install name
420 ;; An active built-in has never been "selected"
421 ;; before. Mark it as installed explicitly.
422 (and pkg-desc 'dont-select)))))
423
424(defun package--upgradeable-packages (&optional include-builtins)
425 ;; Initialize the package system to get the list of package
426 ;; symbols for completion.
427 (package--archives-initialize)
428 (mapcar
429 #'car
430 (seq-filter
431 (lambda (elt)
432 (or (let ((available
433 (assq (car elt) package-archive-contents)))
434 (and available
435 (or (and
436 include-builtins
437 (not (package-desc-version (cadr elt))))
438 (version-list-<
439 (package-desc-version (cadr elt))
440 (package-desc-version (cadr available))))))
441 (package-vc-p (cadr elt))))
442 (if include-builtins
443 (append package-alist
444 (mapcan
445 (lambda (elt)
446 (when (not (assq (car elt) package-alist))
447 (list (list (car elt) (package--from-builtin elt)))))
448 package--builtins))
449 package-alist))))
450
451;;;###autoload
452(defun package-upgrade-all (&optional query)
453 "Refresh package list and upgrade all packages.
454If QUERY, ask the user before upgrading packages. When called
455interactively, QUERY is always true.
456
457Currently, packages which are part of the Emacs distribution are
458not upgraded by this command. To enable upgrading such a package
459using this command, first upgrade the package to a newer version
460from ELPA by either using `\\[package-upgrade]' or
461`\\<package-menu-mode-map>\\[package-menu-mark-install]' after `\\[list-packages]'."
462 (interactive (list (not noninteractive)))
463 (package-refresh-contents)
464 (let ((upgradeable (package--upgradeable-packages)))
465 (if (not upgradeable)
466 (message "No packages to upgrade")
467 (when (and query
468 (not (yes-or-no-p
469 (if (length= upgradeable 1)
470 "One package to upgrade. Do it? "
471 (format "%s packages to upgrade. Do it?"
472 (length upgradeable))))))
473 (user-error "Upgrade aborted"))
474 (mapc #'package-upgrade upgradeable))))
475
476(defun package--dependencies (pkg)
477 "Return a list of all transitive dependencies of PKG.
478If PKG is a package descriptor, the return value is a list of
479package descriptors. If PKG is a symbol designating a package,
480the return value is a list of symbols designating packages."
481 (when-let* ((desc (if (package-desc-p pkg) pkg
482 (cadr (assq pkg package-archive-contents)))))
483 ;; Can we have circular dependencies? Assume "nope".
484 (let ((all (named-let more ((pkg-desc desc))
485 (let (deps)
486 (dolist (req (package-desc-reqs pkg-desc))
487 (setq deps (nconc
488 (catch 'found
489 (dolist (p (apply #'append (mapcar #'cdr (package--alist))))
490 (when (and (string= (car req) (package-desc-name p))
491 (version-list-<= (cadr req) (package-desc-version p)))
492 (throw 'found (more p)))))
493 deps)))
494 (delete-dups (cons pkg-desc deps))))))
495 (remq pkg (mapcar (if (package-desc-p pkg) #'identity #'package-desc-name) all)))))
496
497(defun package-buffer-info ()
498 "Return a `package-desc' describing the package in the current buffer.
499
500If the buffer does not contain a conforming package, signal an
501error. If there is a package, narrow the buffer to the file's
502boundaries."
503 (goto-char (point-min))
504 (unless (re-search-forward "^;;; \\([^ ]*\\)\\.el ---[ \t]*\\(.*?\\)[ \t]*\\(-\\*-.*-\\*-[ \t]*\\)?$" nil t)
505 (error "Package lacks a file header"))
506 (let ((file-name (match-string-no-properties 1))
507 (desc (match-string-no-properties 2)))
508 (require 'lisp-mnt)
509 (let* ((version-info (lm-package-version))
510 (pkg-version (package-strip-rcs-id version-info))
511 (keywords (lm-keywords-list))
512 (website (lm-website)))
513 (unless pkg-version
514 (if version-info
515 (error "Unrecognized package version: %s" version-info)
516 (error "Package lacks a \"Version\" or \"Package-Version\" header")))
517 (package-desc-from-define
518 file-name pkg-version desc
519 (lm-package-requires)
520 :kind 'single
521 :url website
522 :keywords keywords
523 :maintainer
524 ;; For backward compatibility, use a single cons-cell if
525 ;; there's only one maintainer (the most common case).
526 (let ((maints (lm-maintainers))) (if (cdr maints) maints (car maints)))
527 :authors (lm-authors)))))
528
529(defun package-dir-info ()
530 "Find package information for a directory.
531The return result is a `package-desc'."
532 (cl-assert (derived-mode-p 'dired-mode))
533 (let* ((desc-file (package--description-file default-directory)))
534 (if (file-readable-p desc-file)
535 (with-temp-buffer
536 (insert-file-contents desc-file)
537 (package--read-pkg-desc 'dir))
538 (catch 'found
539 (let ((files (or (and (derived-mode-p 'dired-mode)
540 (dired-get-marked-files))
541 (directory-files-recursively default-directory "\\.el\\'"))))
542 ;; We sort the file names in lexicographical order, to ensure
543 ;; that we check shorter file names first (ie. those further
544 ;; up in the directory structure).
545 (dolist (file (sort files))
546 ;; The file may be a link to a nonexistent file; e.g., a
547 ;; lock file.
548 (when (file-exists-p file)
549 (with-temp-buffer
550 (insert-file-contents file)
551 ;; When we find the file with the data,
552 (when-let* ((info (ignore-errors (package-buffer-info))))
553 (setf (package-desc-kind info) 'dir)
554 (throw 'found info))))))
555 (error "No .el files with package headers in `%s'" default-directory)))))
556
557;;;###autoload
558(defun package-install-from-buffer ()
559 "Install a package from the current buffer.
560The current buffer is assumed to be a single .el or .tar file or
561a directory. These must follow the packaging guidelines (see
562info node `(elisp)Packaging').
563
564Specially, if current buffer is a directory, the -pkg.el
565description file is not mandatory, in which case the information
566is derived from the main .el file in the directory. Using Dired,
567you can restrict what files to install by marking specific files.
568
569Downloads and installs required packages as needed."
570 (interactive)
571 (let* ((pkg-desc
572 (cond
573 ((derived-mode-p 'dired-mode)
574 ;; This is the only way a package-desc object with a `dir'
575 ;; desc-kind can be created. Such packages can't be
576 ;; uploaded or installed from archives, they can only be
577 ;; installed from local buffers or directories.
578 (package-dir-info))
579 ((derived-mode-p 'tar-mode)
580 (package-tar-file-info))
581 (t
582 ;; Package headers should be parsed from decoded text
583 ;; (see Bug#48137) where possible.
584 (if (and (eq buffer-file-coding-system 'no-conversion)
585 buffer-file-name)
586 (let* ((package-buffer (current-buffer))
587 (decoding-system
588 (car (find-operation-coding-system
589 'insert-file-contents
590 (cons buffer-file-name
591 package-buffer)))))
592 (with-temp-buffer
593 (insert-buffer-substring package-buffer)
594 (decode-coding-region (point-min) (point-max)
595 decoding-system)
596 (package-buffer-info)))
597
598 (save-excursion
599 (package-buffer-info))))))
600 (name (package-desc-name pkg-desc)))
601 ;; Download and install the dependencies.
602 (let* ((requires (package-desc-reqs pkg-desc))
603 (transaction (package-compute-transaction nil requires)))
604 (package-download-transaction transaction))
605 ;; Install the package itself.
606 (package-unpack pkg-desc)
607 (unless (package--user-selected-p name)
608 (package--save-selected-packages
609 (cons name package-selected-packages)))
610 (package--quickstart-maybe-refresh)
611 pkg-desc))
612
613;;;###autoload
614(defun package-install-file (file)
615 "Install a package from FILE.
616The file can either be a tar file, an Emacs Lisp file, or a
617directory."
618 (interactive "fPackage file name: ")
619 (with-temp-buffer
620 (if (file-directory-p file)
621 (progn
622 (setq default-directory file)
623 (dired-mode))
624 (insert-file-contents-literally file)
625 (set-visited-file-name file)
626 (set-buffer-modified-p nil)
627 (when (string-match "\\.tar\\'" file) (tar-mode)))
628 (package-install-from-buffer)))
629
630
631
632;;;###autoload
633(defun package-install-selected-packages (&optional noconfirm)
634 "Ensure packages in `package-selected-packages' are installed.
635If some packages are not installed, propose to install them.
636
637If optional argument NOCONFIRM is non-nil, or when invoked with a prefix
638argument, don't ask for confirmation to install packages."
639 (interactive "P")
640 (package--archives-initialize)
641 ;; We don't need to populate `package-selected-packages' before
642 ;; using here, because the outcome is the same either way (nothing
643 ;; gets installed).
644 (if (not package-selected-packages)
645 (message "`package-selected-packages' is empty, nothing to install")
646 (let* ((not-installed (seq-remove #'package-installed-p package-selected-packages))
647 (available (seq-filter (lambda (p) (assq p package-archive-contents)) not-installed))
648 (difference (- (length not-installed) (length available))))
649 (cond
650 (available
651 (when (or noconfirm
652 (y-or-n-p
653 (format "Packages to install: %d (%s), proceed? "
654 (length available)
655 (mapconcat #'symbol-name available " "))))
656 (mapc (lambda (p) (package-install p 'dont-select)) available)))
657 ((> difference 0)
658 (message (substitute-command-keys
659 "Packages that are not available: %d (the rest is already \
660installed), maybe you need to \\[package-refresh-contents]")
661 difference))
662 (t
663 (message "All your packages are already installed"))))))
664
665(defun package--newest-p (pkg)
666 "Return non-nil if PKG is the newest package with its name."
667 (equal (cadr (assq (package-desc-name pkg) package-alist))
668 pkg))
669
670(declare-function comp-el-to-eln-filename "comp.c")
671(defvar package-vc-repository-store)
672(defun package--delete-directory (dir)
673 "Delete PKG-DESC directory DIR recursively.
674Clean-up the corresponding .eln files if Emacs is native
675compiled."
676 (when (featurep 'native-compile)
677 (cl-loop
678 for file in (directory-files-recursively dir
679 ;; Exclude lockfiles
680 (rx bos (or (and "." (not "#")) (not ".")) (* nonl) ".el" eos))
681 do (comp-clean-up-stale-eln (comp-el-to-eln-filename file))))
682 (if (file-symlink-p (directory-file-name dir))
683 (delete-file (directory-file-name dir))
684 (delete-directory dir t)))
685
686(defun package-delete (pkg-desc &optional force nosave)
687 "Delete package PKG-DESC.
688
689Argument PKG-DESC is the full description of the package, for example as
690obtained by `package-get-descriptor'. Interactively, prompt the user
691for the package name and version.
692
693When package is used elsewhere as dependency of another package,
694refuse deleting it and return an error.
695If prefix argument FORCE is non-nil, package will be deleted even
696if it is used elsewhere.
697If NOSAVE is non-nil, the package is not removed from
698`package-selected-packages'."
699 (interactive
700 (progn
701 (let* ((package-table
702 (mapcar
703 (lambda (p) (cons (package-desc-full-name p) p))
704 (delq nil
705 (mapcar (lambda (p) (unless (package-built-in-p p) p))
706 (apply #'append (mapcar #'cdr (package--alist)))))))
707 (package-name (completing-read "Delete package: "
708 (mapcar #'car package-table)
709 nil t)))
710 (list (cdr (assoc package-name package-table))
711 current-prefix-arg nil))))
712 (let* ((dir (package-desc-dir pkg-desc))
713 (name (package-desc-name pkg-desc))
714 (new-package-alist (let ((pkgs (assq name package-alist)))
715 (if (null (remove pkg-desc (cdr pkgs)))
716 (remq pkgs package-alist)
717 package-alist)))
718 pkg-used-elsewhere-by)
719 ;; If the user is trying to delete this package, they definitely
720 ;; don't want it marked as selected, so we remove it from
721 ;; `package-selected-packages' even if it can't be deleted.
722 (when (and (null nosave)
723 (package--user-selected-p name)
724 ;; Don't deselect if this is an older version of an
725 ;; upgraded package.
726 (package--newest-p pkg-desc))
727 (package--save-selected-packages (remove name package-selected-packages)))
728 (cond ((not (string-prefix-p (file-name-as-directory
729 (expand-file-name package-user-dir))
730 (expand-file-name dir)))
731 ;; Don't delete "system" packages.
732 (error "Package `%s' is a system package, not deleting"
733 (package-desc-full-name pkg-desc)))
734 ((and (null force)
735 (setq pkg-used-elsewhere-by
736 (let ((package-alist new-package-alist))
737 (package--used-elsewhere-p pkg-desc)))) ;See bug#65475
738 ;; Don't delete packages used as dependency elsewhere.
739 (error "Package `%s' is used by `%s' as dependency, not deleting"
740 (package-desc-full-name pkg-desc)
741 (package-desc-name pkg-used-elsewhere-by)))
742 (t
743 (add-hook 'post-command-hook 'package-menu--post-refresh)
744 (package--delete-directory dir)
745 ;; Remove NAME-VERSION.signed and NAME-readme.txt files.
746 ;;
747 ;; NAME-readme.txt files are no longer created, but they
748 ;; may be left around from an earlier install.
749 (dolist (suffix '(".signed" "readme.txt"))
750 (let* ((version (package-version-join (package-desc-version pkg-desc)))
751 (file (concat (if (string= suffix ".signed")
752 dir
753 (substring dir 0 (- (length version))))
754 suffix)))
755 (when (file-exists-p file)
756 (delete-file file))))
757 ;; Update package-alist.
758 (setq package-alist new-package-alist)
759 (package--quickstart-maybe-refresh)
760 (message "Package `%s' deleted."
761 (package-desc-full-name pkg-desc))))))
762
763;;;###autoload
764(defun package-reinstall (pkg)
765 "Reinstall package PKG.
766PKG should be either a symbol, the package name, or a `package-desc'
767object."
768 (interactive
769 (progn
770 (package--archives-initialize)
771 (list (intern (completing-read
772 "Reinstall package: "
773 (mapcar #'symbol-name
774 (mapcar #'car package-alist)))))))
775 (package--archives-initialize)
776 (package-delete
777 (if (package-desc-p pkg) pkg (cadr (assq pkg package-alist)))
778 'force 'nosave)
779 (package-install pkg 'dont-select))
780
781;;;###autoload
782(defun package-autoremove (&optional noconfirm)
783 "Remove packages that are no longer needed.
784
785Packages that are no more needed by other packages in
786`package-selected-packages' and their dependencies
787will be deleted.
788
789If optional argument NOCONFIRM is non-nil, or when invoked with a prefix
790argument, don't ask for confirmation to install packages."
791 (interactive "P")
792 ;; If `package-selected-packages' is nil, it would make no sense to
793 ;; try to populate it here, because then `package-autoremove' will
794 ;; do absolutely nothing.
795 (when (or noconfirm
796 package-selected-packages
797 (yes-or-no-p
798 (format-message
799 "`package-selected-packages' is empty! Really remove ALL packages? ")))
800 (let ((removable (package--removable-packages)))
801 (if removable
802 (when (or noconfirm
803 (y-or-n-p
804 (format "Packages to delete: %d (%s), proceed? "
805 (length removable)
806 (mapconcat #'symbol-name removable " "))))
807 (mapc (lambda (p)
808 (package-delete (cadr (assq p package-alist)) t))
809 removable))
810 (message "Nothing to autoremove")))))
811
812
813;;;; Autoload
814(declare-function autoload-rubric "autoload" (file &optional type feature))
815
816(defun package-autoload-ensure-default-file (file)
817 "Make sure that the autoload file FILE exists and if not create it."
818 (declare (obsolete nil "29.1"))
819 (unless (file-exists-p file)
820 (require 'autoload)
821 (let ((coding-system-for-write 'utf-8-emacs-unix))
822 (with-suppressed-warnings ((obsolete autoload-rubric))
823 (write-region (autoload-rubric file "package" nil)
824 nil file nil 'silent))))
825 file)
826
827(defvar autoload-timestamps)
828(defvar version-control)
829
830(defun package-generate-autoloads (name pkg-dir)
831 "Generate autoloads in PKG-DIR for package named NAME."
832 (let* ((auto-name (format "%s-autoloads.el" name))
833 ;;(ignore-name (concat name "-pkg.el"))
834 (output-file (expand-file-name auto-name pkg-dir))
835 ;; We don't need 'em, and this makes the output reproducible.
836 (autoload-timestamps nil)
837 (backup-inhibited t)
838 (version-control 'never))
839 (loaddefs-generate
840 pkg-dir output-file nil
841 (prin1-to-string
842 '(add-to-list
843 'load-path
844 ;; Add the directory that will contain the autoload file to
845 ;; the load path. We don't hard-code `pkg-dir', to avoid
846 ;; issues if the package directory is moved around.
847 ;; `loaddefs-generate' has code to do this for us, but it's
848 ;; not currently exposed. (Bug#63625)
849 (or (and load-file-name
850 (directory-file-name
851 (file-name-directory load-file-name)))
852 (car load-path)))))
853 (let ((buf (find-buffer-visiting output-file)))
854 (when buf (kill-buffer buf)))
855 auto-name))
856
857(defun package--make-autoloads-and-stuff (pkg-desc pkg-dir)
858 "Generate autoloads, description file, etc., for PKG-DESC installed at PKG-DIR."
859 (package-generate-autoloads (package-desc-name pkg-desc) pkg-dir)
860 (let ((desc-file (expand-file-name (package--description-file pkg-dir)
861 pkg-dir)))
862 (unless (file-exists-p desc-file)
863 (package-generate-description-file pkg-desc desc-file)))
864 ;; FIXME: Create foo.info and dir file from foo.texi?
865 )
866
867(defun package-tar-file-info ()
868 "Find package information for a tar file.
869The return result is a `package-desc'."
870 (cl-assert (derived-mode-p 'tar-mode))
871 (let* ((dir-name (named-let loop
872 ((filename (tar-header-name (car tar-parse-info))))
873 (let ((dirname (file-name-directory filename)))
874 ;; The first file can be in a subdir: look for the top.
875 (if dirname (loop (directory-file-name dirname))
876 (file-name-as-directory filename)))))
877 (desc-file (package--description-file dir-name))
878 (tar-desc (tar-get-file-descriptor (concat dir-name desc-file))))
879 (unless tar-desc
880 (error "No package descriptor file found"))
881 (with-current-buffer (tar--extract tar-desc)
882 (unwind-protect
883 (or (package--read-pkg-desc 'tar)
884 (error "Can't find define-package in %s"
885 (tar-header-name tar-desc)))
886 (kill-buffer (current-buffer))))))
887
888(defun package-untar-buffer (dir)
889 "Untar the current buffer.
890This uses `tar-untar-buffer' from Tar mode. All files should
891untar into a directory named DIR; otherwise, signal an error."
892 (tar-mode)
893 ;; Make sure everything extracts into DIR.
894 (let ((regexp (concat "\\`" (regexp-quote (expand-file-name dir)) "/"))
895 (case-fold-search (file-name-case-insensitive-p dir)))
896 (dolist (tar-data tar-parse-info)
897 (let ((name (expand-file-name (tar-header-name tar-data))))
898 (or (string-match regexp name)
899 ;; Tarballs created by some utilities don't list
900 ;; directories with a trailing slash (Bug#13136).
901 (and (string-equal (expand-file-name dir) name)
902 (eq (tar-header-link-type tar-data) 5))
903 (error "Package does not untar cleanly into directory %s/" dir)))))
904 (tar-untar-buffer))
905
906(declare-function dired-get-marked-files "dired")
907
908(defun package-unpack (pkg-desc)
909 "Install the contents of the current buffer as a package."
910 (let* ((name (package-desc-name pkg-desc))
911 (dirname (package-desc-full-name pkg-desc))
912 (pkg-dir (expand-file-name dirname package-user-dir)))
913 (pcase (package-desc-kind pkg-desc)
914 ('dir
915 (make-directory pkg-dir t)
916 (let ((file-list
917 (or (and (derived-mode-p 'dired-mode)
918 (dired-get-marked-files))
919 (directory-files-recursively default-directory "" nil))))
920 (dolist (source-file file-list)
921 (let ((target (expand-file-name
922 (file-relative-name source-file default-directory)
923 pkg-dir)))
924 (make-directory (file-name-directory target) t)
925 (copy-file source-file target t)))
926 ;; Now that the files have been installed, this package is
927 ;; indistinguishable from a `tar' or a `single'. Let's make
928 ;; things simple by ensuring we're one of them.
929 (setf (package-desc-kind pkg-desc)
930 (if (length> file-list 1) 'tar 'single))))
931 ('tar
932 (make-directory package-user-dir t)
933 (let* ((default-directory (file-name-as-directory package-user-dir)))
934 (package-untar-buffer dirname)))
935 ('single
936 (let ((el-file (expand-file-name (format "%s.el" name) pkg-dir)))
937 (make-directory pkg-dir t)
938 (package--write-file-no-coding el-file)))
939 (kind (error "Unknown package kind: %S" kind)))
940 (package--make-autoloads-and-stuff pkg-desc pkg-dir)
941 ;; Update package-alist.
942 (let ((new-desc (package-load-descriptor pkg-dir)))
943 (unless (equal (package-desc-full-name new-desc)
944 (package-desc-full-name pkg-desc))
945 (error "The retrieved package (`%s') doesn't match what the archive offered (`%s')"
946 (package-desc-full-name new-desc) (package-desc-full-name pkg-desc)))
947 ;; Activation has to be done before compilation, so that if we're
948 ;; upgrading and macros have changed we load the new definitions
949 ;; before compiling.
950 (when (package-activate-1 new-desc :reload :deps)
951 ;; FIXME: Compilation should be done as a separate, optional, step.
952 ;; E.g. for multi-package installs, we should first install all packages
953 ;; and then compile them.
954 (package--compile new-desc)
955 (when package-native-compile
956 (package--native-compile-async new-desc))
957 ;; After compilation, load again any files loaded by
958 ;; `activate-1', so that we use the byte-compiled definitions.
959 (package--reload-previously-loaded new-desc)))
960 pkg-dir))
961
962(defun package-generate-description-file (pkg-desc pkg-file)
963 "Create the foo-pkg.el file PKG-FILE for single-file package PKG-DESC."
964 (let* ((name (package-desc-name pkg-desc)))
965 (let ((print-level nil)
966 (print-quoted t)
967 (print-length nil))
968 (write-region
969 (concat
970 ";;; Generated package description from "
971 (replace-regexp-in-string "-pkg\\.el\\'" ".el"
972 (file-name-nondirectory pkg-file))
973 " -*- no-byte-compile: t -*-\n"
974 (prin1-to-string
975 (nconc
976 (list 'define-package
977 (symbol-name name)
978 (package-version-join (package-desc-version pkg-desc))
979 (package-desc-summary pkg-desc)
980 (let ((requires (package-desc-reqs pkg-desc)))
981 (list 'quote
982 ;; Turn version lists into string form.
983 (mapcar
984 (lambda (elt)
985 (list (car elt)
986 (package-version-join (cadr elt))))
987 requires))))
988 (package--alist-to-plist-args
989 (package-desc-extras pkg-desc))))
990 "\n")
991 nil pkg-file nil 'silent))))
992
993;;;###autoload
994(defun package-isolate (packages &optional temp-init)
995 "Start an uncustomized Emacs and only load a set of PACKAGES.
996Interactively, prompt for PACKAGES to load, which should be specified
997separated by commas.
998If called from Lisp, PACKAGES should be a list of packages to load.
999If TEMP-INIT is non-nil, or when invoked with a prefix argument,
1000the Emacs user directory is set to a temporary directory.
1001This command is intended for testing Emacs and/or the packages
1002in a clean environment."
1003 (interactive
1004 (cl-loop for p in (cl-loop for p in (package--alist) append (cdr p))
1005 unless (package-built-in-p p)
1006 collect (cons (package-desc-full-name p) p) into table
1007 finally return
1008 (list
1009 (cl-loop for c in
1010 (completing-read-multiple
1011 "Packages to isolate: " table
1012 nil t)
1013 collect (alist-get c table nil nil #'string=))
1014 current-prefix-arg)))
1015 (let* ((name (concat "package-isolate-"
1016 (mapconcat #'package-desc-full-name packages ",")))
1017 (all-packages (delete-consecutive-dups
1018 (sort (append packages (mapcan #'package--dependencies packages))
1019 (lambda (p0 p1)
1020 (string< (package-desc-name p0) (package-desc-name p1))))))
1021 initial-scratch-message package-load-list)
1022 (with-temp-buffer
1023 (insert ";; This is an isolated testing environment, with these packages enabled:\n\n")
1024 (dolist (package all-packages)
1025 (push (list (package-desc-name package)
1026 (package-version-join (package-desc-version package)))
1027 package-load-list)
1028 (insert ";; - " (package-desc-full-name package))
1029 (unless (memq package packages)
1030 (insert " (dependency)"))
1031 (insert "\n"))
1032 (insert "\n")
1033 (setq initial-scratch-message (buffer-string)))
1034 (apply #'start-process (concat "*" name "*") nil
1035 (list (expand-file-name invocation-name invocation-directory)
1036 "--quick" "--debug-init"
1037 "--init-directory" (if temp-init
1038 (make-temp-file name t)
1039 user-emacs-directory)
1040 (format "--eval=%S"
1041 `(progn
1042 (setq initial-scratch-message ,initial-scratch-message)
1043
1044 (require 'package)
1045 ,@(mapcar
1046 (lambda (dir)
1047 `(add-to-list 'package-directory-list ,dir))
1048 (cons package-user-dir package-directory-list))
1049 (setq package-load-list ',package-load-list)
1050 (package-activate-all)))))))
1051
1052(provide 'package-install)
1053;;; package-install.el ends here