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

From: Dmitry Gutov <[email-masked]>
Date: Sat, 22 Apr 2023 03:57:03 +0300

On 22/04/2023 02:12, Dmitry Gutov wrote:
>> In interactive invocation, package-upgrade calls completing-read with
>> its 4th argument non-nil, so you cannot select a package which is not
>> in the collection returned by package--updateable-packages.  What I
>> meant above is to allow that collection to include built-in packages
>> as optional behavior.  I just tried invoking package-update for ElDoc,
>> and I get "No match" after typing "eldoc" to its prompt, although
>> eldoc version 1.14.0 is in the list presented by list-packages as
>> "available".
> 
> That's what I imagined: adding a new optional argument to 
> package--updateable-packages which would include builtins in the result.
> 
> And only pass it when called from package-upgrade.
> 
> Hopefully that's the kind of optional that you meant.

Here's a patch which does that. The diff could be reduced (the 
package-update part) by binding the new option 
(package-install-upgrade-built-in), but I figured it's better to avoid 
interdependency while we're still deciding what to keep.

diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index ffa6272dd1f..1f0a47f6b6a 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2270,17 +2270,21 @@ package-update
    "Update package NAME if a newer version exists."
    (interactive
     (list (completing-read
-          "Update package: " (package--updateable-packages) nil t)))
+          "Update package: " (package--updateable-packages t) nil t)))
    (let* ((package (if (symbolp name)
                        name
                      (intern name)))
           (pkg-desc (cadr (assq package package-alist))))
-    (if (package-vc-p pkg-desc)
+    (if (and pkg-desc (package-vc-p pkg-desc))
          (package-vc-update pkg-desc)
-      (package-delete pkg-desc 'force)
-      (package-install package 'dont-select))))
-
-(defun package--updateable-packages ()
+      (when pkg-desc
+        (package-delete pkg-desc 'force))
+      (package-install-from-archive
+       (car (last (seq-sort-by #'package-desc-priority-version
+                               #'version-list-<
+                               (cdr (assq package 
package-archive-contents)))))))))
+
+(defun package--updateable-packages (&optional allow-builtins)
    ;; Initialize the package system to get the list of package
    ;; symbols for completion.
    (package--archives-initialize)
@@ -2291,11 +2295,21 @@ package--updateable-packages
        (or (let ((available
                   (assq (car elt) package-archive-contents)))
              (and available
-                 (version-list-<
-                  (package-desc-version (cadr elt))
-                  (package-desc-version (cadr available)))))
-          (package-vc-p (cadr (assq (car elt) package-alist)))))
-    package-alist)))
+                 (or (and
+                      allow-builtins
+                      (not (package-desc-version (cadr elt))))
+                     (version-list-<
+                      (package-desc-version (cadr elt))
+                      (package-desc-version (cadr available))))))
+          (package-vc-p (cadr elt))))
+    (if allow-builtins
+        (append package-alist
+                (mapcan
+                 (lambda (elt)
+                   (when (not (assq (car elt) package-alist))
+                     (list (list (car elt) (package--from-builtin elt)))))
+                 package--builtins))
+      package-alist))))

  ;;;###autoload
  (defun package-update-all (&optional query)