commit:     d87ed03875c709b451a9e512d74f9b3d9c689271
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Thu Aug  7 07:42:07 2014 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Thu Dec  4 14:00:25 2014 +0000
URL:        
http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=d87ed038

repoman: Add check for missing slot values/slot operators

The idea if that a particular dependency atom matches more than one slot
of a package, you are supposed to either use := or :* operator
(or a specific :slot dependency), whichever is appropriate.

This will help catching mistakes (when packages become slotted) and make
cross-slot behavior clear (it is undefined with no slot operator). I
will estimate the amount of new warnings later.

---
 bin/repoman                      |  6 ++++++
 pym/repoman/check_missingslot.py | 31 +++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/bin/repoman b/bin/repoman
index ddd2e92..5380146 100755
--- a/bin/repoman
+++ b/bin/repoman
@@ -58,6 +58,7 @@ from portage import _encodings
 from portage import _unicode_encode
 import repoman.checks
 from repoman.checks import run_checks
+from repoman.check_missingslot import check_missingslot
 from repoman import utilities
 from repoman.herdbase import make_herd_base
 from _emerge.Package import Package
@@ -299,6 +300,7 @@ qahelp = {
        "dependency.badindev": "User-visible ebuilds with unsatisfied 
dependencies (matched against *visible* ebuilds) in developing arch",
        "dependency.badmaskedindev": "Masked ebuilds with unsatisfied 
dependencies (matched against *all* ebuilds) in developing arch",
        "dependency.badtilde": "Uses the ~ dep operator with a non-zero 
revision part, which is useless (the revision is ignored)",
+       "dependency.missingslot": "RDEPEND matches more than one SLOT but does 
not specify a slot and/or use the := or :* slot operator",
        "dependency.perlcore": "This ebuild directly depends on a package in 
perl-core; it should use the corresponding virtual instead.",
        "dependency.syntax": "Syntax error in dependency string (usually an 
extra/missing space/parenthesis)",
        "dependency.unknown": "Ebuild has a dependency that refers to an 
unknown package (which may be valid if it is a blocker for a renamed/removed 
package, or is an alternative choice provided by an overlay)",
@@ -386,6 +388,7 @@ qawarnings = set((
 "dependency.badindev",
 "dependency.badmaskedindev",
 "dependency.badtilde",
+"dependency.missingslot",
 "dependency.perlcore",
 "DESCRIPTION.toolong",
 "EAPI.deprecated",
@@ -2090,6 +2093,9 @@ for x in effective_scanlist:
                                                         " with a non-zero 
revision:" + \
                                                         " '%s'") % (mytype, 
atom))
 
+                                       check_missingslot(atom, mytype, eapi, 
portdb, stats, fails,
+                                               relative_path, myaux)
+
                        type_list.extend([mytype] * (len(badsyntax) - 
len(type_list)))
 
                for m, b in zip(type_list, badsyntax):

diff --git a/pym/repoman/check_missingslot.py b/pym/repoman/check_missingslot.py
new file mode 100644
index 0000000..fa436a7
--- /dev/null
+++ b/pym/repoman/check_missingslot.py
@@ -0,0 +1,31 @@
+# repoman: missing slot check
+# Copyright 2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+"""This module contains the check used to find missing slot values
+in dependencies."""
+
+from portage.eapi import eapi_has_slot_operator
+
+def check_missingslot(atom, mytype, eapi, portdb, stats, fails, relative_path, 
my_aux):
+       # If no slot or slot operator is specified in RDEP...
+       if (not atom.blocker and not atom.slot and not atom.slot_operator
+                       and mytype == 'RDEPEND' and 
eapi_has_slot_operator(eapi)):
+               # Check whether it doesn't match more than one.
+               atom_matches = portdb.xmatch("match-all", atom)
+               dep_slots = frozenset(
+                               portdb.aux_get(cpv, ['SLOT'])[0].split('/')[0]
+                                       for cpv in atom_matches)
+
+               if len(dep_slots) > 1:
+                       # See if it is a DEPEND as well. It's a very simple & 
dumb
+                       # check but should suffice for catching it.
+                       depend = my_aux['DEPEND'].split()
+                       if atom not in depend:
+                               return
+
+                       stats["dependency.missingslot"] += 1
+                       fails["dependency.missingslot"].append(
+                               relative_path +
+                               ": %s: '%s' matches more than one slot, please 
specify an explicit slot and/or use the := or :* slot operator" %
+                               (mytype, atom))

Reply via email to