Gentoo Archives: gentoo-commits

From: Brian Dolbec <dolsen@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:repoman commit in: pym/repoman/, pym/repoman/modules/scan/depend/
Date: Mon, 07 Mar 2016 21:53:31
Message-Id: 1457385678.4b25757dc8ebc42e276b07aa190a21682963a35a.dolsen@gentoo
1 commit: 4b25757dc8ebc42e276b07aa190a21682963a35a
2 Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
3 AuthorDate: Mon Jan 4 07:57:36 2016 +0000
4 Commit: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
5 CommitDate: Mon Mar 7 21:21:18 2016 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=4b25757d
7
8 repoman: Move the large depency checks loop to a new plugin ProfileDependsChecks class
9
10 pym/repoman/modules/scan/depend/__init__.py | 9 ++
11 pym/repoman/modules/scan/depend/profile.py | 207 ++++++++++++++++++++++++++++
12 pym/repoman/repos.py | 1 +
13 pym/repoman/scanner.py | 181 +-----------------------
14 4 files changed, 224 insertions(+), 174 deletions(-)
15
16 diff --git a/pym/repoman/modules/scan/depend/__init__.py b/pym/repoman/modules/scan/depend/__init__.py
17 index ebc716c..cddb7f1 100644
18 --- a/pym/repoman/modules/scan/depend/__init__.py
19 +++ b/pym/repoman/modules/scan/depend/__init__.py
20 @@ -19,6 +19,15 @@ module_spec = {
21 'func_desc': {
22 },
23 },
24 + 'profile-module': {
25 + 'name': "profile",
26 + 'sourcefile': "profile",
27 + 'class': "ProfileDependsChecks",
28 + 'description': doc,
29 + 'functions': ['check'],
30 + 'func_desc': {
31 + },
32 + },
33 }
34 }
35
36
37 diff --git a/pym/repoman/modules/scan/depend/profile.py b/pym/repoman/modules/scan/depend/profile.py
38 new file mode 100644
39 index 0000000..db63b1c
40 --- /dev/null
41 +++ b/pym/repoman/modules/scan/depend/profile.py
42 @@ -0,0 +1,207 @@
43 +# -*- coding:utf-8 -*-
44 +
45 +
46 +import copy
47 +from pprint import pformat
48 +
49 +from _emerge.Package import Package
50 +
51 +# import our initialized portage instance
52 +from repoman._portage import portage
53 +from portage.dep import Atom
54 +
55 +
56 +def sort_key(item):
57 + return item[2].sub_path
58 +
59 +
60 +class ProfileDependsChecks(object):
61 +
62 + def __init__(self, **kwargs):
63 + self.qatracker = kwargs.get('qatracker')
64 + self.portdb = kwargs.get('portdb')
65 + self.profiles = kwargs.get('profiles')
66 + self.options = kwargs.get('options')
67 + self.repo_settings = kwargs.get('repo_settings')
68 + self.include_arches = kwargs.get('include_arches')
69 + self.caches = kwargs.get('caches')
70 + self.repoman_incrementals = kwargs.get('repoman_incrementals')
71 + self.env = kwargs.get('env')
72 + self.have = kwargs.get('have')
73 + self.dev_keywords = kwargs.get('dev_keywords')
74 +
75 + def check(self, **kwargs):
76 + arches = kwargs.get('arches')
77 + ebuild = kwargs.get('ebuild')
78 + pkg = kwargs.get('pkg')
79 + baddepsyntax = kwargs.get('baddepsyntax')
80 + unknown_pkgs = kwargs.get('unknown_pkgs')
81 +
82 + relevant_profiles = []
83 + for keyword, arch, groups in arches:
84 + if arch not in self.profiles:
85 + # A missing profile will create an error further down
86 + # during the KEYWORDS verification.
87 + continue
88 +
89 + if self.include_arches is not None:
90 + if arch not in self.include_arches:
91 + continue
92 +
93 + relevant_profiles.extend(
94 + (keyword, groups, prof) for prof in self.profiles[arch])
95 +
96 + relevant_profiles.sort(key=sort_key)
97 +
98 + for keyword, groups, prof in relevant_profiles:
99 +
100 + is_stable_profile = prof.status == "stable"
101 + is_dev_profile = prof.status == "dev" and \
102 + self.options.include_dev
103 + is_exp_profile = prof.status == "exp" and \
104 + self.options.include_exp_profiles == 'y'
105 + if not (is_stable_profile or is_dev_profile or is_exp_profile):
106 + continue
107 +
108 + dep_settings = self.caches['arch'].get(prof.sub_path)
109 + if dep_settings is None:
110 + dep_settings = portage.config(
111 + config_profile_path=prof.abs_path,
112 + config_incrementals=self.repoman_incrementals,
113 + config_root=self.repo_settings.config_root,
114 + local_config=False,
115 + _unmatched_removal=self.options.unmatched_removal,
116 + env=self.env, repositories=self.repo_settings.repoman_settings.repositories)
117 + dep_settings.categories = self.repo_settings.repoman_settings.categories
118 + if self.options.without_mask:
119 + dep_settings._mask_manager_obj = \
120 + copy.deepcopy(dep_settings._mask_manager)
121 + dep_settings._mask_manager._pmaskdict.clear()
122 + self.caches['arch'][prof.sub_path] = dep_settings
123 +
124 + xmatch_cache_key = (prof.sub_path, tuple(groups))
125 + xcache = self.caches['arch_xmatch'].get(xmatch_cache_key)
126 + if xcache is None:
127 + self.portdb.melt()
128 + self.portdb.freeze()
129 + xcache = self.portdb.xcache
130 + xcache.update(self.caches['shared_xmatch'])
131 + self.caches['arch_xmatch'][xmatch_cache_key] = xcache
132 +
133 + self.repo_settings.trees[self.repo_settings.root]["porttree"].settings = dep_settings
134 + self.portdb.settings = dep_settings
135 + self.portdb.xcache = xcache
136 +
137 + dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups)
138 + # just in case, prevent config.reset() from nuking these.
139 + dep_settings.backup_changes("ACCEPT_KEYWORDS")
140 +
141 + # This attribute is used in dbapi._match_use() to apply
142 + # use.stable.{mask,force} settings based on the stable
143 + # status of the parent package. This is required in order
144 + # for USE deps of unstable packages to be resolved correctly,
145 + # since otherwise use.stable.{mask,force} settings of
146 + # dependencies may conflict (see bug #456342).
147 + dep_settings._parent_stable = dep_settings._isStable(pkg)
148 +
149 + # Handle package.use*.{force,mask) calculation, for use
150 + # in dep_check.
151 + dep_settings.useforce = dep_settings._use_manager.getUseForce(
152 + pkg, stable=dep_settings._parent_stable)
153 + dep_settings.usemask = dep_settings._use_manager.getUseMask(
154 + pkg, stable=dep_settings._parent_stable)
155 +
156 + if not baddepsyntax:
157 + ismasked = not ebuild.archs or \
158 + pkg.cpv not in self.portdb.xmatch("match-visible",
159 + Atom("%s::%s" % (pkg.cp, self.repo_settings.repo_config.name)))
160 + if ismasked:
161 + if not self.have['pmasked']:
162 + self.have['pmasked'] = bool(dep_settings._getMaskAtom(
163 + pkg.cpv, ebuild.metadata))
164 + if self.options.ignore_masked:
165 + continue
166 + # we are testing deps for a masked package; give it some lee-way
167 + suffix = "masked"
168 + matchmode = "minimum-all-ignore-profile"
169 + else:
170 + suffix = ""
171 + matchmode = "minimum-visible"
172 +
173 + if not self.have['dev_keywords']:
174 + self.have['dev_keywords'] = \
175 + bool(self.dev_keywords.intersection(ebuild.keywords))
176 +
177 + if prof.status == "dev":
178 + suffix = suffix + "indev"
179 +
180 + for mytype in Package._dep_keys:
181 +
182 + mykey = "dependency.bad" + suffix
183 + myvalue = ebuild.metadata[mytype]
184 + if not myvalue:
185 + continue
186 +
187 + success, atoms = portage.dep_check(
188 + myvalue, self.portdb, dep_settings,
189 + use="all", mode=matchmode, trees=self.repo_settings.trees)
190 +
191 + if success:
192 + if atoms:
193 +
194 + # Don't bother with dependency.unknown for
195 + # cases in which *DEPEND.bad is triggered.
196 + for atom in atoms:
197 + # dep_check returns all blockers and they
198 + # aren't counted for *DEPEND.bad, so we
199 + # ignore them here.
200 + if not atom.blocker:
201 + unknown_pkgs.discard(
202 + (mytype, atom.unevaluated_atom))
203 +
204 + if not prof.sub_path:
205 + # old-style virtuals currently aren't
206 + # resolvable with empty profile, since
207 + # 'virtuals' mappings are unavailable
208 + # (it would be expensive to search
209 + # for PROVIDE in all ebuilds)
210 + atoms = [
211 + atom for atom in atoms if not (
212 + atom.cp.startswith('virtual/')
213 + and not self.portdb.cp_list(atom.cp))]
214 +
215 + # we have some unsolvable deps
216 + # remove ! deps, which always show up as unsatisfiable
217 + atoms = [
218 + str(atom.unevaluated_atom)
219 + for atom in atoms if not atom.blocker]
220 +
221 + # if we emptied out our list, continue:
222 + if not atoms:
223 + continue
224 + if self.options.output_style in ['column']:
225 + self.qatracker.add_error(mykey,
226 + "%s: %s: %s(%s) %s"
227 + % (ebuild.relative_path, mytype, keyword,
228 + prof, repr(atoms)))
229 + else:
230 + self.qatracker.add_error(mykey,
231 + "%s: %s: %s(%s)\n%s"
232 + % (ebuild.relative_path, mytype, keyword,
233 + prof, pformat(atoms, indent=6)))
234 + else:
235 + if self.options.output_style in ['column']:
236 + self.qatracker.add_error(mykey,
237 + "%s: %s: %s(%s) %s"
238 + % (ebuild.relative_path, mytype, keyword,
239 + prof, repr(atoms)))
240 + else:
241 + self.qatracker.add_error(mykey,
242 + "%s: %s: %s(%s)\n%s"
243 + % (ebuild.relative_path, mytype, keyword,
244 + prof, pformat(atoms, indent=6)))
245 + return {'continue': False}
246 +
247 + @property
248 + def runInEbuilds(self):
249 + return (True, [self.check])
250
251 diff --git a/pym/repoman/repos.py b/pym/repoman/repos.py
252 index a34f785..39f53c1 100644
253 --- a/pym/repoman/repos.py
254 +++ b/pym/repoman/repos.py
255 @@ -28,6 +28,7 @@ class RepoSettings(object):
256 self, config_root, portdir, portdir_overlay,
257 repoman_settings=None, vcs_settings=None, options=None,
258 qawarnings=None):
259 + self.config_root = config_root
260 self.repoman_settings = repoman_settings
261 self.vcs_settings = vcs_settings
262
263
264 diff --git a/pym/repoman/scanner.py b/pym/repoman/scanner.py
265 index 2625de4..b82cefb 100644
266 --- a/pym/repoman/scanner.py
267 +++ b/pym/repoman/scanner.py
268 @@ -2,17 +2,12 @@
269
270 from __future__ import print_function, unicode_literals
271
272 -import copy
273 import logging
274 from itertools import chain
275 -from pprint import pformat
276 -
277 -from _emerge.Package import Package
278
279 import portage
280 from portage import normalize_path
281 from portage import os
282 -from portage.dep import Atom
283 from portage.output import green
284 from repoman.modules.commit import repochecks
285 from repoman.profile import check_profiles, dev_profile_keywords, setup_profile
286 @@ -33,10 +28,6 @@ MODULE_CONTROLLER = Modules(path=MODULES_PATH, namepath="repoman.modules.scan")
287 MODULE_NAMES = MODULE_CONTROLLER.module_names[:]
288
289
290 -def sort_key(item):
291 - return item[2].sub_path
292 -
293 -
294 class Scanner(object):
295 '''Primary scan class. Operates all the small Q/A tests and checks'''
296
297 @@ -197,6 +188,12 @@ class Scanner(object):
298 "checks": self.checks,
299 "repo_metadata": self.repo_metadata,
300 "profiles": self.profiles,
301 + "include_arches": self.include_arches,
302 + "caches": self.caches,
303 + "repoman_incrementals": self.repoman_incrementals,
304 + "env": self.env,
305 + "have": self.have,
306 + "dev_keywords": self.dev_keywords,
307 }
308 # initialize the plugin checks here
309 self.modules = {}
310 @@ -292,7 +289,7 @@ class Scanner(object):
311 ('license', 'LicenseChecks'), ('restrict', 'RestrictChecks'),
312 ('mtime', 'MtimeChecks'), ('multicheck', 'MultiCheck'),
313 # Options.is_forced() is used to bypass further checks
314 - ('options', 'Options'),
315 + ('options', 'Options'), ('profile', 'ProfileDependsChecks'),
316 ]:
317 if mod[0]:
318 mod_class = MODULE_CONTROLLER.get_class(mod[0])
319 @@ -320,170 +317,6 @@ class Scanner(object):
320 if y_ebuild_continue:
321 continue
322
323 - relevant_profiles = []
324 - for keyword, arch, groups in dynamic_data['arches']:
325 - if arch not in self.profiles:
326 - # A missing profile will create an error further down
327 - # during the KEYWORDS verification.
328 - continue
329 -
330 - if self.include_arches is not None:
331 - if arch not in self.include_arches:
332 - continue
333 -
334 - relevant_profiles.extend(
335 - (keyword, groups, prof) for prof in self.profiles[arch])
336 -
337 - relevant_profiles.sort(key=sort_key)
338 -
339 - for keyword, groups, prof in relevant_profiles:
340 -
341 - is_stable_profile = prof.status == "stable"
342 - is_dev_profile = prof.status == "dev" and \
343 - self.options.include_dev
344 - is_exp_profile = prof.status == "exp" and \
345 - self.options.include_exp_profiles == 'y'
346 - if not (is_stable_profile or is_dev_profile or is_exp_profile):
347 - continue
348 -
349 - dep_settings = self.caches['arch'].get(prof.sub_path)
350 - if dep_settings is None:
351 - dep_settings = portage.config(
352 - config_profile_path=prof.abs_path,
353 - config_incrementals=self.repoman_incrementals,
354 - config_root=self.config_root,
355 - local_config=False,
356 - _unmatched_removal=self.options.unmatched_removal,
357 - env=self.env, repositories=self.repo_settings.repoman_settings.repositories)
358 - dep_settings.categories = self.repo_settings.repoman_settings.categories
359 - if self.options.without_mask:
360 - dep_settings._mask_manager_obj = \
361 - copy.deepcopy(dep_settings._mask_manager)
362 - dep_settings._mask_manager._pmaskdict.clear()
363 - self.caches['arch'][prof.sub_path] = dep_settings
364 -
365 - xmatch_cache_key = (prof.sub_path, tuple(groups))
366 - xcache = self.caches['arch_xmatch'].get(xmatch_cache_key)
367 - if xcache is None:
368 - self.portdb.melt()
369 - self.portdb.freeze()
370 - xcache = self.portdb.xcache
371 - xcache.update(self.caches['shared_xmatch'])
372 - self.caches['arch_xmatch'][xmatch_cache_key] = xcache
373 -
374 - self.repo_settings.trees[self.repo_settings.root]["porttree"].settings = dep_settings
375 - self.portdb.settings = dep_settings
376 - self.portdb.xcache = xcache
377 -
378 - dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups)
379 - # just in case, prevent config.reset() from nuking these.
380 - dep_settings.backup_changes("ACCEPT_KEYWORDS")
381 -
382 - # This attribute is used in dbapi._match_use() to apply
383 - # use.stable.{mask,force} settings based on the stable
384 - # status of the parent package. This is required in order
385 - # for USE deps of unstable packages to be resolved correctly,
386 - # since otherwise use.stable.{mask,force} settings of
387 - # dependencies may conflict (see bug #456342).
388 - dep_settings._parent_stable = dep_settings._isStable(dynamic_data['pkg'])
389 -
390 - # Handle package.use*.{force,mask) calculation, for use
391 - # in dep_check.
392 - dep_settings.useforce = dep_settings._use_manager.getUseForce(
393 - dynamic_data['pkg'], stable=dep_settings._parent_stable)
394 - dep_settings.usemask = dep_settings._use_manager.getUseMask(
395 - dynamic_data['pkg'], stable=dep_settings._parent_stable)
396 -
397 - if not dynamic_data['baddepsyntax']:
398 - ismasked = not dynamic_data['ebuild'].archs or \
399 - dynamic_data['pkg'].cpv not in self.portdb.xmatch("match-visible",
400 - Atom("%s::%s" % (dynamic_data['pkg'].cp, self.repo_settings.repo_config.name)))
401 - if ismasked:
402 - if not self.have['pmasked']:
403 - self.have['pmasked'] = bool(dep_settings._getMaskAtom(
404 - dynamic_data['pkg'].cpv, dynamic_data['pkg']._metadata))
405 - if self.options.ignore_masked:
406 - continue
407 - # we are testing deps for a masked package; give it some lee-way
408 - suffix = "masked"
409 - matchmode = "minimum-all-ignore-profile"
410 - else:
411 - suffix = ""
412 - matchmode = "minimum-visible"
413 -
414 - if not self.have['dev_keywords']:
415 - self.have['dev_keywords'] = \
416 - bool(self.dev_keywords.intersection(dynamic_data['ebuild'].keywords))
417 -
418 - if prof.status == "dev":
419 - suffix = suffix + "indev"
420 -
421 - for mytype in Package._dep_keys:
422 -
423 - mykey = "dependency.bad" + suffix
424 - myvalue = dynamic_data['ebuild'].metadata[mytype]
425 - if not myvalue:
426 - continue
427 -
428 - success, atoms = portage.dep_check(
429 - myvalue, self.portdb, dep_settings,
430 - use="all", mode=matchmode, trees=self.repo_settings.trees)
431 -
432 - if success:
433 - if atoms:
434 -
435 - # Don't bother with dependency.unknown for
436 - # cases in which *DEPEND.bad is triggered.
437 - for atom in atoms:
438 - # dep_check returns all blockers and they
439 - # aren't counted for *DEPEND.bad, so we
440 - # ignore them here.
441 - if not atom.blocker:
442 - dynamic_data['unknown_pkgs'].discard(
443 - (mytype, atom.unevaluated_atom))
444 -
445 - if not prof.sub_path:
446 - # old-style virtuals currently aren't
447 - # resolvable with empty profile, since
448 - # 'virtuals' mappings are unavailable
449 - # (it would be expensive to search
450 - # for PROVIDE in all ebuilds)
451 - atoms = [
452 - atom for atom in atoms if not (
453 - atom.cp.startswith('virtual/')
454 - and not self.portdb.cp_list(atom.cp))]
455 -
456 - # we have some unsolvable deps
457 - # remove ! deps, which always show up as unsatisfiable
458 - atoms = [
459 - str(atom.unevaluated_atom)
460 - for atom in atoms if not atom.blocker]
461 -
462 - # if we emptied out our list, continue:
463 - if not atoms:
464 - continue
465 - if self.options.output_style in ['column']:
466 - self.qatracker.add_error(mykey,
467 - "%s: %s: %s(%s) %s"
468 - % (dynamic_data['ebuild'].relative_path, mytype, keyword,
469 - prof, repr(atoms)))
470 - else:
471 - self.qatracker.add_error(mykey,
472 - "%s: %s: %s(%s)\n%s"
473 - % (dynamic_data['ebuild'].relative_path, mytype, keyword,
474 - prof, pformat(atoms, indent=6)))
475 - else:
476 - if self.options.output_style in ['column']:
477 - self.qatracker.add_error(mykey,
478 - "%s: %s: %s(%s) %s"
479 - % (dynamic_data['ebuild'].relative_path, mytype, keyword,
480 - prof, repr(atoms)))
481 - else:
482 - self.qatracker.add_error(mykey,
483 - "%s: %s: %s(%s)\n%s"
484 - % (dynamic_data['ebuild'].relative_path, mytype, keyword,
485 - prof, pformat(atoms, indent=6)))
486 -
487 if not dynamic_data['baddepsyntax'] and dynamic_data['unknown_pkgs']:
488 type_map = {}
489 for mytype, atom in dynamic_data['unknown_pkgs']: