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