Gentoo Archives: gentoo-portage-dev

From: Sergei Trofimovich <slyfox@g.o>
To: gentoo-portage-dev@l.g.o
Cc: zmedico@g.o, Sergei Trofimovich <siarheit@××××××.com>, dolsen@g.o, qa@g.o, mgorny@g.o
Subject: [gentoo-portage-dev] [PATCH] repoman: new QA error: slot operator under '||' alternative
Date: Sat, 18 Jun 2016 21:54:45
Message-Id: 20160618215416.26824-1-slyfox@gentoo.org
In Reply to: Re: [gentoo-portage-dev] [PATCH] repoman: new QA error: slot operator under '||' alternative by Brian Dolbec
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: dolsen@g.o
24 CC: qa@g.o
25 CC: mgorny@g.o
26 Signed-off-by: Sergei Trofimovich <siarheit@××××××.com>
27 ---
28 V3: unbaked tree traversal back to _traverse_tree, moved dependency parser out
29 to check_slotop() helper
30 V2: made check_slotop function local, baked tree traversal in it
31 .../repoman/modules/scan/depend/_depend_checks.py | 45 ++++++++++++++++++++++
32 repoman/pym/repoman/qa_data.py | 2 +
33 2 files changed, 47 insertions(+)
34
35 diff --git a/repoman/pym/repoman/modules/scan/depend/_depend_checks.py b/repoman/pym/repoman/modules/scan/depend/_depend_checks.py
36 index 4e1d216..64a35f4 100644
37 --- a/repoman/pym/repoman/modules/scan/depend/_depend_checks.py
38 +++ b/repoman/pym/repoman/modules/scan/depend/_depend_checks.py
39 @@ -3,11 +3,52 @@
40
41 from _emerge.Package import Package
42
43 +from portage.dep import Atom
44 +
45 from repoman.check_missingslot import check_missingslot
46 # import our initialized portage instance
47 from repoman._portage import portage
48 from repoman.qa_data import suspect_virtual, suspect_rdepend
49
50 +def check_slotop(depstr, is_valid_flag, badsyntax, mytype,
51 + qatracker, relative_path):
52 + '''Checks if RDEPEND uses ':=' slot operator
53 + in '||' style dependencies.'''
54 +
55 + try:
56 + # to find use of ':=' in '||' we preserve
57 + # tree structure of dependencies
58 + my_dep_tree = portage.dep.use_reduce(
59 + depstr,
60 + flat=False,
61 + matchall=1,
62 + is_valid_flag=is_valid_flag,
63 + opconvert=True,
64 + token_class=portage.dep.Atom)
65 + except portage.exception.InvalidDependString as e:
66 + my_dep_tree = None
67 + badsyntax.append(str(e))
68 +
69 + def _traverse_tree(dep_tree, in_any_of):
70 + # leaf
71 + if isinstance(dep_tree, Atom):
72 + atom = dep_tree
73 + if in_any_of and atom.slot_operator:
74 + qatracker.add_error("dependency.badslotop",
75 + "%s: %s: '%s' uses ':=' slot operator under '||' dep clause." %
76 + (relative_path, mytype, atom))
77 +
78 + # branches
79 + if isinstance(dep_tree, list):
80 + if len(dep_tree) == 0:
81 + return
82 + # entering any-of
83 + if dep_tree[0] == '||':
84 + _traverse_tree(dep_tree[1:], in_any_of=True)
85 + else:
86 + for branch in dep_tree:
87 + _traverse_tree(branch, in_any_of=in_any_of)
88 + _traverse_tree(my_dep_tree, False)
89
90 def _depend_checks(ebuild, pkg, portdb, qatracker, repo_metadata):
91 '''Checks the ebuild dependencies for errors
92 @@ -117,6 +158,10 @@ def _depend_checks(ebuild, pkg, portdb, qatracker, repo_metadata):
93
94 type_list.extend([mytype] * (len(badsyntax) - len(type_list)))
95
96 + if runtime:
97 + check_slotop(mydepstr, pkg.iuse.is_valid_flag,
98 + badsyntax, mytype, qatracker, ebuild.relative_path)
99 +
100 for m, b in zip(type_list, badsyntax):
101 if m.endswith("DEPEND"):
102 qacat = "dependency.syntax"
103 diff --git a/repoman/pym/repoman/qa_data.py b/repoman/pym/repoman/qa_data.py
104 index b9475e8..48ab389 100644
105 --- a/repoman/pym/repoman/qa_data.py
106 +++ b/repoman/pym/repoman/qa_data.py
107 @@ -58,6 +58,8 @@ qahelp = {
108 "Ebuild has a dependency that refers to an unknown package"
109 " (which may be valid if it is a blocker for a renamed/removed package,"
110 " or is an alternative choice provided by an overlay)"),
111 + "dependency.badslotop": (
112 + "RDEPEND contains ':=' slot operator under '||' dependency."),
113 "file.executable": (
114 "Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do not need"
115 " the executable bit"),
116 --
117 2.9.0