commit:     2e255729ec8c4cf7ab234fd9f2b65bd0d791ef9f
Author:     James Le Cuirot <chewi <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 18 11:21:55 2024 +0000
Commit:     James Le Cuirot <chewi <AT> gentoo <DOT> org>
CommitDate: Wed Sep 18 17:22:29 2024 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=2e255729

WIP Auto resolve cyclic USE conflicts by trying the first suggestion

Signed-off-by: James Le Cuirot <chewi <AT> gentoo.org>

 lib/_emerge/depgraph.py                     | 29 ++++++++++++++++++++++-------
 lib/_emerge/resolver/circular_dependency.py |  2 +-
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py
index 2acd8f2e13..8b68e0179f 100644
--- a/lib/_emerge/depgraph.py
+++ b/lib/_emerge/depgraph.py
@@ -9886,6 +9886,9 @@ class depgraph:
                 drop_satisfied = True
                 continue
 
+            if not selected_nodes:
+                circular_dep_handler = circular_dependency_handler(self, 
mygraph)
+
             if not selected_nodes and myblocker_uninstalls:
                 # If possible, drop an uninstall task here in order to avoid
                 # the circular deps code path. The corresponding blocker will
@@ -9897,8 +9900,9 @@ class depgraph:
                     except KeyError:
                         pass
                     else:
-                        uninst_task = node
-                        ignored_uninstall_tasks.add(node)
+                        if not circular_dep_handler.solutions:
+                            uninst_task = node
+                            ignored_uninstall_tasks.add(node)
                         break
 
                 if uninst_task is not None:
@@ -9909,8 +9913,6 @@ class depgraph:
                     continue
 
             if not selected_nodes:
-                self._dynamic_config._circular_deps_for_display = mygraph
-
                 unsolved_cycle = False
                 if self._dynamic_config._allow_backtracking:
                     backtrack_infos = self._dynamic_config._backtrack_infos
@@ -9935,11 +9937,24 @@ class depgraph:
                             )
 
                 if unsolved_cycle or not 
self._dynamic_config._allow_backtracking:
+                    self._dynamic_config._circular_deps_for_display = mygraph
                     self._dynamic_config._skip_restart = True
+                    raise self._unknown_internal_error()
                 else:
-                    self._dynamic_config._need_restart = True
-
-                raise self._unknown_internal_error()
+                    if circular_dep_handler.solutions:
+                        pkg = list(circular_dep_handler.solutions.keys())[0]
+                        parent, solution = 
list(circular_dep_handler.solutions[pkg])[0]
+                        solution = list(solution)[0]
+                        enabled = list(parent.use.enabled)
+                        if solution[1]:
+                            enabled.append(solution[0])
+                        else:
+                            enabled.remove(solution[0])
+                        selected_nodes = [parent.with_use(enabled), pkg, 
parent]
+                    else:
+                        self._dynamic_config._circular_deps_for_display = 
mygraph
+                        self._dynamic_config._need_restart = True
+                        raise self._unknown_internal_error()
 
             # At this point, we've succeeded in selecting one or more nodes, so
             # reset state variables for leaf node selection.

diff --git a/lib/_emerge/resolver/circular_dependency.py 
b/lib/_emerge/resolver/circular_dependency.py
index 6c21423083..09b1afebfb 100644
--- a/lib/_emerge/resolver/circular_dependency.py
+++ b/lib/_emerge/resolver/circular_dependency.py
@@ -293,7 +293,7 @@ class circular_dependency_handler:
                         " (This change might require USE changes on parent 
packages.)"
                     )
                 suggestions.append(msg)
-                final_solutions.setdefault(pkg, set()).add(solution)
+                final_solutions.setdefault(pkg, set()).add((parent, solution))
 
         return final_solutions, suggestions
 

Reply via email to