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 14:29:46 +0300

On 22/04/2023 14:24, Dmitry Gutov wrote:
>>>> I also don't think I like the significant changes in package-update,
>>>> nor understand why they are needed.
>>>
>>> Like I said: the changes are to avoid relying on package-install being
>>> able to install a package that's already installed. Which currently
>>> works only for builtins and when only a user option is set. It's a mess.
>>>
>>> And to "avoid interdependency".
>>
>> Why does this have to be in Emacs 29?  It's a cleanup, right?
> 
> Not a cleanup, no. If I just keep the previous version of the code, I 
> get "package xxx is already installed". Because when upgrading a builtin 
> package, the "current" version is not deleted.
> 
> So we need to compute the exact version to install (then package-install 
> does not say "it's already installed" because the installed version is 
> different). The use of package-install-from-archive might have been a 
> mistake, though, (in case dependencies need to be updated too) I'm 
> looking into that now.

Here's an updated patch that's a little closer to what's been there before.

> Alternatively, we could add an optional argument to package-install 
> which would mean "install the latest version anyway".
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index ffa6272dd1f..f9ad83d7650 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2270,17 +2270,22 @@ 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
+       (car (last (seq-sort-by #'package-desc-priority-version
+                               #'version-list-<
+                               (cdr (assq package package-archive-contents)))))
+       'dont-select))))
+
+(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 +2296,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)