Closed AlynxZhou closed 1 year ago
I'm experiencing the same thing. If use-package-always-ensure
is set, any use-package
declaration for a built-in package causes Emacs to connect to the package archives on startup.
The relevant use-package
code is here:
https://github.com/jwiegley/use-package/blob/a7422fb8ab1baee19adb2717b5b47b9c3812a84c/use-package-ensure.el#L165-L170
The code above seems sensible. The problem is that when package--initialized
is nil, package-installed-p
returns nil for built-in packages, which I find surprising. This case causes connection to the package archives.
The package.el
code for package-installed-p
is here:
package--initialized
is nil, the second cond
test matches causing the package to be looked up in package-activated-list
. For a built-in package, this will return nil.package--initialized
is non-nil, it falls through to the third cond
clause, which returns (package-built-in-p package min-version)
. This gives the desired result.I would expect package-installed-p
to always return t for a built-in package (when no min-version
argument is specified). That is not the current behavior. Does this sound correct? If so, I believe this should be fixed in package.el
.
In the meanwhile, a few workarounds are possible. The first involves an update to use-package
. The others are user configurations.
Modify the test in use-package-ensure-elpa
to be:
(unless (or (package-installed-p package)
(package-built-in-p package)))
Define a custom use-package-ensure-function
with the same logic as above. (Quite heavy on the user)
Add (setq package--initialized t)
before any built-in use-package
declarations. (A vague, magical hack)
Add :ensure nil
to use-package
declarations for all built-in packages. (Cleaner, but less convenient)
Thanks for the detective work, everyone! I also ran into this, and adding :ensure nil
to my use-package
directives for the tramp
and project
packages worked for me. I agree that this is very surprising behavior…
I would expect
package-installed-p
to always return t for a built-in package (when nomin-version
argument is specified). That is not the current behavior. Does this sound correct? If so, I believe this should be fixed inpackage.el
.
Which version of Emacs are you using?
On current master (Emacs 29) and Emacs 27.1, the following evaluates to t
in emacs -Q
here:
(progn
(require 'package)
(package-installed-p 'recentf))
I would expect
package-installed-p
to always return t for a built-in package (when nomin-version
argument is specified). That is not the current behavior. Does this sound correct? If so, I believe this should be fixed inpackage.el
.Which version of Emacs are you using?
On current master (Emacs 29) and Emacs 27.1, the following evaluates to
t
inemacs -Q
here:(progn (require 'package) (package-installed-p 'recentf))
A simple git blame tells me that this has been fixed by Emacs upstream, let's cheers and close this issue!
https://github.com/emacs-mirror/emacs/commit/50a192795ad64d2ea49274b402cb42530a5199ca
A simple git blame tells me that this has been fixed by Emacs upstream, let's cheers and close this issue!
That's good news indeed, thanks for looking into it.
I can reproduce this with following
init.el
:If you start Emacs with it, you can see following messages in
*Messages*
buffer every startup (ignore my ELPA mirror):and
recentf
will be added intopackage-selected-packages
.I think
use-package
should not try to install built-in packages and ignore:ensure
for them.I did some test to find what makes my Emacs refresh archive contents on every startup before I found it's
use-package-always-ensure
, and find some interesting things:It seems related to
package-activate-all
added in Emacs 27.1, after 27.1, Emacs will callpackage-activate-all
automatically betweenearly-init.el
andinit.el
instead ofpackage-initialize
, becausepackage-activate-all
supportspackage-quickstart
and will load the cache.And if I disable this behavior by adding
(setq package-enable-at-startup nil)
toearly-init.el
, and call(package-initialize)
manually ininit.el
,use-package
works fine withuse-package-always-ensure
and built-in packages, but this makespackages-quickstart
invalid, sincepackage-initialize
loads each package's autoload files before quickstart cache is loaded.If I replace
(package-initialize)
I added ininit.el
with(package-activate-all)
, this bug happens again, and I then read the code of them to find what makesuse-package
behave different, I found thatpackage-initialize
contains a line(setq package--initialized t)
before it calls(package-activate-all)
, if I replace(package-initialize)
with(setq package--initialized t)(package-activate-all)
,use-package
also works fine and quickstart is used.So the simplest way to resolve this problem is ignore
:ensure
for built-in packages of Emacs, but I am also wondering whypackage--initialized
makesuse-package
behave different, maybe functions to detect built-in packages depends on it? If so, is this an issue ofpackage.el
?