1 |
From: Sergei Trofimovich <siarheit@××××××.com> |
2 |
|
3 |
A few links discussing what can go wrong with slot operator under '||': |
4 |
https://archives.gentoo.org/gentoo-dev/message/81a4e1a1f5767e20009628ecd33da8d4 |
5 |
https://archives.gentoo.org/gentoo-dev/message/66ff016a055e57b6027abcd36734e0e3 |
6 |
|
7 |
The main problem here is how vdb gets updated when you have a dependency of style: |
8 |
RDEPEND="|| ( foo:= bar:= )" |
9 |
depending on what you have installed in system: only 'foo'/'bar' or both 'foo' and 'bar'. |
10 |
|
11 |
I'm about to add actual test for some examples to gen-b0rk. |
12 |
|
13 |
New repoman complains on them as follows: |
14 |
|
15 |
RDEPEND="|| ( =not-broken/pkg1-subslot-0:= =not-broken/pkg1-subslot-1:0= )" |
16 |
|
17 |
Yields: |
18 |
|
19 |
dependency.badslotop [fatal] 2 |
20 |
ebuild-test/RDEPEND-any-of-slotop/RDEPEND-any-of-slotop-0.ebuild: RDEPEND: '=not-broken/pkg1-subslot-0:=' uses ':=' slot operator under '||' dep clause. |
21 |
ebuild-test/RDEPEND-any-of-slotop/RDEPEND-any-of-slotop-0.ebuild: RDEPEND: '=not-broken/pkg1-subslot-1:0=' uses ':=' slot operator under '||' dep clause. |
22 |
|
23 |
CC: qa@g.o |
24 |
CC: mgorny@g.o |
25 |
Signed-off-by: Sergei Trofimovich <siarheit@××××××.com> |
26 |
--- |
27 |
repoman/pym/repoman/check_slotop.py | 32 ++++++++++++++++++++++ |
28 |
.../repoman/modules/scan/depend/_depend_checks.py | 17 ++++++++++++ |
29 |
repoman/pym/repoman/qa_data.py | 2 ++ |
30 |
3 files changed, 51 insertions(+) |
31 |
create mode 100644 repoman/pym/repoman/check_slotop.py |
32 |
|
33 |
diff --git a/repoman/pym/repoman/check_slotop.py b/repoman/pym/repoman/check_slotop.py |
34 |
new file mode 100644 |
35 |
index 0000000..3c3aec1 |
36 |
--- /dev/null |
37 |
+++ b/repoman/pym/repoman/check_slotop.py |
38 |
@@ -0,0 +1,32 @@ |
39 |
+# -*- coding:utf-8 -*- |
40 |
+# repoman: missing slot check |
41 |
+# Copyright 2016 Gentoo Foundation |
42 |
+# Distributed under the terms of the GNU General Public License v2 |
43 |
+ |
44 |
+"""This module contains the check used to find ':=' slot operator |
45 |
+uses in '||' style dependencies.""" |
46 |
+ |
47 |
+from portage.dep import Atom |
48 |
+ |
49 |
+def check_slotop(dep_tree, mytype, qatracker, relative_path): |
50 |
+ def _traverse_tree(dep_tree, is_under_any_of): |
51 |
+ # leaf |
52 |
+ if isinstance(dep_tree, Atom): |
53 |
+ atom = dep_tree |
54 |
+ if is_under_any_of and atom.slot_operator: |
55 |
+ qatracker.add_error("dependency.badslotop", relative_path + |
56 |
+ ": %s: '%s' uses ':=' slot operator under '||' dep clause." % |
57 |
+ (mytype, atom)) |
58 |
+ |
59 |
+ # branches |
60 |
+ if isinstance(dep_tree, list): |
61 |
+ if len(dep_tree) == 0: |
62 |
+ return |
63 |
+ # any-of |
64 |
+ if dep_tree[0] == '||': |
65 |
+ _traverse_tree(dep_tree[1:], True) |
66 |
+ else: |
67 |
+ for branch in dep_tree: |
68 |
+ _traverse_tree(branch, is_under_any_of) |
69 |
+ |
70 |
+ _traverse_tree(dep_tree, False) |
71 |
diff --git a/repoman/pym/repoman/modules/scan/depend/_depend_checks.py b/repoman/pym/repoman/modules/scan/depend/_depend_checks.py |
72 |
index 4e1d216..1fd69d4 100644 |
73 |
--- a/repoman/pym/repoman/modules/scan/depend/_depend_checks.py |
74 |
+++ b/repoman/pym/repoman/modules/scan/depend/_depend_checks.py |
75 |
@@ -4,6 +4,7 @@ |
76 |
from _emerge.Package import Package |
77 |
|
78 |
from repoman.check_missingslot import check_missingslot |
79 |
+from repoman.check_slotop import check_slotop |
80 |
# import our initialized portage instance |
81 |
from repoman._portage import portage |
82 |
from repoman.qa_data import suspect_virtual, suspect_rdepend |
83 |
@@ -117,6 +118,22 @@ def _depend_checks(ebuild, pkg, portdb, qatracker, repo_metadata): |
84 |
|
85 |
type_list.extend([mytype] * (len(badsyntax) - len(type_list))) |
86 |
|
87 |
+ if runtime: |
88 |
+ try: |
89 |
+ # to find use of ':=' in '||' we preserve |
90 |
+ # tree structure of dependencies |
91 |
+ hier_atoms = portage.dep.use_reduce( |
92 |
+ mydepstr, |
93 |
+ flat=False, |
94 |
+ matchall=1, |
95 |
+ is_valid_flag=pkg.iuse.is_valid_flag, |
96 |
+ opconvert=True, |
97 |
+ token_class=token_class) |
98 |
+ except portage.exception.InvalidDependString as e: |
99 |
+ hier_atoms = None |
100 |
+ badsyntax.append(str(e)) |
101 |
+ check_slotop(hier_atoms, mytype, qatracker, ebuild.relative_path) |
102 |
+ |
103 |
for m, b in zip(type_list, badsyntax): |
104 |
if m.endswith("DEPEND"): |
105 |
qacat = "dependency.syntax" |
106 |
diff --git a/repoman/pym/repoman/qa_data.py b/repoman/pym/repoman/qa_data.py |
107 |
index b9475e8..48ab389 100644 |
108 |
--- a/repoman/pym/repoman/qa_data.py |
109 |
+++ b/repoman/pym/repoman/qa_data.py |
110 |
@@ -58,6 +58,8 @@ qahelp = { |
111 |
"Ebuild has a dependency that refers to an unknown package" |
112 |
" (which may be valid if it is a blocker for a renamed/removed package," |
113 |
" or is an alternative choice provided by an overlay)"), |
114 |
+ "dependency.badslotop": ( |
115 |
+ "RDEPEND contains ':=' slot operator under '||' dependency."), |
116 |
"file.executable": ( |
117 |
"Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do not need" |
118 |
" the executable bit"), |
119 |
-- |
120 |
2.9.0 |