14

I ran into a bug that involved an interaction between several packages. In order to report the bug, I need to provide a reproducible recipe illustrating the problem. This requires loading the appropriate packages, but nothing else from my init, and no other packages. What is the best way to do this?

UPDATE

To clarify, I am familiar with the concept of sifting through my .emacs in a binary search to identify the code causing a problem. In this situation, I know exactly what packages are causing the problem already. What I don't know, is how to use the package- system to load just those few packages.

(package-initialize) will load the packages, but also everything else in my .emacs.d/elpa directory. package-load-list allows me to specify particular versions of packages to load, or particular packages to explicitly exclude. I need the reverse - how to supply Emacs with a list of packages to include, without loading any other packages in the elpa/package system.

Tyler
  • 21,719
  • 1
  • 52
  • 92
  • If you have isolated the problem to a finite number of packages, then you can try reproducing the problem by starting from a blank `.emacs` file -- install each package one by one and then see if the problem still exists. You may surprise yourself and find the package responsible that doesn't play nice with the other package. When you have gone as far as you can, write up the steps that you used to reproduce the problem and submit the bug report -- e.g., starting from **Emacs -Q**, install package A, then install package B, then install package C, then open the `*Scratch*` buffer and type... – lawlist Oct 20 '15 at 22:09
  • What @lawlist said. If you are not sure you've narrowed things down completely, use binary search: remove an arbitrary 1/2 of what you have that repros the problem (e.g. remove 2 pkgs out of 4). Then remove 3/4, 7/8, ... chopping the code needed to repro it in half each time. You can similarly chop the code of a given pkg in 1/2, etc., to narrow things down to a very small bit of code needed to repro it. You can use command `comment-region` to comment out (or, with `C-u`, to uncomment) a region of text. – Drew Oct 20 '15 at 22:18
  • I understand this at a pseudo-code level. I don't understand how, using the package- family of commands, you load only a subset of the packages in your. emacs.d/elpa directory – Tyler Oct 21 '15 at 03:07
  • Previously a maintainer indicated that I was loading everything with package-initialize, and I'm not sure how to avoid this https://github.com/emacs-ess/ESS/issues/140 – Tyler Oct 21 '15 at 03:15
  • 1
    `package-load-list` *is* a way to explicitly include packages, just remove the `all` symbol. – npostavs Oct 21 '15 at 17:01
  • @npostavs ok! this wasn't clear in the docs, but now I think I understand. I just need three lines: `(require 'package)` `(setq package-load list '((pack1 t) (pack2 t)))` `(package-initialize)`. Submit an answer and I'll accept it. – Tyler Oct 21 '15 at 17:23
  • After your update and the accepted answer, I think it would be perhaps helpful to also update the title of your question. – Name Oct 22 '15 at 07:45

4 Answers4

11

The package-load-list variable can be used to specify precisely which packages and versions to load:

List of packages for `package-initialize' to load.
Each element in this list should be a list (NAME VERSION), or the
symbol `all'.  The symbol `all' says to load the latest installed
versions of all packages not specified by other elements.

For an element (NAME VERSION), NAME is a package name (a symbol).
VERSION should be t, a string, or nil.
If VERSION is t, the most recent version is activated.
If VERSION is a string, only that version is ever loaded.
 Any other version, even if newer, is silently ignored.
 Hence, the package is "held" at that version.
If VERSION is nil, the package is not loaded (it is "disabled").

The only thing to watch out for is that the default value includes all, if you setq it then you'll be fine because that completely overwrites the original value.

(require 'package)
(setq package-load-list
      '((package1 "4.2")
        (package2 "0.5.1")))
(package-initialize)
npostavs
  • 9,033
  • 1
  • 21
  • 53
4

An option that would work well in contexts where the developers working on reproducing the bug may not already have (or want) those dependencies installed is to use the try package (https://melpa.org/#/try). Others can load a packages from package management without modifying their local installation.

(package-install 'try)
(require 'try)

(try 'some-package)
(try 'some-other-package)

(steps (to reproduce) (the (problem)))
Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
ebpa
  • 7,319
  • 26
  • 53
3

This use case is a terrible deficiency of package.el, so don't use package.el. Instead, use a package manager like straight.el (I'm the author), which was specifically designed to support this use case.

For verbose documentation on straight.el, including comparisons to other package managers, see the README. Below, I've quoted the section that is relevant to your question.

Using straight.el to reproduce bugs

One of the major reasons I wanted to write straight.el was that existing package managers were not good for reproducing bugs. For instance, some of them would load all installed packages when the package manager was initialized! Obviously that is not acceptable for a "minimal test case".

On the contrary, bootstrapping straight.el does not load anything except for straight.el itself (the default recipe repositories are registered, but not cloned until needed). You should normally be loading straight.el by means of the bootstrap snippet, but when you are in emacs -Q, here is how you can initialize straight.el:

M-x load-file RET ~/.emacs.d/straight/repos/straight.el/bootstrap.el RET

You can also do this from the command line, perhaps by creating an alias for it:

$ emacs -Q -l ~/.emacs.d/straight/repos/straight.el/bootstrap.el

Let's say you are making a bug report for Projectile. To load just Projectile and all of its dependencies, run:

M-x straight-use-package RET projectile RET

Note that this will use the currently checked-out revisions of Projectile and all of its dependencies, so you should take note of those in order to make your bug report.

Resigned June 2023
  • 1,502
  • 15
  • 20
  • This is great. On my machine, the straight.el bootstrap file is now `~/.emacs.d/straight/repos/straight.el/bootstrap.el` – GaryO Apr 21 '20 at 17:51
  • @GaryO Gosh, that was changed a long time ago. Thanks for pointing out that this answer needed to be updated! – Resigned June 2023 Apr 26 '20 at 16:51
0

When you need it for a one-off (e.g. to try and test a recipe to reproduce a bug), you can often get away with:

emacs -Q -l ~/.emacs.d/elpa/<pkg>-<vers>/<pkg>-autoloads.el

I said "often" because it will not pay attention to dependencies, so in some cases you'll need to add more of those -l ... args to load the other packages that are needed.

Stefan
  • 26,154
  • 3
  • 46
  • 84