Commit 5e87fcb1 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

* lisp/emacs-lisp/package.el (package-compute-transaction): Topological sort.

Add optional `seen' argument to detect and break infinite loops.

Fixes: debbugs:16994
parent 8e102bcc
2014-05-06 Stefan Monnier <monnier@iro.umontreal.ca>
* emacs-lisp/package.el (package-compute-transaction): Topological sort.
Add optional `seen' argument to detect and break infinite loops.
2014-05-06 Eli Zaretskii <eliz@gnu.org> 2014-05-06 Eli Zaretskii <eliz@gnu.org>
   
* emacs-lisp/find-gc.el (find-gc-unsafe, find-unsafe-funcs) * emacs-lisp/find-gc.el (find-gc-unsafe, find-unsafe-funcs)
...@@ -6,11 +11,11 @@ ...@@ -6,11 +11,11 @@
   
2014-05-06 Michael Albinus <michael.albinus@gmx.de> 2014-05-06 Michael Albinus <michael.albinus@gmx.de>
   
* net/tramp-sh.el (tramp-remote-process-environment): Remove * net/tramp-sh.el (tramp-remote-process-environment):
HISTFILE and HISTSIZE; it's too late to set them here. Add Remove HISTFILE and HISTSIZE; it's too late to set them here.
:version entry. Add :version entry.
(tramp-open-shell): Do not let-bind `tramp-end-of-output'. Add (tramp-open-shell): Do not let-bind `tramp-end-of-output'.
"HISTSIZE=/dev/null" to the shell's env arguments. Do not send Add "HISTSIZE=/dev/null" to the shell's env arguments. Do not send
extra "PSx=..." commands. extra "PSx=..." commands.
(tramp-maybe-open-connection): Setenv HISTFILE to /dev/null. (tramp-maybe-open-connection): Setenv HISTFILE to /dev/null.
(Bug#17295) (Bug#17295)
...@@ -126,8 +131,8 @@ ...@@ -126,8 +131,8 @@
(todo-edit-done-item--param-key-alist): New defconsts. (todo-edit-done-item--param-key-alist): New defconsts.
(todo-edit-item--prompt): New variable. (todo-edit-item--prompt): New variable.
(todo-edit-item--next-key): New function. (todo-edit-item--next-key): New function.
(todo-key-bindings-t): Bind "e" to todo-edit-item. Remove (todo-key-bindings-t): Bind "e" to todo-edit-item.
bindings of deleted commands. Remove bindings of deleted commands.
   
2014-05-02 Leo Liu <sdl.web@gmail.com> 2014-05-02 Leo Liu <sdl.web@gmail.com>
   
......
...@@ -868,7 +868,7 @@ MIN-VERSION should be a version list." ...@@ -868,7 +868,7 @@ MIN-VERSION should be a version list."
;; Also check built-in packages. ;; Also check built-in packages.
(package-built-in-p package min-version))) (package-built-in-p package min-version)))
(defun package-compute-transaction (packages requirements) (defun package-compute-transaction (packages requirements &optional seen)
"Return a list of packages to be installed, including PACKAGES. "Return a list of packages to be installed, including PACKAGES.
PACKAGES should be a list of `package-desc'. PACKAGES should be a list of `package-desc'.
...@@ -880,7 +880,9 @@ version of that package. ...@@ -880,7 +880,9 @@ version of that package.
This function recursively computes the requirements of the This function recursively computes the requirements of the
packages in REQUIREMENTS, and returns a list of all the packages packages in REQUIREMENTS, and returns a list of all the packages
that must be installed. Packages that are already installed are that must be installed. Packages that are already installed are
not included in this list." not included in this list.
SEEN is used internally to detect infinite recursion."
;; FIXME: We really should use backtracking to explore the whole ;; FIXME: We really should use backtracking to explore the whole
;; search space (e.g. if foo require bar-1.3, and bar-1.4 requires toto-1.1 ;; search space (e.g. if foo require bar-1.3, and bar-1.4 requires toto-1.1
;; whereas bar-1.3 requires toto-1.0 and the user has put a hold on toto-1.0: ;; whereas bar-1.3 requires toto-1.0 and the user has put a hold on toto-1.0:
...@@ -893,15 +895,22 @@ not included in this list." ...@@ -893,15 +895,22 @@ not included in this list."
(dolist (pkg packages) (dolist (pkg packages)
(if (eq next-pkg (package-desc-name pkg)) (if (eq next-pkg (package-desc-name pkg))
(setq already pkg))) (setq already pkg)))
(cond (when already
(already
(if (version-list-<= next-version (package-desc-version already)) (if (version-list-<= next-version (package-desc-version already))
;; Move to front, so it gets installed early enough (bug#14082). ;; `next-pkg' is already in `packages', but its position there
(setq packages (cons already (delq already packages))) ;; means it might be installed too late: remove it from there, so
;; we re-add it (along with its dependencies) at an earlier place
;; below (bug#16994).
(if (memq already seen) ;Avoid inf-loop on dependency cycles.
(message "Dependency cycle going through %S"
(package-desc-full-name already))
(setq packages (delq already packages))
(setq already nil))
(error "Need package `%s-%s', but only %s is being installed" (error "Need package `%s-%s', but only %s is being installed"
next-pkg (package-version-join next-version) next-pkg (package-version-join next-version)
(package-version-join (package-desc-version already))))) (package-version-join (package-desc-version already)))))
(cond
(already nil)
((package-installed-p next-pkg next-version) nil) ((package-installed-p next-pkg next-version) nil)
(t (t
...@@ -933,12 +942,13 @@ but version %s required" ...@@ -933,12 +942,13 @@ but version %s required"
(t (setq found pkg-desc))))) (t (setq found pkg-desc)))))
(unless found (unless found
(if problem (if problem
(error problem) (error "%s" problem)
(error "Package `%s-%s' is unavailable" (error "Package `%s-%s' is unavailable"
next-pkg (package-version-join next-version)))) next-pkg (package-version-join next-version))))
(setq packages (setq packages
(package-compute-transaction (cons found packages) (package-compute-transaction (cons found packages)
(package-desc-reqs found)))))))) (package-desc-reqs found)
(cons found seen))))))))
packages) packages)
(defun package-read-from-string (str) (defun package-read-from-string (str)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment