aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2014-05-06 14:11:16 -0400
committerStefan Monnier2014-05-06 14:11:16 -0400
commit5e87fcb1d7c55532cfb7163b1de68e7ddaed4201 (patch)
treeb4fbd39f117e1cda1e90fa620f45bffb68ae1ab3
parent8e102bcc97871ed6e0d2deba84fe46d9a78e9e44 (diff)
downloademacs-5e87fcb1d7c55532cfb7163b1de68e7ddaed4201.tar.gz
emacs-5e87fcb1d7c55532cfb7163b1de68e7ddaed4201.zip
* lisp/emacs-lisp/package.el (package-compute-transaction): Topological sort.
Add optional `seen' argument to detect and break infinite loops. Fixes: debbugs:16994
-rw-r--r--lisp/ChangeLog19
-rw-r--r--lisp/emacs-lisp/package.el28
2 files changed, 31 insertions, 16 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 7a737129bb7..8e5f5f54f16 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,8 @@
12014-05-06 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacs-lisp/package.el (package-compute-transaction): Topological sort.
4 Add optional `seen' argument to detect and break infinite loops.
5
12014-05-06 Eli Zaretskii <eliz@gnu.org> 62014-05-06 Eli Zaretskii <eliz@gnu.org>
2 7
3 * emacs-lisp/find-gc.el (find-gc-unsafe, find-unsafe-funcs) 8 * emacs-lisp/find-gc.el (find-gc-unsafe, find-unsafe-funcs)
@@ -6,11 +11,11 @@
6 11
72014-05-06 Michael Albinus <michael.albinus@gmx.de> 122014-05-06 Michael Albinus <michael.albinus@gmx.de>
8 13
9 * net/tramp-sh.el (tramp-remote-process-environment): Remove 14 * net/tramp-sh.el (tramp-remote-process-environment):
10 HISTFILE and HISTSIZE; it's too late to set them here. Add 15 Remove HISTFILE and HISTSIZE; it's too late to set them here.
11 :version entry. 16 Add :version entry.
12 (tramp-open-shell): Do not let-bind `tramp-end-of-output'. Add 17 (tramp-open-shell): Do not let-bind `tramp-end-of-output'.
13 "HISTSIZE=/dev/null" to the shell's env arguments. Do not send 18 Add "HISTSIZE=/dev/null" to the shell's env arguments. Do not send
14 extra "PSx=..." commands. 19 extra "PSx=..." commands.
15 (tramp-maybe-open-connection): Setenv HISTFILE to /dev/null. 20 (tramp-maybe-open-connection): Setenv HISTFILE to /dev/null.
16 (Bug#17295) 21 (Bug#17295)
@@ -126,8 +131,8 @@
126 (todo-edit-done-item--param-key-alist): New defconsts. 131 (todo-edit-done-item--param-key-alist): New defconsts.
127 (todo-edit-item--prompt): New variable. 132 (todo-edit-item--prompt): New variable.
128 (todo-edit-item--next-key): New function. 133 (todo-edit-item--next-key): New function.
129 (todo-key-bindings-t): Bind "e" to todo-edit-item. Remove 134 (todo-key-bindings-t): Bind "e" to todo-edit-item.
130 bindings of deleted commands. 135 Remove bindings of deleted commands.
131 136
1322014-05-02 Leo Liu <sdl.web@gmail.com> 1372014-05-02 Leo Liu <sdl.web@gmail.com>
133 138
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 7be0354992f..c194e1352ac 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -868,7 +868,7 @@ MIN-VERSION should be a version list."
868 ;; Also check built-in packages. 868 ;; Also check built-in packages.
869 (package-built-in-p package min-version))) 869 (package-built-in-p package min-version)))
870 870
871(defun package-compute-transaction (packages requirements) 871(defun package-compute-transaction (packages requirements &optional seen)
872 "Return a list of packages to be installed, including PACKAGES. 872 "Return a list of packages to be installed, including PACKAGES.
873PACKAGES should be a list of `package-desc'. 873PACKAGES should be a list of `package-desc'.
874 874
@@ -880,7 +880,9 @@ version of that package.
880This function recursively computes the requirements of the 880This function recursively computes the requirements of the
881packages in REQUIREMENTS, and returns a list of all the packages 881packages in REQUIREMENTS, and returns a list of all the packages
882that must be installed. Packages that are already installed are 882that must be installed. Packages that are already installed are
883not included in this list." 883not included in this list.
884
885SEEN is used internally to detect infinite recursion."
884 ;; FIXME: We really should use backtracking to explore the whole 886 ;; FIXME: We really should use backtracking to explore the whole
885 ;; search space (e.g. if foo require bar-1.3, and bar-1.4 requires toto-1.1 887 ;; search space (e.g. if foo require bar-1.3, and bar-1.4 requires toto-1.1
886 ;; whereas bar-1.3 requires toto-1.0 and the user has put a hold on toto-1.0: 888 ;; 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 (dolist (pkg packages) 895 (dolist (pkg packages)
894 (if (eq next-pkg (package-desc-name pkg)) 896 (if (eq next-pkg (package-desc-name pkg))
895 (setq already pkg))) 897 (setq already pkg)))
896 (cond 898 (when already
897 (already
898 (if (version-list-<= next-version (package-desc-version already)) 899 (if (version-list-<= next-version (package-desc-version already))
899 ;; Move to front, so it gets installed early enough (bug#14082). 900 ;; `next-pkg' is already in `packages', but its position there
900 (setq packages (cons already (delq already packages))) 901 ;; means it might be installed too late: remove it from there, so
902 ;; we re-add it (along with its dependencies) at an earlier place
903 ;; below (bug#16994).
904 (if (memq already seen) ;Avoid inf-loop on dependency cycles.
905 (message "Dependency cycle going through %S"
906 (package-desc-full-name already))
907 (setq packages (delq already packages))
908 (setq already nil))
901 (error "Need package `%s-%s', but only %s is being installed" 909 (error "Need package `%s-%s', but only %s is being installed"
902 next-pkg (package-version-join next-version) 910 next-pkg (package-version-join next-version)
903 (package-version-join (package-desc-version already))))) 911 (package-version-join (package-desc-version already)))))
904 912 (cond
913 (already nil)
905 ((package-installed-p next-pkg next-version) nil) 914 ((package-installed-p next-pkg next-version) nil)
906 915
907 (t 916 (t
@@ -933,12 +942,13 @@ but version %s required"
933 (t (setq found pkg-desc))))) 942 (t (setq found pkg-desc)))))
934 (unless found 943 (unless found
935 (if problem 944 (if problem
936 (error problem) 945 (error "%s" problem)
937 (error "Package `%s-%s' is unavailable" 946 (error "Package `%s-%s' is unavailable"
938 next-pkg (package-version-join next-version)))) 947 next-pkg (package-version-join next-version))))
939 (setq packages 948 (setq packages
940 (package-compute-transaction (cons found packages) 949 (package-compute-transaction (cons found packages)
941 (package-desc-reqs found)))))))) 950 (package-desc-reqs found)
951 (cons found seen))))))))
942 packages) 952 packages)
943 953
944(defun package-read-from-string (str) 954(defun package-read-from-string (str)