[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 96e4f95cc8c0d544d375b28394dafe8809c4bc9b Author: Zac Medico gentoo org> AuthorDate: Sun May 26 18:23:27 2024 + Commit: Zac Medico gentoo org> CommitDate: Sun May 26 18:34:04 2024 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=96e4f95c Revert "find_smallest_cycle: Optimize to traverse fewer nodes" This reverts commit 49e01d041c74680a81860b819daff812d83df02f in order to fix bug 922629. Later we can try to optimize it again but without breaking testTarMergeOrder. Bug: https://bugs.gentoo.org/922629 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/depgraph.py| 36 ++ .../tests/resolver/test_rebuild_ghostscript.py | 2 +- .../resolver/test_runtime_cycle_merge_order.py | 7 ++--- lib/portage/tests/resolver/test_tar_merge_order.py | 4 ++- 4 files changed, 9 insertions(+), 40 deletions(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 6b91d5c42d..3adc04bcfb 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -9313,14 +9313,7 @@ class depgraph: asap_nodes.extend(libc_pkgs) -def gather_deps( -ignore_priority, -mergeable_nodes, -selected_nodes, -node, -smallest_cycle=None, -traversed_nodes=None, -): +def gather_deps(ignore_priority, mergeable_nodes, selected_nodes, node): """ Recursively gather a group of nodes that RDEPEND on eachother. This ensures that they are merged as a group @@ -9340,24 +9333,10 @@ class depgraph: # RDEPENDs installed first, but ignore uninstalls # (these occur when new portage blocks an older package version). return False -if traversed_nodes is not None: -if node in traversed_nodes: -# Identical to a previously traversed cycle. -return False -traversed_nodes.add(node) selected_nodes.add(node) -if smallest_cycle is not None and len(selected_nodes) >= len( -smallest_cycle -): -return False for child in mygraph.child_nodes(node, ignore_priority=ignore_priority): if not gather_deps( -ignore_priority, -mergeable_nodes, -selected_nodes, -child, -smallest_cycle=smallest_cycle, -traversed_nodes=traversed_nodes, +ignore_priority, mergeable_nodes, selected_nodes, child ): return False return True @@ -9515,21 +9494,12 @@ class depgraph: local_priority_range.MEDIUM_SOFT + 1, ) ): -# Traversed nodes for current priority -traversed_nodes = set() for node in nodes: if not mygraph.parent_nodes(node): continue -if node in traversed_nodes: -continue selected_nodes = set() if gather_deps( -priority, -mergeable_nodes, -selected_nodes, -node, -smallest_cycle=smallest_cycle, -traversed_nodes=traversed_nodes, +priority, mergeable_nodes, selected_nodes, node ): if smallest_cycle is None or len(selected_nodes) < len( smallest_cycle diff --git a/lib/portage/tests/resolver/test_rebuild_ghostscript.py b/lib/portage/tests/resolver/test_rebuild_ghostscript.py index 8ee3349d6f..dad6a21322 100644 --- a/lib/portage/tests/resolver/test_rebuild_ghostscript.py +++ b/lib/portage/tests/resolver/test_rebuild_ghostscript.py @@ -137,9 +137,9 @@ class RebuildGhostscriptTestCase(TestCase): mergelist=[ "sys-apps/dbus-1.15.6", "x11-libs/gtk+-3.24.38", -"app-text/ghostscript-gpl-10.01.2", "net-dns/avahi-0.8-r7", "net-print/cups-2.4.6", +"app-text/ghostscript-gpl-10.01.2", "app-text/libspectre-0.2.12", "x11-libs/goffice-0.10.55", ], diff --git a/lib/portage/tests/resolver/test_runtime_cycle_merge_order.py b/lib/portage/tests/resolver/test_runtime_cycle_merge_order.py index ed329aa097..a695b25198 100644 ---
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: bf3d091de8702f0c95e5530d03c6e925008ee80a Author: Zac Medico gentoo org> AuthorDate: Sun Dec 24 05:12:55 2023 + Commit: Zac Medico gentoo org> CommitDate: Sun Dec 24 19:29:25 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=bf3d091d depclean: drop direct circular deps in merge order calculation Drop direct circular deps in the depclean merge order calculation, since it does not handle them well as shown by the test case for bug 916135. Bug: https://bugs.gentoo.org/916135 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/actions.py| 8 ++-- lib/portage/tests/resolver/test_depclean_order.py | 10 ++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py index 86ba7f77a5..13bb75931c 100644 --- a/lib/_emerge/actions.py +++ b/lib/_emerge/actions.py @@ -1,4 +1,4 @@ -# Copyright 1999-2021 Gentoo Authors +# Copyright 1999-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import collections @@ -1642,7 +1642,11 @@ def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spi if mypriority.runtime: mypriority.runtime_slot_op = True -graph.add(child_node, node, priority=mypriority) +# Drop direct circular deps because the unmerge order +# calculation does not handle them well as demonstrated +# by the test case for bug 916135. +if child_node is not node: +graph.add(child_node, node, priority=mypriority) if debug: writemsg_level("\nunmerge digraph:\n\n", noiselevel=-1, level=logging.DEBUG) diff --git a/lib/portage/tests/resolver/test_depclean_order.py b/lib/portage/tests/resolver/test_depclean_order.py index 867b1a54ca..23b5e755c3 100644 --- a/lib/portage/tests/resolver/test_depclean_order.py +++ b/lib/portage/tests/resolver/test_depclean_order.py @@ -1,8 +1,6 @@ -# Copyright 2013 Gentoo Foundation +# Copyright 2013-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 -import pytest - from portage.tests import TestCase from portage.tests.resolver.ResolverPlayground import ( ResolverPlayground, @@ -60,8 +58,12 @@ class SimpleDepcleanTestCase(TestCase): finally: playground.cleanup() -@pytest.mark.xfail() def testIDEPENDDepclean(self): +""" +Test for bug 916135, where a direct circular dependency caused +the unmerge order to fail to account for IDEPEND. +""" + ebuilds = { "dev-util/A-1": {}, "dev-libs/B-1": {
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 1d856747ada48f8d32c033091b1156cc655efed3 Author: Zac Medico gentoo org> AuthorDate: Wed Dec 6 06:05:46 2023 + Commit: Zac Medico gentoo org> CommitDate: Wed Dec 6 20:23:14 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=1d856747 DepPriority{Normal,Satisfied}Range: weaken _ignore_runtime for cross root When the dependency parent is for a cross root (ROOT != /) package, weaken _ignore_runtime in order to tolerate runtime cycles that are less problematic for cross root packages. The included test case fails with this error without the fix: * Error: circular dependencies: (dev-libs/gmp-6.3.0:0/10.4::test_repo, binary scheduled for merge to '/tmp/tmp25nwdjn7/cross_root/') depends on (sys-devel/gcc-13.2.1_p20230826:0/0::test_repo, binary scheduled for merge to '/tmp/tmp25nwdjn7/cross_root/') (runtime) (dev-libs/gmp-6.3.0:0/10.4::test_repo, binary scheduled for merge to '/tmp/tmp25nwdjn7/cross_root/') (runtime_slot_op) It might be possible to break this cycle by applying the following change: - dev-libs/gmp-6.3.0 (Change USE: -cxx) Bug: https://bugs.gentoo.org/919174 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/DepPriority.py | 4 +- lib/_emerge/DepPriorityNormalRange.py | 4 +- lib/_emerge/DepPrioritySatisfiedRange.py | 1 + lib/_emerge/UnmergeDepPriority.py | 3 +- lib/_emerge/depgraph.py| 46 -- lib/portage/tests/resolver/meson.build | 1 + .../tests/resolver/test_cross_dep_priority.py | 164 + 7 files changed, 208 insertions(+), 15 deletions(-) diff --git a/lib/_emerge/DepPriority.py b/lib/_emerge/DepPriority.py index 99d38477e2..8d282b937a 100644 --- a/lib/_emerge/DepPriority.py +++ b/lib/_emerge/DepPriority.py @@ -1,11 +1,11 @@ -# Copyright 1999-2013 Gentoo Foundation +# Copyright 1999-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 from _emerge.AbstractDepPriority import AbstractDepPriority class DepPriority(AbstractDepPriority): -__slots__ = ("satisfied", "optional", "ignored") +__slots__ = ("cross", "ignored", "optional", "satisfied") def __int__(self): """ diff --git a/lib/_emerge/DepPriorityNormalRange.py b/lib/_emerge/DepPriorityNormalRange.py index d7e4381b47..cb0e6c26b1 100644 --- a/lib/_emerge/DepPriorityNormalRange.py +++ b/lib/_emerge/DepPriorityNormalRange.py @@ -1,4 +1,4 @@ -# Copyright 1999-2011 Gentoo Foundation +# Copyright 1999-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 from _emerge.DepPriority import DepPriority @@ -41,7 +41,7 @@ class DepPriorityNormalRange: # to adjust this appropriately. But only build time dependencies # are optional right now, so it's not an issue as-is. return bool( -not priority.runtime_slot_op +not (priority.runtime_slot_op and not priority.cross) and (priority.optional or not priority.buildtime) ) diff --git a/lib/_emerge/DepPrioritySatisfiedRange.py b/lib/_emerge/DepPrioritySatisfiedRange.py index 0d42e7613d..b3bc90c2ff 100644 --- a/lib/_emerge/DepPrioritySatisfiedRange.py +++ b/lib/_emerge/DepPrioritySatisfiedRange.py @@ -96,6 +96,7 @@ class DepPrioritySatisfiedRange: ( (not priority.runtime_slot_op) or (priority.satisfied and priority.runtime_slot_op) +or priority.cross ) and (priority.satisfied or priority.optional or not priority.buildtime) ) diff --git a/lib/_emerge/UnmergeDepPriority.py b/lib/_emerge/UnmergeDepPriority.py index ff81eff46f..d818bad1b8 100644 --- a/lib/_emerge/UnmergeDepPriority.py +++ b/lib/_emerge/UnmergeDepPriority.py @@ -1,4 +1,4 @@ -# Copyright 1999-2013 Gentoo Foundation +# Copyright 1999-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 from _emerge.AbstractDepPriority import AbstractDepPriority @@ -6,6 +6,7 @@ from _emerge.AbstractDepPriority import AbstractDepPriority class UnmergeDepPriority(AbstractDepPriority): __slots__ = ( +"cross", "ignored", "optional", "satisfied", diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 9b09701021..59c78c7354 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -3630,7 +3630,7 @@ class depgraph: blocker=False, depth=depth, parent=pkg, -priority=self._priority(runtime=True), +priority=self._priority(cross=self._cross(pkg.root), runtime=True), root=pkg.root, ) if not self._add_dep(dep, allow_unsatisfied=allow_unsatisfied): @@ -3968,17 +3968,26 @@ class depgraph: # _dep_disjunctive_stack first, so
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 3487594cd8f46a5c83caaab3a9425321443e5efc Author: Zac Medico gentoo org> AuthorDate: Tue Nov 28 04:58:07 2023 + Commit: Zac Medico gentoo org> CommitDate: Tue Nov 28 22:41:45 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=3487594c Increase ignore_priority during topological sort for runtime cycle Fix AlternativesGzipTestCase by increasing ignore_priority in order to find smaller groups of leaf nodes during topological sort for runtime cycles. This causes some changes in merge order for MergeOrderTestCase, but they appear to be acceptable since they prevent temporarily unsatisfied RDEPEND by relying on satisfied installed build-time dependencies. Bug: https://bugs.gentoo.org/917259 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/depgraph.py| 27 -- .../tests/resolver/test_alternatives_gzip.py | 8 +++ lib/portage/tests/resolver/test_merge_order.py | 20 .../tests/resolver/test_rebuild_ghostscript.py | 2 +- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 29eadba3d1..da37f980ad 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -9478,17 +9478,30 @@ class depgraph: ) selected_nodes = [] while cycle_digraph: +# Increase ignore_priority in order to find +# smaller groups of leaf nodes. This solves +# bug 917259 which happened because too many +# leaves were selected at once. +smallest_leaves = None for ignore_priority in ignore_priorities: leaves = cycle_digraph.leaf_nodes( ignore_priority=ignore_priority ) -if leaves: -cycle_digraph.difference_update(leaves) -selected_nodes.extend(leaves) -break -else: -selected_nodes.extend(cycle_digraph) -break +if leaves and ( +smallest_leaves is None +or len(leaves) < len(smallest_leaves) +): +smallest_leaves = leaves +if len(smallest_leaves) == 1: +break + +if smallest_leaves is None: +smallest_leaves = [cycle_digraph.order[-1]] + +# Only harvest one node at a time, in order to +# minimize the number of ignored dependencies. +cycle_digraph.remove(smallest_leaves[0]) +selected_nodes.append(smallest_leaves[0]) if not selected_nodes and myblocker_uninstalls: # An Uninstall task needs to be executed in order to diff --git a/lib/portage/tests/resolver/test_alternatives_gzip.py b/lib/portage/tests/resolver/test_alternatives_gzip.py index 602ed1756f..e763e84640 100644 --- a/lib/portage/tests/resolver/test_alternatives_gzip.py +++ b/lib/portage/tests/resolver/test_alternatives_gzip.py @@ -1,8 +1,6 @@ # Copyright 2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 -import pytest - from portage.tests import TestCase from portage.tests.resolver.ResolverPlayground import ( ResolverPlayground, @@ -10,7 +8,6 @@ from portage.tests.resolver.ResolverPlayground import ( ) -@pytest.mark.xfail() class AlternativesGzipTestCase(TestCase): def testAlternativesGzip(self): """ @@ -19,8 +16,9 @@ class AlternativesGzipTestCase(TestCase): find_smallest_cycle selects a large cycle and the topological sort produces poor results when leaf_nodes returns app-alternatives/gzip as part of a large group of nodes. -This problem might be solved by implementing a finer-grained -ignore_priority for leaf_nodes calls. +This problem was solved by changing the topological sort to +increase ignore_priority in order to select a smaller number +of leaf nodes at a time. """ ebuilds = { "app-alternatives/gzip-1": { diff --git a/lib/portage/tests/resolver/test_merge_order.py b/lib/portage/tests/resolver/test_merge_order.py index 940eb3bbbe..e6d45c847b 100644 --- a/lib/portage/tests/resolver/test_merge_order.py +++ b/lib/portage/tests/resolver/test_merge_order.py @@ -1,4 +1,4 @@ -# Copyright 2011-2020 Gentoo Authors +# Copyright 2011-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 from portage.tests import TestCase @@ -382,10 +382,12 @@ class MergeOrderTestCase(TestCase): ambiguous_merge_order=True,
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 2e298ea7ba36801a1cfba6e4cbfc16a7c05ee73d Author: Sam James gentoo org> AuthorDate: Tue Nov 28 06:22:44 2023 + Commit: Sam James gentoo org> CommitDate: Tue Nov 28 22:07:46 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=2e298ea7 DepPriority{Normal,Satisfied}Range: strengthen _ignore_runtime for runtime slot operators In the reported bug, net-misc/curl gets merged (binary), then dev-util/cmake gets bulit (from source) which fails because one of the built curl's dependencies (net-libs/nghttp2) is missing: ``` [binary R] net-misc/curl-8.4.0::test_repo USE="http2%*" 0 KiB [ebuild U ] dev-util/cmake-3.27.8::test_repo [3.26.5-r2::test_repo] 0 KiB [ebuild N ] net-libs/nghttp2-1.57.0::test_repo 0 KiB ``` Zac had the idea [0] of strengthening _ignore_runtime to consider runtime slot deps as well, so we now get: ``` [ebuild U ] dev-util/cmake-3.27.8::test_repo [3.26.5-r2::test_repo] 0 KiB [ebuild N ] net-libs/nghttp2-1.57.0::test_repo 0 KiB [binary R] net-misc/curl-8.4.0::test_repo USE="http2%*" 0 KiB ``` For DepPrioritySatisfiedRange, we now allow ignoring the dep if: * it's either a satisfied runtime slot dep, or it's not a runtime slot dep at all, and * the dep is satisfied or it's optional/not a build time dep. (i.e. we now prevent ignoring the slot dep unless it's satisfied.) For DepPriorityNormalRange, we now allow ignoring the dep if: * it's not a runtime slot dep, and * it's optional, or * it's not a buildtime dep. (i.e. we now prevent ignoring the slot dep.) We then realise we can't ignore curl's dep on nghttp2 and come up with a better order. [0] https://github.com/gentoo/portage/pull/1193#issuecomment-1829178126 Bug: https://bugs.gentoo.org/918683 Thanks-to: Zac Medico gentoo.org> Signed-off-by: Sam James gentoo.org> lib/_emerge/DepPriorityNormalRange.py | 8 +++- lib/_emerge/DepPrioritySatisfiedRange.py| 13 +++-- .../tests/resolver/test_runtime_cycle_merge_order.py| 9 - 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/_emerge/DepPriorityNormalRange.py b/lib/_emerge/DepPriorityNormalRange.py index a85e1b9c14..d7e4381b47 100644 --- a/lib/_emerge/DepPriorityNormalRange.py +++ b/lib/_emerge/DepPriorityNormalRange.py @@ -37,7 +37,13 @@ class DepPriorityNormalRange: def _ignore_runtime(cls, priority): if priority.__class__ is not DepPriority: return False -return bool(priority.optional or not priority.buildtime) +# If we ever allow "optional" runtime_slot_op, we'll need +# to adjust this appropriately. But only build time dependencies +# are optional right now, so it's not an issue as-is. +return bool( +not priority.runtime_slot_op +and (priority.optional or not priority.buildtime) +) ignore_medium = _ignore_runtime ignore_medium_soft = _ignore_runtime_post diff --git a/lib/_emerge/DepPrioritySatisfiedRange.py b/lib/_emerge/DepPrioritySatisfiedRange.py index 0633a5e1c2..0d42e7613d 100644 --- a/lib/_emerge/DepPrioritySatisfiedRange.py +++ b/lib/_emerge/DepPrioritySatisfiedRange.py @@ -1,4 +1,4 @@ -# Copyright 1999-2013 Gentoo Foundation +# Copyright 1999-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 from _emerge.DepPriority import DepPriority @@ -89,7 +89,16 @@ class DepPrioritySatisfiedRange: def _ignore_runtime(cls, priority): if priority.__class__ is not DepPriority: return False -return bool(priority.satisfied or priority.optional or not priority.buildtime) +# We could split this up into 2 variants (ignoring satisfied +# runtime_slot_op, and not) if we need more granularity for ignore_priority +# in future. +return bool( +( +(not priority.runtime_slot_op) +or (priority.satisfied and priority.runtime_slot_op) +) +and (priority.satisfied or priority.optional or not priority.buildtime) +) ignore_medium = _ignore_runtime ignore_medium_soft = _ignore_satisfied_buildtime_slot_op diff --git a/lib/portage/tests/resolver/test_runtime_cycle_merge_order.py b/lib/portage/tests/resolver/test_runtime_cycle_merge_order.py index 26850ccad2..ed329aa097 100644 --- a/lib/portage/tests/resolver/test_runtime_cycle_merge_order.py +++ b/lib/portage/tests/resolver/test_runtime_cycle_merge_order.py @@ -1,4 +1,4 @@ -# Copyright 2016 Gentoo Foundation +# Copyright 2016-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 from portage.tests import TestCase @@ -7,8 +7,6 @@ from portage.tests.resolver.ResolverPlayground import ( ResolverPlaygroundTestCase, ) -import pytest - class RuntimeCycleMergeOrderTestCase(TestCase): def testRuntimeCycleMergeOrder(self): @@ -77,7
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 49e01d041c74680a81860b819daff812d83df02f Author: Zac Medico gentoo org> AuthorDate: Tue Nov 28 03:42:17 2023 + Commit: Zac Medico gentoo org> CommitDate: Tue Nov 28 03:42:17 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=49e01d04 find_smallest_cycle: Optimize to traverse fewer nodes If gather_deps is traversing a cycle that is greater than or equal to the size of the current smallest_cycle, then abort early. Also abort early if we traverse a node encountered in a previous cycle for the same ignore_priority, since that means the two cycles are identical. On my laptop, this brings the emerge -pe @world time down to 3m28.884s, compared to 10m44.268s with portage-3.0.55. Bug: https://bugs.gentoo.org/918682 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/depgraph.py| 36 -- .../tests/resolver/test_rebuild_ghostscript.py | 2 +- .../resolver/test_runtime_cycle_merge_order.py | 7 +++-- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index e4305c18c9..29eadba3d1 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -9151,7 +9151,14 @@ class depgraph: asap_nodes.extend(libc_pkgs) -def gather_deps(ignore_priority, mergeable_nodes, selected_nodes, node): +def gather_deps( +ignore_priority, +mergeable_nodes, +selected_nodes, +node, +smallest_cycle=None, +traversed_nodes=None, +): """ Recursively gather a group of nodes that RDEPEND on eachother. This ensures that they are merged as a group @@ -9171,10 +9178,24 @@ class depgraph: # RDEPENDs installed first, but ignore uninstalls # (these occur when new portage blocks an older package version). return False +if traversed_nodes is not None: +if node in traversed_nodes: +# Identical to a previously traversed cycle. +return False +traversed_nodes.add(node) selected_nodes.add(node) +if smallest_cycle is not None and len(selected_nodes) >= len( +smallest_cycle +): +return False for child in mygraph.child_nodes(node, ignore_priority=ignore_priority): if not gather_deps( -ignore_priority, mergeable_nodes, selected_nodes, child +ignore_priority, +mergeable_nodes, +selected_nodes, +child, +smallest_cycle=smallest_cycle, +traversed_nodes=traversed_nodes, ): return False return True @@ -9332,12 +9353,21 @@ class depgraph: local_priority_range.MEDIUM_SOFT + 1, ) ): +# Traversed nodes for current priority +traversed_nodes = set() for node in nodes: if not mygraph.parent_nodes(node): continue +if node in traversed_nodes: +continue selected_nodes = set() if gather_deps( -priority, mergeable_nodes, selected_nodes, node +priority, +mergeable_nodes, +selected_nodes, +node, +smallest_cycle=smallest_cycle, +traversed_nodes=traversed_nodes, ): if smallest_cycle is None or len(selected_nodes) < len( smallest_cycle diff --git a/lib/portage/tests/resolver/test_rebuild_ghostscript.py b/lib/portage/tests/resolver/test_rebuild_ghostscript.py index 8d7cbb1f92..88dc2b5fc3 100644 --- a/lib/portage/tests/resolver/test_rebuild_ghostscript.py +++ b/lib/portage/tests/resolver/test_rebuild_ghostscript.py @@ -137,9 +137,9 @@ class RebuildGhostscriptTestCase(TestCase): mergelist=[ "sys-apps/dbus-1.15.6", "x11-libs/gtk+-3.24.38", +"app-text/ghostscript-gpl-10.01.2", "net-print/cups-2.4.6", "net-dns/avahi-0.8-r7", -"app-text/ghostscript-gpl-10.01.2", "app-text/libspectre-0.2.12", "x11-libs/goffice-0.10.55", ], diff --git a/lib/portage/tests/resolver/test_runtime_cycle_merge_order.py
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 9206d5a75ecd2d9ae0fe63e57d28aa8061b5927e Author: Zac Medico gentoo org> AuthorDate: Sat Nov 18 17:07:59 2023 + Commit: Zac Medico gentoo org> CommitDate: Sun Nov 19 04:15:22 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=9206d5a7 find_smallest_cycle: Increase ignore_priority to find smaller cycles Fix AlternativesGzipTestCase by increasing ignore_priority in order to find smaller cycles. This causes some changes in merge order for MergeOrderTestCase, but they appear to be acceptable since they prevent temporarily unsatisfied RDEPEND by relying on satisfied installed build-time dependencies. Add a test case for bug 690436, since the change to merge order in MergeOrderTestCase is related (see commit 680276cc4d4f). Bug: https://bugs.gentoo.org/690436 Bug: https://bugs.gentoo.org/917259 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/depgraph.py| 7 +- lib/portage/tests/resolver/meson.build | 1 + .../tests/resolver/test_alternatives_gzip.py | 7 +- lib/portage/tests/resolver/test_merge_order.py | 24 ++-- .../tests/resolver/test_rebuild_ghostscript.py | 160 + 5 files changed, 180 insertions(+), 19 deletions(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index e4305c18c9..0d3b37c698 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -9345,9 +9345,10 @@ class depgraph: smallest_cycle = selected_nodes ignore_priority = priority -# Exit this loop with the lowest possible priority, which -# minimizes the use of installed packages to break cycles. -if smallest_cycle is not None: +if smallest_cycle is not None and len(smallest_cycle) == 1: +# The cycle can't get any smaller than this, +# so there is no need to search further since +# we try to minimize ignore_priority. break return smallest_cycle, ignore_priority diff --git a/lib/portage/tests/resolver/meson.build b/lib/portage/tests/resolver/meson.build index 7d2bd367d4..770027ac47 100644 --- a/lib/portage/tests/resolver/meson.build +++ b/lib/portage/tests/resolver/meson.build @@ -49,6 +49,7 @@ py.install_sources( 'test_profile_default_eapi.py', 'test_profile_package_set.py', 'test_rebuild.py', +'test_rebuild_ghostscript.py', 'test_regular_slot_change_without_revbump.py', 'test_required_use.py', 'test_runtime_cycle_merge_order.py', diff --git a/lib/portage/tests/resolver/test_alternatives_gzip.py b/lib/portage/tests/resolver/test_alternatives_gzip.py index 602ed1756f..7cd1da25f1 100644 --- a/lib/portage/tests/resolver/test_alternatives_gzip.py +++ b/lib/portage/tests/resolver/test_alternatives_gzip.py @@ -1,8 +1,6 @@ # Copyright 2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 -import pytest - from portage.tests import TestCase from portage.tests.resolver.ResolverPlayground import ( ResolverPlayground, @@ -10,7 +8,6 @@ from portage.tests.resolver.ResolverPlayground import ( ) -@pytest.mark.xfail() class AlternativesGzipTestCase(TestCase): def testAlternativesGzip(self): """ @@ -19,8 +16,8 @@ class AlternativesGzipTestCase(TestCase): find_smallest_cycle selects a large cycle and the topological sort produces poor results when leaf_nodes returns app-alternatives/gzip as part of a large group of nodes. -This problem might be solved by implementing a finer-grained -ignore_priority for leaf_nodes calls. +This problem was solved by increasing ignore_priority in order +to find a smaller cycle. """ ebuilds = { "app-alternatives/gzip-1": { diff --git a/lib/portage/tests/resolver/test_merge_order.py b/lib/portage/tests/resolver/test_merge_order.py index 940eb3bbbe..671543ca29 100644 --- a/lib/portage/tests/resolver/test_merge_order.py +++ b/lib/portage/tests/resolver/test_merge_order.py @@ -382,10 +382,12 @@ class MergeOrderTestCase(TestCase): ambiguous_merge_order=True, # The following merge order assertion reflects optimal order for # a circular relationship which is DEPEND in one direction and -# RDEPEND in the other. -merge_order_assertions=( -("app-misc/circ-buildtime-a-1", "app-misc/circ-buildtime-c-1"), -), +# RDEPEND in the other. However, it is not respected because +# it would result in a temporarily broken RDEPEND, so we instead +# rely on satisfied installed build-time dependencies.
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/, /
commit: c56ca69564452198039e17b3a07f24f5b87a6852 Author: Sam James gentoo org> AuthorDate: Mon Nov 6 15:03:10 2023 + Commit: Sam James gentoo org> CommitDate: Mon Nov 6 15:57:56 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=c56ca695 emerge: fix _show_ignored_binaries_respect_use with incomplete depgraph I've gone for the simpler solution of just using an empty tuple where the merge list is empty to preserve prior behaviour with what we do (or do not) display wrt skipped binaries. Bug: https://bugs.gentoo.org/916614 Signed-off-by: Sam James gentoo.org> NEWS| 2 + lib/_emerge/depgraph.py | 4 +- lib/portage/tests/resolver/test_useflags.py | 89 + 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 4a33559a33..89d9335275 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ Bug fixes: * Avoid crash with incomplete depgraph for binpkg-respect-use notice (bug #916614). +* Avoid crash with blockers in depgraph for binpkg-respect-use notice (bug #916336). + portage-3.0.54 (2023-10-25) -- diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index d1fed0d652..e4305c18c9 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -1234,11 +1234,13 @@ class depgraph: def _show_ignored_binaries_respect_use(self, respect_use): seen = {} messages = [] + merging = { (pkg.root, pkg.cpv) -for pkg in self._dynamic_config._displayed_list +for pkg in self._dynamic_config._displayed_list or () if isinstance(pkg, Package) } + for pkg, flags in respect_use.items(): # Don't include recursive deps which aren't in the merge list anyway. if (pkg.root, pkg.cpv) not in merging: diff --git a/lib/portage/tests/resolver/test_useflags.py b/lib/portage/tests/resolver/test_useflags.py index ee9f4f2763..86684f7f28 100644 --- a/lib/portage/tests/resolver/test_useflags.py +++ b/lib/portage/tests/resolver/test_useflags.py @@ -229,3 +229,92 @@ class UseFlagsTestCase(TestCase): ) finally: playground.cleanup() + +def testNoMergeBinpkgRespectUse(self): +""" +Testcase for bug #916614 where an incomplete depgraph may be fed into +_show_ignored_binaries_respect_use. + +We use a mix of +/-abi_x86_32 to trigger the binpkg-respect-use notice +and depend on a non-existent package in one of the available ebuilds we +queue to reinstall to trigger an aborted calculation. +""" +ebuilds = { +"dev-libs/A-2": { +"EAPI": "7", +"IUSE": "abi_x86_32", +}, +"dev-libs/B-1": { +"IUSE": "abi_x86_32", +"RDEPEND": "=dev-libs/A-1", +}, +} + +installed = { +"dev-libs/B-1": { +"IUSE": "abi_x86_32", +"USE": "abi_x86_32", +}, +"dev-libs/A-1": { +"IUSE": "abi_x86_32", +"USE": "abi_x86_32", +}, +} + +binpkgs = { +"dev-libs/A-2": { +"IUSE": "abi_x86_32", +"USE": "abi_x86_32", +}, +"dev-libs/B-1": { +"IUSE": "abi_x86_32", +"USE": "", +"BUILD_ID": "2", +"BUILD_TIME": "2", +}, +} + +user_config = { +"make.conf": ( +'FEATURES="binpkg-multi-instance"', +'USE="abi_x86_32 abi_x86_32"', +), +} + +world = ("dev-libs/A",) + +test_cases = ( +ResolverPlaygroundTestCase( +["@installed"], +options={ +"--verbose": "y", +"--emptytree": True, +"--usepkg": True, +}, +success=False, +mergelist=["[binary]dev-libs/A-2", "dev-libs/B-1"], +slot_collision_solutions=[], +), +) + +for binpkg_format in SUPPORTED_GENTOO_BINPKG_FORMATS: +with self.subTest(binpkg_format=binpkg_format): +print(colorize("HILITE", binpkg_format), end=" ... ") +sys.stdout.flush() +user_config["make.conf"] += (f'BINPKG_FORMAT="{binpkg_format}"',) +playground = ResolverPlayground( +ebuilds=ebuilds, +binpkgs=binpkgs, +installed=installed, +user_config=user_config, +world=world, +) + +try: +for test_case in test_cases: +
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/, /
commit: 262b8c9213c6698be4a7e2ce88536568899e6c2a Author: Sam James gentoo org> AuthorDate: Mon Oct 30 05:30:04 2023 + Commit: Sam James gentoo org> CommitDate: Mon Nov 6 15:57:56 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=262b8c92 emerge: fix binpkg-respect-use notice with blockers Items in _dynamic_config._displayed_list might be blockers, so filter those out. Bug: https://bugs.gentoo.org/916336 Fixes: bb82666b48e18f448661a1a8bf6a39b773cc4b1c Signed-off-by: Sam James gentoo.org> NEWS| 2 + lib/_emerge/depgraph.py | 6 +- lib/portage/tests/resolver/test_useflags.py | 87 + 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index be551de33d..4a33559a33 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ Bug fixes: * Convert portageq helper to a function to avoid breaking external callers (bug #916287, bug #916296). +* Avoid crash with incomplete depgraph for binpkg-respect-use notice (bug #916614). + portage-3.0.54 (2023-10-25) -- diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 85845dc1e2..0717e0429f 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -1234,7 +1234,11 @@ class depgraph: def _show_ignored_binaries_respect_use(self, respect_use): seen = {} messages = [] -merging = {pkg.cpv for pkg in self._dynamic_config._displayed_list} +merging = { +pkg.cpv +for pkg in self._dynamic_config._displayed_list +if isinstance(pkg, Package) +} for pkg, flags in respect_use.items(): # Don't include recursive deps which aren't in the merge list anyway. if pkg.cpv not in merging: diff --git a/lib/portage/tests/resolver/test_useflags.py b/lib/portage/tests/resolver/test_useflags.py index 0af1cb5585..ee9f4f2763 100644 --- a/lib/portage/tests/resolver/test_useflags.py +++ b/lib/portage/tests/resolver/test_useflags.py @@ -142,3 +142,90 @@ class UseFlagsTestCase(TestCase): ) finally: playground.cleanup() + +def testBlockerBinpkgRespectUse(self): +""" +Test for bug #916336 where we tried to check properties of a blocker +object which isn't a Package to be merged. +""" + +ebuilds = { +"dev-libs/A-1": { +"EAPI": "7", +"IUSE": "abi_x86_32", +"RDEPEND": "dev-libs/B", +}, +"dev-libs/B-1": { +"EAPI": "7", +"IUSE": "abi_x86_32", +}, +"dev-libs/A-2": { +"EAPI": "7", +"IUSE": "abi_x86_32", +"RDEPEND": "!
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 224207c7d1988a354d004507bb7ecfb90b4ef097 Author: YiFei Zhu gmail com> AuthorDate: Tue Jun 13 00:47:52 2023 + Commit: Sam James gentoo org> CommitDate: Fri Jun 16 03:34:46 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=224207c7 depgraph: Do not allow slotted deps to be satisfied by wrong slots This may be part of what caused the "perl rebuild bug". The "priority" of perl, when seen by perl modules, may have "satisfied" set to an installed perl of a wrong slot. Compounding this factor with bug #756199 where find_smallest_cycle would select a single node, in this case because the dependency of perl is satisfied and the priority then gets ignored, the "cycle" becomes a perl module alone and gets rebuilt early. I also updated the test from the previous patch to account for this change. No other tests seems affected. For a larger scale test, I reproduced this initially with a stage3 chroot from a Jan 1 2022 stage3 snapshot, and testing in an equivalent dockerfile would work too: FROM gentoo/stage3:amd64-openrc-20220101 RUN emerge-webrsync COPY . /portage Before this patch (USE flags omitted): # cd /portage && bin/emerge -puDN @world 2>&1 | grep -i perl [ebuild U ] app-admin/perl-cleaner-2.30-r1 [2.30] [ebuild rR] virtual/perl-File-Temp-0.231.100 [ebuild rR] dev-perl/Locale-gettext-1.70.0-r1 [ebuild rR] dev-perl/MIME-Charset-1.12.2-r1 [ebuild rR] dev-perl/Module-Build-0.423.100 [ebuild rR] dev-perl/Text-CharWidth-0.40.0-r2 [ebuild U ] dev-lang/perl-5.36.0-r2 [5.34.0-r3] [ebuild N ] virtual/perl-CPAN-2.330.0 [ebuild U ] virtual/perl-ExtUtils-MakeMaker-7.640.0 [7.620.0] [ebuild U ] virtual/perl-File-Spec-3.840.0 [3.800.0] [...] After this patch: # cd /portage && bin/emerge -puDN @world 2>&1 | grep -i perl [ebuild U ] app-admin/perl-cleaner-2.30-r1 [2.30] [ebuild U ] dev-lang/perl-5.36.0-r2:0/5.36 [5.34.0-r3:0/5.34] [ebuild N ] virtual/perl-CPAN-2.330.0 [ebuild U ] virtual/perl-ExtUtils-MakeMaker-7.640.0 [7.620.0] [ebuild U ] virtual/perl-Data-Dumper-2.184.0 [2.179.0] [ebuild U ] virtual/perl-File-Spec-3.840.0 [3.800.0] [ebuild U ] virtual/perl-Test-Harness-3.440.0-r1 [3.430.0] [ebuild rR] dev-perl/Pod-Parser-1.630.0-r1 [ebuild rR] dev-perl/Text-CharWidth-0.40.0-r2 [ebuild rR] dev-perl/Text-WrapI18N-0.60.0-r2 [...] Bug: https://bugs.gentoo.org/463976 Bug: https://bugs.gentoo.org/592880 Bug: https://bugs.gentoo.org/596664 Bug: https://bugs.gentoo.org/631490 Bug: https://bugs.gentoo.org/764365 Bug: https://bugs.gentoo.org/793992 Signed-off-by: YiFei Zhu gmail.com> Closes: https://github.com/gentoo/portage/pull/1055 Signed-off-by: Sam James gentoo.org> lib/_emerge/depgraph.py | 18 ++ lib/portage/tests/resolver/test_perl_rebuild_bug.py | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 60e57b226..28acfed9d 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -4042,6 +4042,16 @@ class depgraph: inst_pkg, modified_use=self._pkg_use_enabled(inst_pkg) ) ] +# Do not allow slotted deps to be satisfied by wrong slots. +# Otherwise, slot-operator-dependent packages may rebuild +# before the slotted package they are dependent on. +if child and atom.slot_operator == "=": +inst_pkgs = [ +inst_pkg +for inst_pkg in inst_pkgs +if inst_pkg.slot == child.slot +and inst_pkg.sub_slot == child.sub_slot +] if inst_pkgs: for inst_pkg in inst_pkgs: if self._pkg_visibility_check(inst_pkg): @@ -4161,6 +4171,14 @@ class depgraph: inst_pkg, modified_use=self._pkg_use_enabled(inst_pkg) ) ] +# Do not allow slotted deps to be satisfied by wrong slots. +if child and atom.slot_operator == "=": +inst_pkgs = [ +inst_pkg +for inst_pkg in inst_pkgs +if inst_pkg.slot == child.slot +and inst_pkg.sub_slot == child.sub_slot +] if inst_pkgs: for inst_pkg in inst_pkgs: if self._pkg_visibility_check(inst_pkg): diff --git a/lib/portage/tests/resolver/test_perl_rebuild_bug.py b/lib/portage/tests/resolver/test_perl_rebuild_bug.py index 928fd47d7..7e376f396 100644 --- a/lib/portage/tests/resolver/test_perl_rebuild_bug.py +++
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 44afa8445dc46464200fe46c1e09e0c7475067bf Author: YiFei Zhu gmail com> AuthorDate: Mon Jun 12 02:23:09 2023 + Commit: Sam James gentoo org> CommitDate: Fri Jun 16 03:34:46 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=44afa844 depgraph: Don't ignore downgrades as missed_updates Missed updates can also come in the form of package downgrades, when, for example, there are keyword changes. They can cause rebuilds, and these rebuilds may be not possible due to reasons such as keywords or masks. In this case, prior to this patch, portage would cancel the downgrade, but the rebuilds would be requested endlessly, because bug 439688's backtrack code does not trigger. To reproduce, on an ACCEPT_KEYWORDS=~amd64 machine, emerge =dev-libs/openssl=3.0.9, dev-util/rustup, and something else that depends on openssl. Then un-accept ~amd64 for openssl and rustup. Prior to this patch, a @world upgrade would cause: These are the packages that would be merged, in order: Calculating dependencies... done! [ebuild rR] dev-libs/libevent-2.1.12-r1:0/2.1-7::gentoo [ebuild rR] net-misc/rsync-3.2.7-r2::gentoo [...] Total: 71 packages (71 reinstalls), Size of downloads: 0 KiB There are no packages marked "R", only "rR". There are no section labeled "The following packages are causing rebuilds:" either. After this patch, we have: These are the packages that would be merged, in order: Calculating dependencies... done! Total: 0 packages, Size of downloads: 0 KiB WARNING: One or more updates/rebuilds have been skipped due to a dependency conflict: dev-libs/openssl:0 (dev-libs/openssl-1.1.1u:0/1.1::gentoo, ebuild scheduled for merge) dev-libs/openssl:0/3= required by (dev-util/rustup-1.25.2:0/0::gentoo, installed) I also updated the test from the previous patch to account for this change. No other tests seems affected. Bug: https://bugs.gentoo.org/439688 Bug: https://bugs.gentoo.org/622270 Signed-off-by: YiFei Zhu gmail.com> Closes: https://github.com/gentoo/portage/pull/1053 Signed-off-by: Sam James gentoo.org> lib/_emerge/depgraph.py| 4 +--- lib/portage/tests/resolver/test_slot_conflict_blocked_prune.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 77133e99c..60e57b226 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -1287,9 +1287,7 @@ class depgraph: pkg.root, pkg.slot_atom ): any_selected = True -if chosen_pkg > pkg or ( -not chosen_pkg.installed and chosen_pkg.version == pkg.version -): +if not chosen_pkg.installed and chosen_pkg.version == pkg.version: missed_update = False break if any_selected and missed_update: diff --git a/lib/portage/tests/resolver/test_slot_conflict_blocked_prune.py b/lib/portage/tests/resolver/test_slot_conflict_blocked_prune.py index 14e98cd00..b23126d5f 100644 --- a/lib/portage/tests/resolver/test_slot_conflict_blocked_prune.py +++ b/lib/portage/tests/resolver/test_slot_conflict_blocked_prune.py @@ -63,7 +63,7 @@ class SlotConflictBlockedPruneTestCase(TestCase): ["@world"], options={"--deep": True, "--update": True, "--verbose": True}, success=True, -mergelist=["x11-base/xwayland-23.1.1"], +mergelist=[], ), )
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/, /, man/
commit: 75a4f2c2e07c128fef4d9faf3a8fb9d67565239e Author: Sam James gentoo org> AuthorDate: Thu Feb 16 06:26:07 2023 + Commit: Sam James gentoo org> CommitDate: Tue Feb 21 07:16:27 2023 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=75a4f2c2 emerge: add --update-if-installed This adds a new emerge option '--update-if-installed'. The use case for such an option is as follows: - User finds out libfoo-1.2 is buggy. - They want to upgrade all their systems if libfoo is installed. - They don't want to install libfoo if it's not already installed. Unfortunately, --update fails this last point, hence the need for a new option. Closes: https://github.com/gentoo/portage/pull/988 Signed-off-by: Sam James gentoo.org> NEWS | 4 ++ lib/_emerge/create_depgraph_params.py | 6 ++ lib/_emerge/depgraph.py | 17 - lib/_emerge/main.py | 3 +- lib/portage/tests/resolver/test_update.py | 106 ++ man/emerge.1 | 6 ++ 6 files changed, 140 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 29e9de038..9389d2c09 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ Features: * emerge: add --onlydeps-with-ideps= option (bug #890777) +* emerge: add --update-if-installed option. This is useful for one-shot + emerge commands to be run across several machines to upgrade packages + only if they're installed. + * install-qa-check.d: 60pkgconfig: add opt-in QA_PKGCONFIG_VERSION check * emerge: Log completion of package installs. diff --git a/lib/_emerge/create_depgraph_params.py b/lib/_emerge/create_depgraph_params.py index 531230402..1bbca5de9 100644 --- a/lib/_emerge/create_depgraph_params.py +++ b/lib/_emerge/create_depgraph_params.py @@ -129,6 +129,12 @@ def create_depgraph_params(myopts, myaction): if changed_slot: myparams["changed_slot"] = True +# --update-if-installed implies --update +update_if_installed = myopts.get("--update-if-installed") +if update_if_installed is not None: +myparams["update_if_installed"] = update_if_installed +myopts["--update"] = True + if ( "--update" in myopts or "--newrepo" in myopts diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 1631ed126..412dc7b6f 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -1,4 +1,4 @@ -# Copyright 1999-2021 Gentoo Authors +# Copyright 1999-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import errno @@ -5019,6 +5019,21 @@ class depgraph: pkg, existing_node = self._select_package( myroot, atom, onlydeps=onlydeps ) + +# Is the package installed (at any version)? +if pkg and "update_if_installed" in self._dynamic_config.myparams: +package_is_installed = any( +self._iter_match_pkgs( +self._frozen_config.roots[myroot], "installed", atom +) +) + +# This package isn't eligible for selection in the +# merge list as the user passed --update-if-installed +# and it isn't installed. +if not package_is_installed: +continue + if not pkg: pprovided_match = False for virt_choice in virtuals.get(atom.cp, []): diff --git a/lib/_emerge/main.py b/lib/_emerge/main.py index 38233e05c..850487d36 100644 --- a/lib/_emerge/main.py +++ b/lib/_emerge/main.py @@ -1,4 +1,4 @@ -# Copyright 1999-2020 Gentoo Authors +# Copyright 1999-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import argparse @@ -52,6 +52,7 @@ options = [ "--tree", "--unordered-display", "--update", +"--update-if-installed", ] shortmapping = { diff --git a/lib/portage/tests/resolver/test_update.py b/lib/portage/tests/resolver/test_update.py new file mode 100644 index 0..e67013f9f --- /dev/null +++ b/lib/portage/tests/resolver/test_update.py @@ -0,0 +1,106 @@ +# Copyright 2022-2023 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.tests.resolver.ResolverPlayground import ( +ResolverPlayground, +ResolverPlaygroundTestCase, +) + + +class UpdateIfInstalledTestCase(TestCase): +def testUpdateIfInstalledEmerge(self): +installed = { +"dev-lang/ghc-4": {}, +"dev-libs/larryware-3": {}, +"dev-libs/larryware-ng-3": {}, +"virtual/libc-1": {}, +} + +ebuilds = installed.copy() +ebuilds.update( +
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 5095c2023595a75e2848f1ad3dbe25b5fb451a44 Author: Zac Medico gentoo org> AuthorDate: Mon Nov 16 05:55:54 2020 + Commit: Zac Medico gentoo org> CommitDate: Sun Nov 22 03:19:29 2020 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=5095c202 find_smallest_cycle: enhance search prioritization Enhance the find_smallest_cycle function to prioritize its search so that it will minimize the use of installed packages to break cycles. When installed packages must be used to break cycles, it will now prefer to do this for runtime dependencies over buildtime dependencies, since it's preferable to build against latest versions of buildtime dependencies whenever possible. This should solve some cases of bug 199856 which have been triggered by unsafe reliance on installed packages to break cycles. The included unit test case demonstrates correct merge order for a dependency calculation involving 6 independent cycles. This test case fails with the master branch, due to a buildtime dependency cycle of 3 packages being merged earlier than cycles of 2 packages. We can generalize this to say that the master branch may use an installed package to break an arbitrarily sized cycle in a somewhat random location, even though that cycle may be composed of smaller independent cycles which would be safer to break individually. Bug: https://bugs.gentoo.org/754903 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/DepPriorityNormalRange.py | 2 + lib/_emerge/DepPrioritySatisfiedRange.py | 53 -- lib/_emerge/depgraph.py| 43 - lib/portage/tests/resolver/test_merge_order.py | 10 + 4 files changed, 70 insertions(+), 38 deletions(-) diff --git a/lib/_emerge/DepPriorityNormalRange.py b/lib/_emerge/DepPriorityNormalRange.py index 5f3f3da70..10f205a3b 100644 --- a/lib/_emerge/DepPriorityNormalRange.py +++ b/lib/_emerge/DepPriorityNormalRange.py @@ -14,6 +14,7 @@ class DepPriorityNormalRange: """ MEDIUM = 3 MEDIUM_SOFT = 2 + MEDIUM_POST = 2 SOFT= 1 NONE= 0 @@ -37,6 +38,7 @@ class DepPriorityNormalRange: ignore_medium = _ignore_runtime ignore_medium_soft = _ignore_runtime_post + ignore_medium_post = _ignore_runtime_post ignore_soft= _ignore_optional DepPriorityNormalRange.ignore_priority = ( diff --git a/lib/_emerge/DepPrioritySatisfiedRange.py b/lib/_emerge/DepPrioritySatisfiedRange.py index e056e676f..fb0d7db4e 100644 --- a/lib/_emerge/DepPrioritySatisfiedRange.py +++ b/lib/_emerge/DepPrioritySatisfiedRange.py @@ -8,17 +8,18 @@ class DepPrioritySatisfiedRange: not satisfied and buildtimeHARD not satisfied and runtime 7 MEDIUM - not satisfied and runtime_post 6 MEDIUM_SOFT - satisfied and buildtime_slot_op5 SOFT - satisfied and buildtime4 SOFT - satisfied and runtime 3 SOFT - satisfied and runtime_post 2 SOFT + satisfied and buildtime_slot_op6 MEDIUM_SOFT + satisfied and buildtime5 MEDIUM_SOFT + satisfied and runtime 4 MEDIUM_SOFT + runtime_post 3 MEDIUM_POST + satisfied and runtime_post 2 MEDIUM_POST optional 1 SOFT (none of the above)0 NONE """ MEDIUM = 7 MEDIUM_SOFT = 6 - SOFT= 5 + MEDIUM_POST = 3 + SOFT= 1 NONE= 0 @classmethod @@ -35,42 +36,51 @@ class DepPrioritySatisfiedRange: return True if not priority.satisfied: return False + if priority.buildtime or priority.runtime: + return False return bool(priority.runtime_post) @classmethod - def _ignore_satisfied_runtime(cls, priority): + def _ignore_runtime_post(cls, priority): if priority.__class__ is not DepPriority: return False if priority.optional: return True - if not priority.satisfied: + if priority.buildtime or priority.runtime: return False - return not priority.buildtime + return bool(priority.runtime_post) @classmethod - def _ignore_satisfied_buildtime(cls, priority): + def _ignore_satisfied_runtime(cls, priority): if priority.__class__ is not DepPriority: return False if priority.optional: return True - if priority.buildtime_slot_op: +
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: f64310749f176f8921b72ce282b4294efe81c3f0 Author: Zac Medico gentoo org> AuthorDate: Sat Sep 19 21:32:41 2020 + Commit: Zac Medico gentoo org> CommitDate: Sun Sep 20 22:27:32 2020 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=f6431074 _slot_confict_backtrack: minimize conflict atoms (bug 743631) Prefer choices that minimize conflict atoms, so that choices which satisfy all parents are preferred. This reduces the minimum necessary backtrack tries from 21 to 7 for the unit test related to bug 743115. Bug: https://bugs.gentoo.org/743115 Bug: https://bugs.gentoo.org/743631 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/depgraph.py| 6 ++ lib/portage/tests/resolver/test_slot_operator_missed_update.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 3f864aefc..7281d8692 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -1797,6 +1797,12 @@ class depgraph: if parent_atom not in parent_atoms) backtrack_data.append((to_be_masked, conflict_atoms)) + # Prefer choices that minimize conflict atoms. This is intended + # to take precedence over the earlier package version sort. The + # package version sort is still needed or else choices for the + # testOverlapSlotConflict method of VirtualMinimizeChildrenTestCase + # become non-deterministic. + backtrack_data.sort(key=lambda item: len(item[1])) to_be_masked = backtrack_data[-1][0] self._dynamic_config._backtrack_infos.setdefault( diff --git a/lib/portage/tests/resolver/test_slot_operator_missed_update.py b/lib/portage/tests/resolver/test_slot_operator_missed_update.py index fce012f62..1ea701003 100644 --- a/lib/portage/tests/resolver/test_slot_operator_missed_update.py +++ b/lib/portage/tests/resolver/test_slot_operator_missed_update.py @@ -90,7 +90,7 @@ class BacktrackMissedUpdateTestCase(TestCase): # Bug 743115: missed updates trigger excessive backtracking ResolverPlaygroundTestCase( [">=dev-python/pypy3-7.3.2_rc", "@world"], - options={"--update": True, "--deep": True, "--backtrack": 25}, + options={"--update": True, "--deep": True, "--backtrack": 10}, success=True, mergelist=[ "dev-python/pypy3-7.3.2_rc2_p37-r1",
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 079f8c4a36ccc2ef5e25e7a57cd0707640f82592 Author: Zac Medico gentoo org> AuthorDate: Fri Feb 14 19:21:28 2020 + Commit: Zac Medico gentoo org> CommitDate: Fri Feb 14 23:10:37 2020 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=079f8c4a depclean: ensure consistency with update actions (bug 649622) Make depclean traverse dependencies in the same order as update actions, in order to ensure consistency in decisions which are dependent on the order of dependency evaluation due to inconsistent use of || preferences in different packages. In unit tests, update test_virtual_w3m_realistic to assert that the order of graph traversal is deterministic and consistent between update and removal (depclean) actions. Bug: https://bugs.gentoo.org/649622 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/actions.py | 33 +++--- lib/_emerge/depgraph.py | 21 +-- lib/portage/tests/resolver/ResolverPlayground.py | 77 +++- lib/portage/tests/resolver/test_or_choices.py| 12 +++- 4 files changed, 96 insertions(+), 47 deletions(-) diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py index 31252af16..4bf9ce425 100644 --- a/lib/_emerge/actions.py +++ b/lib/_emerge/actions.py @@ -1,8 +1,9 @@ -# Copyright 1999-2019 Gentoo Authors +# Copyright 1999-2020 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 from __future__ import division, print_function, unicode_literals +import collections import errno import logging import operator @@ -741,7 +742,19 @@ def action_depclean(settings, trees, ldpath_mtimes, return rval + def calc_depclean(settings, trees, ldpath_mtimes, + myopts, action, args_set, spinner): + result = _calc_depclean(settings, trees, ldpath_mtimes, + myopts, action, args_set, spinner) + return result.returncode, result.cleanlist, result.ordered, result.req_pkg_count + + +_depclean_result = collections.namedtuple('_depclean_result', + ('returncode', 'cleanlist', 'ordered', 'req_pkg_count', 'depgraph')) + + +def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spinner): allow_missing_deps = bool(args_set) @@ -805,7 +818,7 @@ def calc_depclean(settings, trees, ldpath_mtimes, writemsg_level(_("!!! Aborting due to set configuration " "errors displayed above.\n"), level=logging.ERROR, noiselevel=-1) - return 1, [], False, 0 + return _depclean_result(1, [], False, 0, None) if action == "depclean": emergelog(xterm_titles, " >>> depclean") @@ -920,7 +933,7 @@ def calc_depclean(settings, trees, ldpath_mtimes, resolver.display_problems() if not success: - return 1, [], False, 0 + return _depclean_result(1, [], False, 0, resolver) def unresolved_deps(): @@ -1020,7 +1033,7 @@ def calc_depclean(settings, trees, ldpath_mtimes, return False if unresolved_deps(): - return 1, [], False, 0 + return _depclean_result(1, [], False, 0, resolver) graph = resolver._dynamic_config.digraph.copy() required_pkgs_total = 0 @@ -1321,7 +1334,7 @@ def calc_depclean(settings, trees, ldpath_mtimes, runtime_slot_op=True), root=pkg.root)): resolver.display_problems() - return 1, [], False, 0 + return _depclean_result(1, [], False, 0, resolver) writemsg_level("\nCalculating dependencies ") success = resolver._complete_graph( @@ -1329,9 +1342,9 @@ def calc_depclean(settings, trees, ldpath_mtimes, writemsg_level("\b\b... done!\n") resolver.display_problems() if not success: - return 1, [], False, 0 + return _depclean_result(1, [], False, 0, resolver) if unresolved_deps(): - return 1, [], False, 0 + return _depclean_result(1, [], False, 0, resolver) graph = resolver._dynamic_config.digraph.copy() required_pkgs_total = 0 @@ -1340,7 +1353,7 @@ def calc_depclean(settings, trees, ldpath_mtimes, required_pkgs_total += 1 cleanlist = create_cleanlist() if not cleanlist: - return 0, [], False, required_pkgs_total + return _depclean_result(0, [], False,
[gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/
commit: 1e61c439143b12d079e1fc344bbc0c192a84cbe0 Author: Zac Medico gentoo org> AuthorDate: Wed Sep 11 02:54:51 2019 + Commit: Zac Medico gentoo org> CommitDate: Thu Sep 12 01:31:21 2019 + URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=1e61c439 _add_dep: less aggressive backtracking (bug 693836) In order to suppress the sort of aggressive backtracking that can trigger undesirable downgrades as in bug 693836, do not backtrack for an unsatisfied dependency if there's an available package in the runtime package mask which was involved in a slot conflict and satisfied all involved parent atoms. Instead, discard the current depgraph in favor of other backtracking configurations that may exist. This case would not have been encountered prior to the fix for bug 692746 which enabled backtracking for the type of slot conflict that is detected here. Fixes: 994ac00aa764 ("_slot_confict_backtrack: consider masking a package matched by all parent atoms (bug 692746)") Bug: https://bugs.gentoo.org/693836 Signed-off-by: Zac Medico gentoo.org> lib/_emerge/depgraph.py| 13 .../test_aggressive_backtrack_downgrade.py | 91 ++ 2 files changed, 104 insertions(+) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 6be1b3ec7..51614fc14 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -2888,6 +2888,19 @@ class depgraph(object): dep.atom.without_use if dep.atom.package else dep.atom, onlydeps=dep.onlydeps) if dep_pkg is None: + + # In order to suppress the sort of aggressive + # backtracking that can trigger undesirable downgrades + # as in bug 693836, do not backtrack if there's an + # available package which was involved in a slot + # conflict and satisfied all involved parent atoms. + for dep_pkg, reasons in self._dynamic_config._runtime_pkg_mask.items(): + if (dep.atom.match(dep_pkg) and + len(reasons) == 1 and + not reasons.get("slot conflict", True)): + self._dynamic_config._skip_restart = True + return 0 + self._dynamic_config._backtrack_infos["missing dependency"] = dep self._dynamic_config._need_restart = True if debug: diff --git a/lib/portage/tests/resolver/test_aggressive_backtrack_downgrade.py b/lib/portage/tests/resolver/test_aggressive_backtrack_downgrade.py new file mode 100644 index 0..fbe85dc89 --- /dev/null +++ b/lib/portage/tests/resolver/test_aggressive_backtrack_downgrade.py @@ -0,0 +1,91 @@ +# Copyright 2019 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.tests.resolver.ResolverPlayground import (ResolverPlayground, + ResolverPlaygroundTestCase) + +class AgressiveBacktrackDowngradeTestCase(TestCase): + + def testAgressiveBacktrackDowngrade(self): + + ebuilds = { + 'www-client/firefox-69.0' : { + 'EAPI': '7', + 'RDEPEND': '=media-libs/libvpx-1.7*:0=[postproc] media-video/ffmpeg' + }, + + 'www-client/firefox-60.9.0' : { + 'EAPI': '7', + 'RDEPEND': '' + }, + + 'media-libs/libvpx-1.8.0' : { + 'EAPI': '7', + 'SLOT' : '0/6', + 'IUSE': 'postproc', + }, + + 'media-libs/libvpx-1.7.0' : { + 'EAPI': '7', + 'SLOT' : '0/5', + 'IUSE': '+postproc', + }, + + 'media-libs/libvpx-1.6.0' : { + 'EAPI': '7', + 'SLOT' : '0/4', + 'IUSE': 'postproc', + }, + + 'media-video/ffmpeg-4.2' : { + 'EAPI': '7', + 'RDEPEND':