Skip to content

Commit

Permalink
emerge: Skip installed packages with emptytree in depgraph selection
Browse files Browse the repository at this point in the history
Running emerge with emptytree tries to find the best match for every
atom it needs to install. Sometimes the best matches would be
already installed packages (with `operation=nomerge`), but these
packages would be silently skipped with full emptytree installation.
This change makes sure that emerge attempts to install every package.
If the package has unmet requirements, emerge will complain.

Bug: https://bugs.gentoo.org/651018
Signed-off-by: Gábor Oszkár Dénes <gaboroszkar@protonmail.com>
Closes: #1272
Signed-off-by: Sam James <sam@gentoo.org>
  • Loading branch information
gaboroszkar authored and thesamesam committed Feb 23, 2024
1 parent fbaaa4a commit 92ff02b
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 4 deletions.
6 changes: 6 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Release notes take the form of the following optional categories:
* Bug fixes
* Cleanups

portage-3.0.63 (UNRELEASED)
--------------

Bug fixes:
* emerge: Skip installed packages with emptytree in depgraph selection (bug #651018).

portage-3.0.62 (2024-02-22)
--------------

Expand Down
13 changes: 13 additions & 0 deletions lib/_emerge/depgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -7639,6 +7639,19 @@ def _wrapped_select_pkg_highest_available_imp(
if pkg.installed and root_slot in self._rebuild.reinstall_list:
continue

if (
empty
and pkg.installed
and not self._frozen_config.excluded_pkgs.findAtomForPackage(
pkg, modified_use=self._pkg_use_enabled(pkg)
)
):
# With --emptytree option we assume no packages
# are installed, so we do not select them.
# But we allow installed packages to satisfy dependency requirements
# if they're explicitly excluded, so we allow them to be selected.
continue

if (
not pkg.installed
and self._frozen_config.excluded_pkgs.findAtomForPackage(
Expand Down
8 changes: 7 additions & 1 deletion lib/portage/tests/resolver/test_depth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2011-2020 Gentoo Authors
# Copyright 2011-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

from portage.tests import TestCase
Expand Down Expand Up @@ -318,6 +318,12 @@ def testResolverDepth(self):
"sys-fs/udev-164",
],
),
ResolverPlaygroundTestCase(
["@world"],
options={"--emptytree": True, "--exclude": ["dev-libs/B"]},
success=True,
mergelist=["dev-libs/C-2", "dev-libs/A-2"],
),
)

playground = ResolverPlayground(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Copyright 2024 Gentoo Foundation
# 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 EmptytreeReinstallUnsatisfiabilityTestCase(TestCase):
def testEmptytreeReinstallUnsatisfiability(self):
"""
Tests to check if emerge fails and complains when --emptytree
package dependency graph reinstall is unsatisfied, even if the already
installed packages successfully satisfy the dependency tree.
See bug #651018 where emerge silently skips package
reinstalls because of unsatisfied use flag requirements.
"""
ebuilds = {
"dev-libs/A-1": {
"DEPEND": "dev-libs/B",
"RDEPEND": "dev-libs/B",
"EAPI": "2",
},
"dev-libs/B-1": {
"DEPEND": "dev-libs/C[foo]",
"RDEPEND": "dev-libs/C[foo]",
"EAPI": "2",
},
"dev-libs/C-1": {
"IUSE": "foo",
"EAPI": "2",
},
"dev-libs/X-1": {
"DEPEND": "dev-libs/Y[-baz]",
"RDEPEND": "dev-libs/Y[-baz]",
"EAPI": "2",
},
"dev-libs/Y-1": {
"IUSE": "baz",
"EAPI": "2",
},
"dev-libs/Z-1": {
"DEPEND": "dev-libs/W",
"RDEPEND": "dev-libs/W",
"EAPI": "2",
},
"dev-libs/W-1": {
"EAPI": "2",
},
}

installed = {
"dev-libs/A-1": {
"DEPEND": "dev-libs/B",
"RDEPEND": "dev-libs/B",
"EAPI": "2",
},
"dev-libs/B-1": {
"DEPEND": "dev-libs/C[foo]",
"RDEPEND": "dev-libs/C[foo]",
"EAPI": "2",
},
"dev-libs/C-1": {
"IUSE": "foo",
"USE": "foo",
"EAPI": "2",
},
"dev-libs/X-1": {
"DEPEND": "dev-libs/Y[-baz]",
"RDEPEND": "dev-libs/Y[-baz]",
"EAPI": "2",
},
"dev-libs/Y-1": {
"IUSE": "baz",
"USE": "-baz",
"EAPI": "2",
},
"dev-libs/Z-1": {
"DEPEND": "dev-libs/W",
"RDEPEND": "dev-libs/W",
"EAPI": "2",
},
"dev-libs/W-1": {
"EAPI": "2",
},
}

user_config = {
"package.use": ("dev-libs/Y baz",),
"package.mask": ("dev-libs/W",),
}

world = ["dev-libs/X"]

test_cases = (
ResolverPlaygroundTestCase(
["dev-libs/A"],
options={"--emptytree": True},
success=False,
mergelist=["dev-libs/C-1", "dev-libs/B-1", "dev-libs/A-1"],
use_changes={"dev-libs/C-1": {"foo": True}},
),
ResolverPlaygroundTestCase(
["dev-libs/A"],
options={"--emptytree": True, "--exclude": ["dev-libs/C"]},
success=True,
mergelist=["dev-libs/B-1", "dev-libs/A-1"],
),
ResolverPlaygroundTestCase(
["@world"],
options={"--emptytree": True},
success=False,
mergelist=["dev-libs/Y-1", "dev-libs/X-1"],
use_changes={"dev-libs/Y-1": {"baz": False}},
),
ResolverPlaygroundTestCase(
["dev-libs/Z"],
options={"--emptytree": True},
success=False,
),
)

playground = ResolverPlayground(
ebuilds=ebuilds,
installed=installed,
user_config=user_config,
world=world,
)
try:
for test_case in test_cases:
playground.run_TestCase(test_case)
self.assertEqual(test_case.test_success, True, test_case.fail_msg)
finally:
playground.cleanup()
6 changes: 3 additions & 3 deletions lib/portage/tests/resolver/test_useflags.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2014 Gentoo Foundation
# Copyright 2014-2024 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import sys
Expand Down Expand Up @@ -292,8 +292,8 @@ def testNoMergeBinpkgRespectUse(self):
"--usepkg": True,
},
success=False,
mergelist=["[binary]dev-libs/A-2", "dev-libs/B-1"],
slot_collision_solutions=[],
mergelist=None,
slot_collision_solutions=None,
),
)

Expand Down

0 comments on commit 92ff02b

Please sign in to comment.