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

Replies