Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] emerge --autounmask: prevent unmask due to unsatisfied REQUIRED_USE (bug 622462)
Date: Mon, 26 Mar 2018 07:34:46
Message-Id: 20180326073216.21905-1-zmedico@gentoo.org
1 Fix autounmask to generate USE changes that violate REQUIRED_USE, in
2 order to prevent it from trying to create inappropriate keywords or
3 package.unmask. This solves the problem reported in bug 622462, where
4 it inappropriately unmasked a newer version of qscintilla. With this
5 fix, it will generate USE changes that violate REQUIRED_USE, and then
6 report the issue as follows:
7
8 emerge: there are no ebuilds built with USE flags to satisfy ">=x11-libs/qscintilla-2.9.3-r2:=[qt5(+)]".
9 !!! One of the following packages is required to complete your request:
10 - x11-libs/qscintilla-2.9.4::test_repo (Change USE: +qt5, this change violates use flag constraints defined by x11-libs/qscintilla-2.9.4: 'exactly-one-of ( qt4 qt5 )')
11
12 Note that it may be possible for autounmask to try harder to solve
13 REQUIRED_USE in cases like this, but that it beyond the scope of this
14 bug fix. The only goal of this patch is to correctly handle the case
15 where satisfaction of REQUIRED_USE has failed.
16
17 Bug: https://bugs.gentoo.org/622462
18 ---
19 pym/_emerge/depgraph.py | 20 +++++++++++++++++---
20 pym/portage/tests/resolver/test_autounmask.py | 27 +++++++++++++++++++++++++++
21 2 files changed, 44 insertions(+), 3 deletions(-)
22
23 diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
24 index 6c728684f..7ec3f09a7 100644
25 --- a/pym/_emerge/depgraph.py
26 +++ b/pym/_emerge/depgraph.py
27 @@ -355,6 +355,13 @@ class _rebuild_config(object):
28 return need_restart
29
30
31 +class _use_changes(tuple):
32 + def __new__(cls, new_use, new_changes, required_use_satisfied=True):
33 + obj = tuple.__new__(cls, [new_use, new_changes])
34 + obj.required_use_satisfied = required_use_satisfied
35 + return obj
36 +
37 +
38 class _dynamic_depgraph_config(object):
39
40 """
41 @@ -6130,22 +6137,25 @@ class depgraph(object):
42
43 if new_changes != old_changes:
44 #Don't do the change if it violates REQUIRED_USE.
45 + required_use_satisfied = True
46 required_use = pkg._metadata.get("REQUIRED_USE")
47 if required_use and check_required_use(required_use, old_use,
48 pkg.iuse.is_valid_flag, eapi=pkg.eapi) and \
49 not check_required_use(required_use, new_use,
50 pkg.iuse.is_valid_flag, eapi=pkg.eapi):
51 - return old_use
52 + required_use_satisfied = False
53
54 if any(x in pkg.use.mask for x in new_changes) or \
55 any(x in pkg.use.force for x in new_changes):
56 return old_use
57
58 - self._dynamic_config._needed_use_config_changes[pkg] = (new_use, new_changes)
59 + changes = _use_changes(new_use, new_changes,
60 + required_use_satisfied=required_use_satisfied)
61 + self._dynamic_config._needed_use_config_changes[pkg] = changes
62 backtrack_infos = self._dynamic_config._backtrack_infos
63 backtrack_infos.setdefault("config", {})
64 backtrack_infos["config"].setdefault("needed_use_config_changes", [])
65 - backtrack_infos["config"]["needed_use_config_changes"].append((pkg, (new_use, new_changes)))
66 + backtrack_infos["config"]["needed_use_config_changes"].append((pkg, changes))
67 if want_restart_for_use_change(pkg, new_use):
68 self._dynamic_config._need_restart = True
69 return new_use
70 @@ -9384,6 +9394,10 @@ class depgraph(object):
71 return self._dynamic_config._need_config_reload
72
73 def autounmask_breakage_detected(self):
74 + # Check for REQUIRED_USE violations.
75 + for changes in self._dynamic_config._needed_use_config_changes.values():
76 + if getattr(changes, 'required_use_satisfied', None) is False:
77 + return True
78 try:
79 for pargs, kwargs in self._dynamic_config._unsatisfied_deps_for_display:
80 self._show_unsatisfied_dep(
81 diff --git a/pym/portage/tests/resolver/test_autounmask.py b/pym/portage/tests/resolver/test_autounmask.py
82 index e2a7de028..c9db6141b 100644
83 --- a/pym/portage/tests/resolver/test_autounmask.py
84 +++ b/pym/portage/tests/resolver/test_autounmask.py
85 @@ -61,6 +61,25 @@ class AutounmaskTestCase(TestCase):
86
87 "app-portage/B-1": { "IUSE": "foo +bar", "REQUIRED_USE": "^^ ( foo bar )", "EAPI": "4" },
88 "app-portage/C-1": { "IUSE": "+foo +bar", "REQUIRED_USE": "^^ ( foo bar )", "EAPI": "4" },
89 +
90 + "sci-mathematics/octave-4.2.2": {
91 + "EAPI": 6,
92 + "RDEPEND": ">=x11-libs/qscintilla-2.9.3-r2:=[qt5(+)]",
93 + },
94 + "sci-mathematics/octave-4.2.2": {
95 + "EAPI": 6,
96 + "RDEPEND": ">=x11-libs/qscintilla-2.9.3-r2:=[qt5(+)]",
97 + },
98 + "x11-libs/qscintilla-2.9.4": {
99 + "EAPI": 6,
100 + "IUSE": "+qt4 qt5",
101 + "REQUIRED_USE": "^^ ( qt4 qt5 )",
102 + },
103 + "x11-libs/qscintilla-2.10": {
104 + "EAPI": 6,
105 + "KEYWORDS": "~x86",
106 + "IUSE": "qt4 +qt5",
107 + },
108 }
109
110 test_cases = (
111 @@ -252,6 +271,14 @@ class AutounmaskTestCase(TestCase):
112 use_changes=None,
113 success=False),
114
115 + # Test bug 622462, where it inappropriately unmasked a newer
116 + # version rather than report unsatisfied REQUIRED_USE.
117 + ResolverPlaygroundTestCase(
118 + ["sci-mathematics/octave"],
119 + options={"--autounmask": True},
120 + use_changes=None,
121 + success=False),
122 +
123 #Make sure we don't change masked/forced flags.
124 ResolverPlaygroundTestCase(
125 ["dev-libs/E:1"],
126 --
127 2.13.6