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 |