From: Philip Kaludercic <philipk@posteo.net>
To: Thierry Volpiatto <thievol@posteo.net>
Cc: emacs-devel@gnu.org
Subject: Re: Changes to make in elpa-packages file for nongnu elpa
Date: Wed, 16 Aug 2023 10:10:46 +0000 [thread overview]
Message-ID: <87zg2ri9g9.fsf@posteo.net> (raw)
In-Reply-To: <87pm3nlbm7.fsf@posteo.net> (Thierry Volpiatto's message of "Wed, 16 Aug 2023 06:51:29 +0000")
[-- Attachment #1: Type: text/plain, Size: 4087 bytes --]
Thierry Volpiatto <thievol@posteo.net> writes:
> Philip Kaludercic <philipk@posteo.net> writes:
>
>> Philip Kaludercic <philipk@posteo.net> writes:
>>
>>>>>> It is used specially for reproducing bugs in a clean environment, see it
>>>>>> as emacs -Q for Emacs when reporting bugs. This script starts Emacs -Q
>>>>>> with only Helm loaded, this ensure the bug if one comes from Helm and
>>>>>> not another package. This is important especially nowaday people are
>>>>>> using "Emacs distribution" with the world list of packages installed.
>>>>>> Apart that the script is useful to quickly launch Emacs with helm, one
>>>>>> can use it from the Helm directory or symlinked to e.g. ~/bin.
>>>>>
>>>>> I see. In that case is there any reason you implement this as a shell
>>>>> script?
>>>>
>>>> Well when I wrote the script, packages where not existing and from
>>>> outside emacs it is actually the only way to run a package isolated.
>>>>
>>>>> (It might be interesting to provide something like this for
>>>>> package.el, to test packages in a generic way.)
>>>>
>>>> Yes, this would be interesting, it would be something like this:
>>>>
>>>> Emacs -Q
>>>> M-x <A command that run a package alone, isolated from other
>>>> packages nuisances>
>>>
>>> I was actually thinking of a command like
>>>
>>> M-x package-isolate RET foo,bar,baz RET
>>>
>>> and a new instance of Emacs using -Q is spun up, with all the packages
>>> you have listed loaded, and nothing else... Sounds like a fun little
>>> weekend project ;^)
>>
>> Here is my first attempt at providing this kind of a command. Any
>> comments?
>
> Why not reusing package.el functions?
> Why do you want to start in an isolated elpa directory?
> Isn't something like this suffice? (just missing to fallback to CRM when
> helm is not available)
I don't know much about Helm, but does it not support CRM?
> (defun package-isolate (packages)
> "Start an uncustomised Emacs and only load a set of PACKAGES."
> (interactive
> (list (let ((helm-comp-read-use-marked t))
> (completing-read "Packages: " (mapcar #'car (package--alist))))))
This doesn't allow selecting specific package versions, in case multiple
are installed (which might easily happen if you use package-vc). I
stole the code in my patch from package-delete, and I guess it would be
possible to generalise it into a utility function.
> (let* ((name (concat "package-isolate-" (mapconcat #'identity
> packages ",")))
This doesn't work, because the above returns a string, not a list of strings.
> (deps (cl-loop for p in packages
> for sym = (intern p)
> append (package--dependencies sym))))
> (apply #'start-process (concat "*" name "*") nil
> (list (file-truename (expand-file-name invocation-name invocation-directory))
> "--quick" "--debug-init"
> (format "--eval=%S"
> `(progn
> (require 'warnings)
> (add-to-list 'warning-suppress-log-types 'initialization)
> (require 'package)
> (setq package-load-list
> ',(append (mapcar (lambda (p) (list (intern p) t)) packages)
> (mapcar (lambda (p) (list p t)) deps)))
> (package-initialize)))))))
This is actually a good idea, assuming there are no issues with lexical
scoping that might arise from --eval. I didn't think of using
package-load-list here, but it seems that this only works if we don't
add --init-directory, because otherwise the elpa/ directory is not
populated. It seems to me, that for a proper isolated environment, we
should add a --init-directory option. This is easy to fix though, we
just need to specify `package-user-dir' at startup. Here is my updated
patch, merging our approaches:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-command-to-start-Emacs-with-specific-packages.patch --]
[-- Type: text/x-diff, Size: 4878 bytes --]
From 6ae48d6d28112d487ea09ca905814da47c2a26cf Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Tue, 15 Aug 2023 18:39:14 +0200
Subject: [PATCH] Add command to start Emacs with specific packages
* lisp/emacs-lisp/package.el (package--dependencies): Extend function
to handle and return package descriptors.
(package-isolate): Add new command.
* etc/NEWS: Announce new command.
---
etc/NEWS | 6 ++++
lisp/emacs-lisp/package.el | 57 ++++++++++++++++++++++++++++++++++----
2 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index 57f04609679..c374695a571 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -505,6 +505,12 @@ project, that you can quickly select using 'project-switch-project'
When non-nil, package specifications with side-effects for building
software will be used when building a package.
+---
+*** New command to start Emacs only with specific packages
+The command 'package-isolate' is equivalent to starting Emacs with the
+-Q flag and loading specific packages (and their dependencies)
+manually.
+
** Flymake
+++
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index b3062d2608b..9e969ce1024 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2330,12 +2330,26 @@ package-upgrade-all
(mapc #'package-upgrade upgradeable))))
(defun package--dependencies (pkg)
- "Return a list of all dependencies PKG has.
-This is done recursively."
- ;; Can we have circular dependencies? Assume "nope".
- (when-let* ((desc (cadr (assq pkg package-archive-contents)))
- (deps (mapcar #'car (package-desc-reqs desc))))
- (delete-dups (apply #'nconc deps (mapcar #'package--dependencies deps)))))
+ "Return a list of all recursive dependencies of PKG.
+If PKG is a package descriptor, the return value will consist of
+a list of package descriptors. If PKG is a symbol, designating a
+package, the return value will be a list of symbols designating
+packages."
+ (when-let* ((desc (if (package-desc-p pkg) pkg
+ (cadr (assq pkg package-archive-contents)))))
+ ;; Can we have circular dependencies? Assume "nope".
+ (let ((all (named-let more ((pkg-desc desc))
+ (let (deps)
+ (dolist (req (package-desc-reqs pkg-desc))
+ (setq deps (nconc
+ (catch 'found
+ (dolist (p (apply #'append (mapcar #'cdr (package--alist))))
+ (when (and (string= (car req) (package-desc-name p))
+ (version-list-<= (cadr req) (package-desc-version p)))
+ (throw 'found (more p)))))
+ deps)))
+ (delete-dups (cons pkg-desc deps))))))
+ (remq pkg (mapcar (if (package-desc-p pkg) #'identity #'package-desc-name) all)))))
(defun package-strip-rcs-id (str)
"Strip RCS version ID from the version string STR.
@@ -2625,6 +2639,37 @@ package-autoremove
removable))
(message "Nothing to autoremove")))))
+(defun package-isolate (packages)
+ "Start an uncustomised Emacs and only load a set of PACKAGES."
+ (interactive
+ (cl-loop for p in (cl-loop for p in (package--alist) append (cdr p))
+ unless (package-built-in-p p)
+ collect (cons (package-desc-full-name p) p) into table
+ finally return
+ (list (cl-loop for c in (completing-read-multiple
+ "Isolate packages: " table
+ nil t)
+ collect (alist-get c table nil nil #'string=)))))
+ (let* ((name (concat "package-isolate-"
+ (mapconcat #'package-desc-full-name packages ",")))
+ package-load-list)
+ (dolist (package (append packages (mapcan #'package--dependencies packages)))
+ (push (list (package-desc-name package)
+ (package-version-join (package-desc-version package)))
+ package-load-list))
+ (apply #'start-process (concat "*" name "*") nil
+ (list (expand-file-name invocation-name invocation-directory)
+ "--quick" "--debug-init"
+ "--init-directory" (make-temp-file name t)
+ (format "--eval=%S"
+ `(progn
+ (require 'warnings)
+ (add-to-list 'warning-suppress-log-types 'initialization)
+ (require 'package)
+ (setq package-user-dir ,(expand-file-name package-user-dir)
+ package-load-list ',package-load-list)
+ (package-initialize)))))))
+
\f
;;;; Package description buffer.
--
2.39.2
[-- Attachment #3: Type: text/plain, Size: 1400 bytes --]
>> [2. text/x-diff; 0002-Add-command-to-start-Emacs-with-specific-packages.patch]...
>>
>> [3. text/x-diff; 0001-Add-a-function-to-query-the-Emacs-executable.patch]...
I have slightly modified your version, fixing issues I had, in case
anyone else wants to try it out:
(defun package-isolate (packages)
"Start an uncustomised Emacs and only load a set of PACKAGES."
(interactive
(list (mapcar #'intern (completing-read-multiple "Packages: " (mapcar #'car (package--alist))))))
(let* ((name (concat "package-isolate-" (mapconcat #'symbol-name packages ",")))
(deps (mapcan #'package--dependencies packages)))
(apply #'start-process (concat "*" name "*") nil
(list (file-truename (expand-file-name invocation-name invocation-directory))
"--quick" "--debug-init"
(format "--eval=%S"
`(progn
(require 'warnings)
(add-to-list 'warning-suppress-log-types 'initialization)
(require 'package)
(setq package-load-list
',(mapcar (lambda (p) (list p t)) (append packages deps)))
(package-initialize)))))))
next prev parent reply other threads:[~2023-08-16 10:10 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-07 7:57 Changes to make in elpa-packages file for nongnu elpa Thierry Volpiatto
2023-08-07 13:30 ` Philip Kaludercic
2023-08-07 18:19 ` Thierry Volpiatto
2023-08-07 20:33 ` Philip Kaludercic
2023-08-08 4:33 ` Thierry Volpiatto
2023-08-08 5:52 ` Philip Kaludercic
2023-08-08 6:17 ` Thierry Volpiatto
2023-08-15 16:55 ` Philip Kaludercic
2023-08-15 17:34 ` Eshel Yaron
2023-08-15 19:39 ` Proposal for 'package-isolate' command Philip Kaludercic
2023-08-17 10:53 ` Adam Porter
2023-08-15 18:56 ` Changes to make in elpa-packages file for nongnu elpa Eli Zaretskii
2023-08-15 19:52 ` Proposal for 'package-isolate' command Philip Kaludercic
2023-08-16 11:25 ` Eli Zaretskii
2023-08-16 18:48 ` Philip Kaludercic
2023-08-16 6:51 ` Changes to make in elpa-packages file for nongnu elpa Thierry Volpiatto
2023-08-16 10:10 ` Philip Kaludercic [this message]
2023-08-16 10:14 ` Thierry Volpiatto
2023-08-16 11:03 ` Philip Kaludercic
2023-08-16 11:55 ` Thierry Volpiatto
2023-08-16 18:34 ` Proposal for 'package-isolate' command Philip Kaludercic
2023-08-16 18:49 ` Stefan Kangas
2023-08-16 19:00 ` Philip Kaludercic
2023-08-17 5:30 ` Thierry Volpiatto
2023-08-17 8:34 ` Philip Kaludercic
2023-08-17 9:07 ` Eshel Yaron
2023-08-17 14:19 ` Philip Kaludercic
2023-08-17 13:32 ` Thierry Volpiatto
2023-08-17 14:04 ` Philip Kaludercic
2023-08-17 14:15 ` Thierry Volpiatto
2023-08-17 13:56 ` Thierry Volpiatto
2023-08-17 14:18 ` Philip Kaludercic
2023-08-17 14:28 ` Thierry Volpiatto
2023-08-17 18:17 ` Philip Kaludercic
2023-08-18 4:57 ` Thierry Volpiatto
2023-08-18 5:44 ` Eli Zaretskii
2023-08-18 7:49 ` Philip Kaludercic
2023-08-18 12:43 ` Thierry Volpiatto
2023-08-18 18:34 ` Adding package and package-vc to ELPA Philip Kaludercic
2023-08-19 10:26 ` Thierry Volpiatto
2023-08-20 6:40 ` Proposal for 'package-isolate' command Thierry Volpiatto
2023-08-20 7:51 ` Philip Kaludercic
2023-08-20 16:06 ` Thierry Volpiatto
2023-08-20 18:41 ` Philip Kaludercic
2023-08-20 19:15 ` Thierry Volpiatto
2023-08-20 20:24 ` Thierry Volpiatto
2023-08-20 20:28 ` Philip Kaludercic
2023-08-16 14:10 ` Changes to make in elpa-packages file for nongnu elpa Eli Zaretskii
2023-08-16 18:52 ` Philip Kaludercic
2023-08-08 6:01 ` Thierry Volpiatto
2023-08-08 6:34 ` Michael Albinus
2023-08-08 16:37 ` Philip Kaludercic
2023-08-08 16:41 ` Michael Albinus
2023-08-09 7:06 ` Philip Kaludercic
2023-08-09 11:53 ` Eli Zaretskii
2023-08-09 14:53 ` Philip Kaludercic
2023-08-09 14:55 ` Eli Zaretskii
2023-08-09 15:24 ` Philip Kaludercic
2023-08-09 16:23 ` Eli Zaretskii
2023-08-09 3:47 ` Richard Stallman
-- strict thread matches above, loose matches on Subject: below --
2023-08-09 21:55 No Wayman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87zg2ri9g9.fsf@posteo.net \
--to=philipk@posteo.net \
--cc=emacs-devel@gnu.org \
--cc=thievol@posteo.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.