emacs-31 ea3d78898a2 1/2: Allow uninstalling dependency with multiple installations

Philip Kaludercic <[email protected]>
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: emacs-31
commit ea3d78898a2be7aafbfda5973fad5453f50d10fe
Author: Philip Kaludercic <[email protected]>
Commit: Philip Kaludercic <[email protected]>

    Allow uninstalling dependency with multiple installations
    
    * lisp/emacs-lisp/package.el (package--dependency-p): Add new
    function to check if a package is a dependency.
    (package-delete): Prompt user if it is OK to uninstall a package
    that serves as a dependency, but where the package has multiple
    installations.  This also means that we don't de-select a
    selected dependency if there are multiple installations.
    
    (Bug#81082)
---
 lisp/emacs-lisp/package.el | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 068b94360d4..cd3c850f7a4 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2379,6 +2379,15 @@ installed), maybe you need to \\[package-refresh-contents]")
   (equal (cadr (assq (package-desc-name pkg) package-alist))
          pkg))
 
+(defun package--dependency-p (pkg)
+  "Return non-nil if PKG is a dependency."
+  (let ((name (package-desc-name pkg)))
+    (catch 'is-dependency
+      (dolist (ent (package--alist) nil)
+        (dolist (desc (cdr ent))
+          (when (assq name (package-desc-reqs desc))
+            (throw 'is-dependency t)))))))
+
 (declare-function comp-el-to-eln-filename "comp.c")
 (defvar package-vc-repository-store)
 (defun package--delete-directory (dir)
@@ -2433,15 +2442,20 @@ If NOSAVE is non-nil, the package is not removed from
                               (if (null (remove pkg-desc (cdr pkgs)))
                                   (remq pkgs package-alist)
                                 package-alist)))
-        pkg-used-elsewhere-by)
+         pkg-used-elsewhere-by)
     ;; If the user is trying to delete this package, they definitely
     ;; don't want it marked as selected, so we remove it from
     ;; `package-selected-packages' even if it can't be deleted.
     (when (and (null nosave)
                (package--user-selected-p name)
-               ;; Don't deselect if this is an older version of an
-               ;; upgraded package.
-               (package--newest-p pkg-desc))
+               (or
+                ;; Don't deselect if this is an older version of an
+                ;; upgraded package.
+                (package--newest-p pkg-desc)
+                ;; Don't deselect if the package is a dependency and
+                ;; there are multiple installations (bug#81082).
+                (and (length< (alist-get name package-alist) 1)
+                     (package--dependency-p pkg-desc))))
       (package--save-selected-packages (remove name package-selected-packages)))
     (cond ((not (string-prefix-p (file-name-as-directory
                                   (expand-file-name package-user-dir))
@@ -2452,7 +2466,16 @@ If NOSAVE is non-nil, the package is not removed from
           ((and (null force)
                 (setq pkg-used-elsewhere-by
                       (let ((package-alist new-package-alist))
-                        (package--used-elsewhere-p pkg-desc)))) ;See bug#65475
+                        (package--used-elsewhere-p pkg-desc))) ;See bug#65475
+                (and-let* ((other (package-get-descriptor
+                                   name 'installed
+                                   (lambda (pkg-other)
+                                     (not (equal pkg-desc pkg-other))))))
+                  (not (yes-or-no-p
+                        (format "Package `%s' is used by `%s' as dependency, but `%s' is also available.  Use that instead?"
+                                (package-desc-full-name pkg-desc)
+                                (package-desc-name pkg-used-elsewhere-by)
+                                (package-desc-full-name other))))))
            ;; Don't delete packages used as dependency elsewhere.
            (error "Package `%s' is used by `%s' as dependency, not deleting"
                   (package-desc-full-name pkg-desc)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.