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

From: Philip Kaludercic <[email-masked]>
Date: Mon, 10 Apr 2023 18:13:50 +0000

João Távora <[email-masked]> writes:

> On Sat, Apr 8, 2023 at 4:45 PM Stefan Monnier <[email-masked]> wrote:
>>
>> > As package-update just defers to package-install, I don't find this
>> > surprising.  What you want is that package.el always treats a built-in
>> > package as upgradable to a package from ELPA.  It seems like this should
>> > be possible by adjusting the interactive spec of package-install and
>> > modifying package-compute-transaction or even package-built-in-p.
>>
>> I agree, tho I don't understand why you say "built-in" above.  Isn't the
>> problem also present for already-installed-but-out-of-date ELPA packages?
>
> I bit the bullet and went after this in package.el.  The answer is no,
> it's not present for those packages.
>
> But Philip's imagined fix seems to be more complicated than it needs
> to be. Here's a simple patch that works well in my tests.  It makes
> M-x package-update also update built-in-packages.
>
> diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
> index f92afe56b76..f54b6f39e40 100644
> --- a/lisp/emacs-lisp/package.el
> +++ b/lisp/emacs-lisp/package.el
> @@ -2243,11 +2243,16 @@ package-update
>    (let* ((package (if (symbolp name)
>                        name
>                      (intern name)))
> -         (pkg-desc (cadr (assq package package-alist))))
> -    (if (package-vc-p pkg-desc)
> -        (package-vc-update pkg-desc)
> -      (package-delete pkg-desc 'force)
> -      (package-install package 'dont-select))))
> +         (nonbuiltin (assq package package-alist)))
> +    (cond (nonbuiltin
> +           (let ((desc (cadr nonbuiltin)))
> +             (if (package-vc-p desc)
> +                 (package-vc-update desc)
> +               (package-delete desc 'force)
> +               (package-install package 'dont-select))))
> +          (t
> +           (package-install
> +            (cadr (assq package package-archive-contents)))))))
>
>  (defun package--updateable-packages ()
>    ;; Initialize the package system to get the list of package
> @@ -2261,10 +2266,14 @@ package--updateable-packages
>                   (assq (car elt) package-archive-contents)))
>              (and available
>                   (version-list-<
> -                  (package-desc-version (cadr elt))
> +                  (if (vectorp (cdr elt)) (aref (cdr elt) 0)
> +                    (package-desc-version (cadr elt)))
>                    (package-desc-version (cadr available)))))
> -          (package-vc-p (cadr (assq (car elt) package-alist)))))
> -    package-alist)))
> +          (and (consp (cdr elt))
> +               (package-desc-p (cadr elt))
> +               (package-vc-p (cadr elt)))))
> +    (seq-union package-alist package--builtins
> +               (lambda (a b) (eq (car a) (car b)))))))

Will this not affect `package-update-all'?  I don't if we want that the
command installs all packages from ELPA that it can find.

>  ;;;###autoload
>  (defun package-update-all (&optional query)
>
> The only thing that's slightly inelegant/hard-to-follow is that
> the format of package-alist is different than package--builtins.
> Lots of consp, cdr-taking, vectorp and so on.  Besides that, it's
> a question of taking the union of the two sets and operating on that.

That is necessary complexity, so I don't think there is any way around it.

> This also relies on seq-union's undocumented behavior of keeping
> the first of any duplicates.  Feel free to rewrite.
>
> João