1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-23 04:53:12 -08:00

Allow 'package-isolate' to fetch missing packages

* lisp/emacs-lisp/package.el (package-isolate): Fetch missing
packages and make them available in the new Emacs process, but
not the current one.
* etc/NEWS: Mention change.
This commit is contained in:
Philip Kaludercic 2025-12-23 19:39:31 +01:00
parent 881be95cdd
commit c8d19034aa
No known key found for this signature in database
2 changed files with 31 additions and 16 deletions

View file

@ -2804,6 +2804,11 @@ When called from Lisp, it now only accepts a symbol.
When invoking the command in a Dired buffer with marked files,
the command will only copy those files.
---
*** 'package-isolate' can now also install packages.
If a package is missing, 'package-isolate' will fetch the missing
tarballs and prepare them to be activated in the sub-process.
+++
*** package-x.el is now obsolete.

View file

@ -2484,14 +2484,16 @@ argument, don't ask for confirmation to install packages."
(defun package-isolate (packages &optional temp-init)
"Start an uncustomized Emacs and only load a set of PACKAGES.
Interactively, prompt for PACKAGES to load, which should be specified
separated by commas.
If called from Lisp, PACKAGES should be a list of packages to load.
If TEMP-INIT is non-nil, or when invoked with a prefix argument,
the Emacs user directory is set to a temporary directory.
This command is intended for testing Emacs and/or the packages
in a clean environment."
separated by commas. If called from Lisp, PACKAGES should be a list of
`package-desc' objects to load. If an element of PACKAGES is not
installed, it will be fetched, but not activated in the current session.
If TEMP-INIT is non-nil, or when invoked with a prefix argument, the
Emacs user directory is set to a temporary directory. This command is
intended for testing Emacs and/or the packages in a clean environment."
(interactive
(cl-loop for p in (cl-loop for p in (package--alist) append (cdr p))
(cl-loop for p in (append
(cl-loop for p in (package--alist) append (cdr p))
(cl-loop for p in package-archive-contents append (cdr p)))
unless (package-built-in-p p)
collect (cons (package-desc-full-name p) p) into table
finally return
@ -2500,21 +2502,27 @@ in a clean environment."
(completing-read-multiple
"Packages to isolate: " table
nil t)
collect (alist-get c table nil nil #'string=))
current-prefix-arg)))
collect (alist-get c table nil nil #'string=))
current-prefix-arg)))
(let* ((name (concat "package-isolate-"
(mapconcat #'package-desc-full-name packages ",")))
(all-packages (delete-consecutive-dups
(sort (append packages (mapcan #'package--dependencies packages))
(lambda (p0 p1)
(string< (package-desc-name p0) (package-desc-name p1))))))
initial-scratch-message package-load-list)
(all-packages (package-compute-transaction
packages (mapcan #'package-desc-reqs packages)))
(package-alist (copy-tree package-alist t))
(temp-install-dir nil) initial-scratch-message load-list)
(when-let* ((missing (seq-remove #'package-installed-p all-packages))
(package-user-dir (make-temp-file "package-isolate" t)))
(setq temp-install-dir (list package-user-dir))
;; We bind `package-activate-1' to prevent activating the package
;; in `package-unpack' for this session.
(cl-letf (((symbol-function #'package-activate-1) #'ignore))
(package-download-transaction missing)))
(with-temp-buffer
(insert ";; This is an isolated testing environment, with these packages enabled:\n\n")
(dolist (package all-packages)
(push (list (package-desc-name package)
(package-version-join (package-desc-version package)))
package-load-list)
load-list)
(insert ";; - " (package-desc-full-name package))
(unless (memq package packages)
(insert " (dependency)"))
@ -2535,7 +2543,9 @@ in a clean environment."
,@(mapcar
(lambda (dir)
`(add-to-list 'package-directory-list ,dir))
(cons package-user-dir package-directory-list))
(append (list package-user-dir)
temp-install-dir
package-directory-list))
(setq package-load-list ',package-load-list)
(package-activate-all)))))))