1 |
commit: 9fefb10f2b5ca6dc3e595e1d318956252f396ed0 |
2 |
Author: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Oct 27 19:07:12 2022 +0000 |
4 |
Commit: Arthur Zamarin <arthurzam <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Nov 4 12:57:44 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=9fefb10f |
7 |
|
8 |
VirtualProvidersCheck: new check for providers issues |
9 |
|
10 |
- check for virtual package defining DEPEND or BDEPEND |
11 |
- check for virtual package with a single provider across versions |
12 |
|
13 |
Closes: https://bugs.gentoo.org/744784 |
14 |
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org> |
15 |
|
16 |
src/pkgcheck/checks/metadata.py | 80 +++++++++++++++++++++- |
17 |
.../VirtualWithBdepend/expected.json | 2 + |
18 |
.../VirtualWithDepend/expected.json | 2 + |
19 |
.../VirtualWithSingleProvider/expected.json | 1 + |
20 |
testdata/repos/standalone/profiles/desc/elibc.desc | 1 + |
21 |
.../repos/standalone/profiles/package.deprecated | 1 + |
22 |
.../VirtualWithBdepend/VirtualWithBdepend-0.ebuild | 6 ++ |
23 |
.../VirtualWithBdepend/VirtualWithBdepend-1.ebuild | 11 +++ |
24 |
.../VirtualWithDepend/VirtualWithDepend-0.ebuild | 6 ++ |
25 |
.../VirtualWithDepend/VirtualWithDepend-1.ebuild | 11 +++ |
26 |
.../VirtualWithSingleProvider1-0.ebuild | 10 +++ |
27 |
.../VirtualWithSingleProvider2-0.ebuild | 10 +++ |
28 |
.../VirtualWithSingleProvider3-0.ebuild | 8 +++ |
29 |
.../VirtualWithSingleProvider3-1.ebuild | 8 +++ |
30 |
.../VirtualWithSingleProvider4-0.ebuild | 8 +++ |
31 |
.../VirtualWithSingleProvider4-1.ebuild | 8 +++ |
32 |
.../VirtualWithSingleProvider5-0.ebuild | 8 +++ |
33 |
.../VirtualWithSingleProvider6-0.ebuild | 9 +++ |
34 |
18 files changed, 189 insertions(+), 1 deletion(-) |
35 |
|
36 |
diff --git a/src/pkgcheck/checks/metadata.py b/src/pkgcheck/checks/metadata.py |
37 |
index 7980942d..6e087c5f 100644 |
38 |
--- a/src/pkgcheck/checks/metadata.py |
39 |
+++ b/src/pkgcheck/checks/metadata.py |
40 |
@@ -7,7 +7,7 @@ from difflib import SequenceMatcher |
41 |
from functools import partial |
42 |
from operator import attrgetter |
43 |
|
44 |
-from pkgcore.ebuild import atom as atom_mod |
45 |
+from pkgcore.ebuild import atom as atom_mod, restricts |
46 |
from pkgcore.ebuild.atom import atom as atom_cls |
47 |
from pkgcore.ebuild.eapi import get_eapi |
48 |
from pkgcore.ebuild.misc import sort_keywords |
49 |
@@ -1627,3 +1627,81 @@ class MissingUnpackerDepCheck(Check): |
50 |
for unpackers, filenames in missing_unpackers.items(): |
51 |
yield MissingUnpackerDep( |
52 |
str(pkg.eapi), sorted(filenames), sorted(unpackers), pkg=pkg) |
53 |
+ |
54 |
+ |
55 |
+class VirtualWithSingleProvider(results.PackageResult, results.Warning): |
56 |
+ """Virtual package with a single remaining provider. |
57 |
+ |
58 |
+ Virtual packages are used to provide a common interface for multiple |
59 |
+ implementations of a given functionality. However, if there is only a |
60 |
+ single implementation, there is no need for a virtual package. In such |
61 |
+ case, consider adding the package to package.deprecated and removing the |
62 |
+ virtual package. |
63 |
+ """ |
64 |
+ |
65 |
+ def __init__(self, provider, **kwargs): |
66 |
+ super().__init__(**kwargs) |
67 |
+ self.provider = str(provider) |
68 |
+ |
69 |
+ @property |
70 |
+ def desc(self): |
71 |
+ return f'virtual package with a single provider: {self.provider}' |
72 |
+ |
73 |
+ |
74 |
+class VirtualWithBdepend(results.VersionResult, results.Warning): |
75 |
+ """Virtual package with a BDEPEND defined.""" |
76 |
+ |
77 |
+ desc = 'virtual package with a BDEPEND defined' |
78 |
+ |
79 |
+ |
80 |
+class VirtualWithDepend(results.VersionResult, results.Warning): |
81 |
+ """Virtual package with a BDEPEND defined.""" |
82 |
+ |
83 |
+ desc = 'virtual package with a DEPEND defined' |
84 |
+ |
85 |
+ |
86 |
+class VirtualProvidersCheck(Check): |
87 |
+ """Check providers of virtual packages.""" |
88 |
+ |
89 |
+ _restricted_source = (sources.RestrictionRepoSource, (restricts.CategoryDep('virtual'), )) |
90 |
+ _source = (sources.PackageRepoSource, (), (('source', _restricted_source),)) |
91 |
+ known_results = frozenset([VirtualWithSingleProvider, |
92 |
+ VirtualWithBdepend, VirtualWithDepend]) |
93 |
+ |
94 |
+ useless_depends = ( |
95 |
+ ('depend', VirtualWithDepend), |
96 |
+ ('bdepend', VirtualWithBdepend), |
97 |
+ ) |
98 |
+ |
99 |
+ def __init__(self, options, **kwargs): |
100 |
+ super().__init__(options, **kwargs) |
101 |
+ |
102 |
+ self.deprecated = self.options.target_repo.deprecated |
103 |
+ |
104 |
+ def pkg_has_conditional_exception(self, pkgs): |
105 |
+ return any(use.startswith(('elibc', 'kernel')) |
106 |
+ for pkg in pkgs |
107 |
+ for dep in iflatten_instance(pkg.rdepend, (atom_cls, packages.Conditional)) |
108 |
+ if isinstance(dep, packages.Conditional) and dep.attr == 'use' and isinstance(dep.restriction, values.ContainmentMatch) |
109 |
+ for use in dep.restriction.vals |
110 |
+ ) |
111 |
+ |
112 |
+ def feed(self, pkgs): |
113 |
+ for pkg in pkgs: |
114 |
+ for attr, cls in self.useless_depends: |
115 |
+ if getattr(pkg, attr): |
116 |
+ yield cls(pkg=pkg) |
117 |
+ |
118 |
+ if not any(self.deprecated.match(pkg) for pkg in pkgs): |
119 |
+ pkgs_rdepends = tuple( |
120 |
+ tuple(iflatten_instance(pkg.rdepend, atom_cls)) |
121 |
+ for pkg in pkgs |
122 |
+ ) |
123 |
+ if max(map(len, pkgs_rdepends)) == 1: |
124 |
+ unversioned_rdepends = { |
125 |
+ deps[0].unversioned_atom |
126 |
+ for deps in pkgs_rdepends |
127 |
+ if len(deps) == 1 |
128 |
+ } |
129 |
+ if len(unversioned_rdepends) == 1 and not self.pkg_has_conditional_exception(pkgs): |
130 |
+ yield VirtualWithSingleProvider(unversioned_rdepends.pop(), pkg=pkgs[0]) |
131 |
|
132 |
diff --git a/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithBdepend/expected.json b/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithBdepend/expected.json |
133 |
new file mode 100644 |
134 |
index 00000000..67f8c375 |
135 |
--- /dev/null |
136 |
+++ b/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithBdepend/expected.json |
137 |
@@ -0,0 +1,2 @@ |
138 |
+{"__class__": "VirtualWithBdepend", "category": "virtual", "package": "VirtualWithBdepend", "version": "0"} |
139 |
+{"__class__": "VirtualWithBdepend", "category": "virtual", "package": "VirtualWithBdepend", "version": "1"} |
140 |
|
141 |
diff --git a/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithDepend/expected.json b/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithDepend/expected.json |
142 |
new file mode 100644 |
143 |
index 00000000..05edb413 |
144 |
--- /dev/null |
145 |
+++ b/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithDepend/expected.json |
146 |
@@ -0,0 +1,2 @@ |
147 |
+{"__class__": "VirtualWithDepend", "category": "virtual", "package": "VirtualWithDepend", "version": "0"} |
148 |
+{"__class__": "VirtualWithDepend", "category": "virtual", "package": "VirtualWithDepend", "version": "1"} |
149 |
|
150 |
diff --git a/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithSingleProvider/expected.json b/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithSingleProvider/expected.json |
151 |
new file mode 100644 |
152 |
index 00000000..898cdb35 |
153 |
--- /dev/null |
154 |
+++ b/testdata/data/repos/standalone/VirtualProvidersCheck/VirtualWithSingleProvider/expected.json |
155 |
@@ -0,0 +1 @@ |
156 |
+{"__class__": "VirtualWithSingleProvider", "category": "virtual", "package": "VirtualWithSingleProvider4", "provider": "stub/slotted"} |
157 |
|
158 |
diff --git a/testdata/repos/standalone/profiles/desc/elibc.desc b/testdata/repos/standalone/profiles/desc/elibc.desc |
159 |
new file mode 100644 |
160 |
index 00000000..82a26e2b |
161 |
--- /dev/null |
162 |
+++ b/testdata/repos/standalone/profiles/desc/elibc.desc |
163 |
@@ -0,0 +1 @@ |
164 |
+glibc - ELIBC setting for systems that use the GNU C library |
165 |
|
166 |
diff --git a/testdata/repos/standalone/profiles/package.deprecated b/testdata/repos/standalone/profiles/package.deprecated |
167 |
new file mode 100644 |
168 |
index 00000000..f3b49d01 |
169 |
--- /dev/null |
170 |
+++ b/testdata/repos/standalone/profiles/package.deprecated |
171 |
@@ -0,0 +1 @@ |
172 |
+virtual/VirtualWithSingleProvider5 |
173 |
|
174 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithBdepend/VirtualWithBdepend-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithBdepend/VirtualWithBdepend-0.ebuild |
175 |
new file mode 100644 |
176 |
index 00000000..a34781c9 |
177 |
--- /dev/null |
178 |
+++ b/testdata/repos/standalone/virtual/VirtualWithBdepend/VirtualWithBdepend-0.ebuild |
179 |
@@ -0,0 +1,6 @@ |
180 |
+EAPI=7 |
181 |
+ |
182 |
+DESCRIPTION="Ebuild with unnecessary DEPEND" |
183 |
+SLOT="0" |
184 |
+ |
185 |
+BDEPEND="stub/stub1" |
186 |
|
187 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithBdepend/VirtualWithBdepend-1.ebuild b/testdata/repos/standalone/virtual/VirtualWithBdepend/VirtualWithBdepend-1.ebuild |
188 |
new file mode 100644 |
189 |
index 00000000..f9f7f891 |
190 |
--- /dev/null |
191 |
+++ b/testdata/repos/standalone/virtual/VirtualWithBdepend/VirtualWithBdepend-1.ebuild |
192 |
@@ -0,0 +1,11 @@ |
193 |
+EAPI=7 |
194 |
+ |
195 |
+DESCRIPTION="Ebuild with unnecessary DEPEND" |
196 |
+SLOT="0" |
197 |
+ |
198 |
+RDEPEND="|| ( |
199 |
+ stub/stub1 |
200 |
+ stub/stub2 |
201 |
+) |
202 |
+" |
203 |
+BDEPEND="${RDEPEND}" |
204 |
|
205 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithDepend/VirtualWithDepend-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithDepend/VirtualWithDepend-0.ebuild |
206 |
new file mode 100644 |
207 |
index 00000000..bc9f2162 |
208 |
--- /dev/null |
209 |
+++ b/testdata/repos/standalone/virtual/VirtualWithDepend/VirtualWithDepend-0.ebuild |
210 |
@@ -0,0 +1,6 @@ |
211 |
+EAPI=7 |
212 |
+ |
213 |
+DESCRIPTION="Ebuild with unnecessary DEPEND" |
214 |
+SLOT="0" |
215 |
+ |
216 |
+DEPEND="stub/stub1" |
217 |
|
218 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithDepend/VirtualWithDepend-1.ebuild b/testdata/repos/standalone/virtual/VirtualWithDepend/VirtualWithDepend-1.ebuild |
219 |
new file mode 100644 |
220 |
index 00000000..d29f3b42 |
221 |
--- /dev/null |
222 |
+++ b/testdata/repos/standalone/virtual/VirtualWithDepend/VirtualWithDepend-1.ebuild |
223 |
@@ -0,0 +1,11 @@ |
224 |
+EAPI=7 |
225 |
+ |
226 |
+DESCRIPTION="Ebuild with unnecessary DEPEND" |
227 |
+SLOT="0" |
228 |
+ |
229 |
+RDEPEND="|| ( |
230 |
+ stub/stub1 |
231 |
+ stub/stub2 |
232 |
+) |
233 |
+" |
234 |
+DEPEND="${RDEPEND}" |
235 |
|
236 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider1/VirtualWithSingleProvider1-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider1/VirtualWithSingleProvider1-0.ebuild |
237 |
new file mode 100644 |
238 |
index 00000000..7a9a8f34 |
239 |
--- /dev/null |
240 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider1/VirtualWithSingleProvider1-0.ebuild |
241 |
@@ -0,0 +1,10 @@ |
242 |
+EAPI=7 |
243 |
+ |
244 |
+DESCRIPTION="Good virtual with 2 providers" |
245 |
+SLOT="0" |
246 |
+ |
247 |
+RDEPEND="|| ( |
248 |
+ stub/stub1 |
249 |
+ stub/stub2 |
250 |
+) |
251 |
+" |
252 |
|
253 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider2/VirtualWithSingleProvider2-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider2/VirtualWithSingleProvider2-0.ebuild |
254 |
new file mode 100644 |
255 |
index 00000000..2891a52e |
256 |
--- /dev/null |
257 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider2/VirtualWithSingleProvider2-0.ebuild |
258 |
@@ -0,0 +1,10 @@ |
259 |
+EAPI=7 |
260 |
+ |
261 |
+DESCRIPTION="Good virtual with 1 provider but different use combinations" |
262 |
+SLOT="0" |
263 |
+ |
264 |
+RDEPEND="|| ( |
265 |
+ stub/stub1[matching] |
266 |
+ stub/stub1[probable] |
267 |
+) |
268 |
+" |
269 |
|
270 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider3/VirtualWithSingleProvider3-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider3/VirtualWithSingleProvider3-0.ebuild |
271 |
new file mode 100644 |
272 |
index 00000000..85b8d702 |
273 |
--- /dev/null |
274 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider3/VirtualWithSingleProvider3-0.ebuild |
275 |
@@ -0,0 +1,8 @@ |
276 |
+EAPI=7 |
277 |
+ |
278 |
+DESCRIPTION="Good virtual with 1 different provider across versions" |
279 |
+SLOT="0" |
280 |
+ |
281 |
+RDEPEND=" |
282 |
+ stub/stub1 |
283 |
+" |
284 |
|
285 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider3/VirtualWithSingleProvider3-1.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider3/VirtualWithSingleProvider3-1.ebuild |
286 |
new file mode 100644 |
287 |
index 00000000..5655b1ff |
288 |
--- /dev/null |
289 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider3/VirtualWithSingleProvider3-1.ebuild |
290 |
@@ -0,0 +1,8 @@ |
291 |
+EAPI=7 |
292 |
+ |
293 |
+DESCRIPTION="Good virtual with 1 different provider across versions" |
294 |
+SLOT="0" |
295 |
+ |
296 |
+RDEPEND=" |
297 |
+ stub/stub2 |
298 |
+" |
299 |
|
300 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider4/VirtualWithSingleProvider4-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider4/VirtualWithSingleProvider4-0.ebuild |
301 |
new file mode 100644 |
302 |
index 00000000..e3469bf8 |
303 |
--- /dev/null |
304 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider4/VirtualWithSingleProvider4-0.ebuild |
305 |
@@ -0,0 +1,8 @@ |
306 |
+EAPI=7 |
307 |
+ |
308 |
+DESCRIPTION="Redundant virtual with 1 provider" |
309 |
+SLOT="1" |
310 |
+ |
311 |
+RDEPEND=" |
312 |
+ stub/slotted:${SLOT} |
313 |
+" |
314 |
|
315 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider4/VirtualWithSingleProvider4-1.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider4/VirtualWithSingleProvider4-1.ebuild |
316 |
new file mode 100644 |
317 |
index 00000000..e3469bf8 |
318 |
--- /dev/null |
319 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider4/VirtualWithSingleProvider4-1.ebuild |
320 |
@@ -0,0 +1,8 @@ |
321 |
+EAPI=7 |
322 |
+ |
323 |
+DESCRIPTION="Redundant virtual with 1 provider" |
324 |
+SLOT="1" |
325 |
+ |
326 |
+RDEPEND=" |
327 |
+ stub/slotted:${SLOT} |
328 |
+" |
329 |
|
330 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider5/VirtualWithSingleProvider5-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider5/VirtualWithSingleProvider5-0.ebuild |
331 |
new file mode 100644 |
332 |
index 00000000..e7c2db6b |
333 |
--- /dev/null |
334 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider5/VirtualWithSingleProvider5-0.ebuild |
335 |
@@ -0,0 +1,8 @@ |
336 |
+EAPI=7 |
337 |
+ |
338 |
+DESCRIPTION="Good virtual with 2 providers" |
339 |
+SLOT="0" |
340 |
+ |
341 |
+RDEPEND=" |
342 |
+ stub/stub1 |
343 |
+" |
344 |
|
345 |
diff --git a/testdata/repos/standalone/virtual/VirtualWithSingleProvider6/VirtualWithSingleProvider6-0.ebuild b/testdata/repos/standalone/virtual/VirtualWithSingleProvider6/VirtualWithSingleProvider6-0.ebuild |
346 |
new file mode 100644 |
347 |
index 00000000..0f874ab4 |
348 |
--- /dev/null |
349 |
+++ b/testdata/repos/standalone/virtual/VirtualWithSingleProvider6/VirtualWithSingleProvider6-0.ebuild |
350 |
@@ -0,0 +1,9 @@ |
351 |
+EAPI=7 |
352 |
+ |
353 |
+DESCRIPTION="virtual with 1 provider, but behind special use flags" |
354 |
+SLOT="0" |
355 |
+IUSE="elibc_glibc" |
356 |
+ |
357 |
+RDEPEND=" |
358 |
+ !elibc_glibc? ( stub/stub1 ) |
359 |
+" |