Subject: Re: bug#62720: 29.0.60; Not easy at all to upgrade :core packages like Eglot

From: Philip Kaludercic <[email-masked]>
Date: Sat, 15 Apr 2023 18:19:31 +0000

Eli Zaretskii <[email-masked]> writes:

>> From: Philip Kaludercic <[email-masked]>
>> Cc: [email-masked],  [email-masked],  [email-masked]
>> Date: Sat, 15 Apr 2023 17:14:41 +0000
>> 
>> Eli Zaretskii <[email-masked]> writes:
>> 
>> > The user option allows those users who always want package-install to
>> > upgrade core package to have what they want, easily.  So I think we
>> > should keep it.  On master, the option could be t by default, or
>> > become unnecessary if that's what happens (but I wouldn't bet on
>> > that).
>> 
>> My argument against a user option is just that the whole deal is
>> something that will in practice at most affect two packages (if we
>> change the behaviour in Emacs 29).  Is it really worth adding a general
>> option for this very specific situation?
>
> I think we should count users of those packages, not just the packages
> themselves.  Yes, I think it's worth it, because we don't know how
> many of the users will want the built-in packages to be included in an
> update.

OK, see below.

>> >   "Return non-nil if PACKAGE if the built-in version is used."
>> >
>> > See those two "if"s?  And even if I replace the second "if" with "is",
>> > the sentence doesn't make sense.
>> 
>> Right, how does
>> 
>>   "Return non-nil if the built-in version of PACKAGE is used."
>> 
>> sound?
>
> I think we should explain what does "the built-in version of PACKAGE
> is used" mean, in the context in which this predicate is used.  Maybe
> say something like
>
>     Return non-nil if the built-in version of PACKAGE is used.
>   If the built-in version of PACKAGE is used and PACKAGE is
>   also available for installation from an archive, it is an
>   indication that PACKAGE was never upgraded to any newer
>   version from the archive.

Sounds good to me.

>From dae52770fa50bb68a4fdd0983de7811e427733a5 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <[email-masked]>
Date: Thu, 13 Apr 2023 20:13:59 +0200
Subject: [PATCH] Allow upgrading built-in packages with 'package-install'

* etc/NEWS: Mention the change
* lisp/emacs-lisp/package.el (package--upgradable-built-in-p): Add new
predicate.
(package-install-upgrade-built-in): Add new user option to enable
feature.
(package-install): Respect new user option.
---
 etc/NEWS                   |  5 ++++
 lisp/emacs-lisp/package.el | 47 +++++++++++++++++++++++++++++++-------
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 84dbb94a71a..a7834cd0d2b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1876,6 +1876,11 @@ package maintainers.
 By customizing this user option you can specify specific packages to
 install.
 
+---
+*** New user option 'package-install-upgrade-built-in'.
+When enabled, 'package-install' can be used to install 
+newer versions of built-in packages.
+
 ** Emacs Sessions (Desktop)
 
 +++
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index f92afe56b76..c0cc7bebeb2 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -797,6 +797,21 @@ package-built-in-p
         (require 'finder-inf nil t) ; For `package--builtins'.
         (assq package package--builtins))))))
 
+(defun package--active-built-in-p (package)
+  "Return non-nil if PACKAGE if the built-in version is used.
+If the built-in version of PACKAGE is used and PACKAGE is
+also available for installation from an archive, it is an
+indication that PACKAGE was never upgraded to any newer
+version from the archive."
+  (and (not (assq (cond
+                   ((package-desc-p package)
+                    (package-desc-name package))
+                   ((stringp package) (intern package))
+                   ((symbolp package) package)
+                   ((error "Unknown package format: %S" package)))
+                  (package--alist)))
+       (package-built-in-p package)))
+
 (defun package--autoloads-file-name (pkg-desc)
   "Return the absolute name of the autoloads file, sans extension.
 PKG-DESC is a `package-desc' object."
@@ -2182,12 +2197,18 @@ package--archives-initialize
   (unless package-archive-contents
     (package-refresh-contents)))
 
+(defcustom package-install-upgrade-built-in nil
+  "Non-nil means that built-in packages can be upgraded via a package archive.
+If disabled, then `package-install' will not suggest to replace a
+built-in package with a version from a package archive."
+  :type 'boolean
+  :version "29.1")
+
 ;;;###autoload
 (defun package-install (pkg &optional dont-select)
   "Install the package PKG.
 PKG can be a `package-desc' or a symbol naming one of the
-available packages in an archive in `package-archives'.  When
-called interactively, prompt for the package name.
+available packages in an archive in `package-archives'.
 
 Mark the installed package as selected by adding it to
 `package-selected-packages'.
@@ -2197,7 +2218,11 @@ package-install
 `package-selected-packages'.
 
 If PKG is a `package-desc' and it is already installed, don't try
-to install it but still mark it as selected."
+to install it but still mark it as selected.
+
+If the command is invoked with a prefix argument, the upgrading
+of built-in packages will be possible, as if
+`package-install-upgrade-built-in' had been enabled."
   (interactive
    (progn
      ;; Initialize the package system to get the list of package
@@ -2205,11 +2230,14 @@ package-install
      (package--archives-initialize)
      (list (intern (completing-read
                     "Install package: "
-                    (delq nil
-                          (mapcar (lambda (elt)
-                                    (unless (package-installed-p (car elt))
-                                      (symbol-name (car elt))))
-                                  package-archive-contents))
+                    (mapcan
+                     (lambda (elt)
+                       (and (or (and (or current-prefix-arg
+                                         package-install-upgrade-built-in)
+                                     (package--active-built-in-p (car elt)))
+                                (not (package-installed-p (car elt))))
+                            (list (symbol-name (car elt)))))
+                     package-archive-contents)
                     nil t))
            nil)))
   (package--archives-initialize)
@@ -2220,6 +2248,9 @@ package-install
     (unless (or dont-select (package--user-selected-p name))
       (package--save-selected-packages
        (cons name package-selected-packages)))
+    (when (and (or current-prefix-arg package-install-upgrade-built-in)
+               (package--active-built-in-p pkg))
+      (setq pkg (or (cadr (assq name package-archive-contents)) pkg)))
     (if-let* ((transaction
                (if (package-desc-p pkg)
                    (unless (package-installed-p pkg)
-- 
2.30.2

-- 
Philip Kaludercic