'get_operator', 'isjustname', 'isspecific',
'isvalidatom', 'match_from_list', 'match_to_list',
'paren_enclose', 'paren_normalize', 'paren_reduce',
- 'remove_slot', 'strip_empty', 'use_reduce'
+ 'remove_slot', 'strip_empty', 'use_reduce',
+ '_repo_separator', '_slot_separator',
]
# DEPEND SYNTAX:
def __init__(self, forbid_overlap=False):
self.overlap = self._overlap(forbid=forbid_overlap)
- def __new__(cls, s, unevaluated_atom=None, allow_wildcard=False,
+ def __new__(cls, s, unevaluated_atom=None, allow_wildcard=False, allow_repo=False,
_use=None, eapi=None, is_valid_flag=None):
return _atom_base.__new__(cls, s)
- def __init__(self, s, unevaluated_atom=None, allow_wildcard=False,
+ def __init__(self, s, unevaluated_atom=None, allow_wildcard=False, allow_repo=False,
_use=None, eapi=None, is_valid_flag=None):
if isinstance(s, Atom):
# This is an efficiency assertion, to ensure that the Atom
if cpv.find("**") != -1:
raise InvalidAtom(self)
slot = gdict['slot']
+ repo = None
use_str = None
extended_syntax = True
else:
op = m.group(base + 1)
cpv = m.group(base + 2)
cp = m.group(base + 3)
- slot = m.group(_atom_re.groups - 1)
+ slot = m.group(_atom_re.groups - 2)
+ repo = m.group(_atom_re.groups - 1)
use_str = m.group(_atom_re.groups)
if m.group(base + 4) is not None:
raise InvalidAtom(self)
op = '=*'
cpv = m.group(base + 1)
cp = m.group(base + 2)
- slot = m.group(_atom_re.groups - 1)
+ slot = m.group(_atom_re.groups - 2)
+ repo = m.group(_atom_re.groups - 1)
use_str = m.group(_atom_re.groups)
if m.group(base + 3) is not None:
raise InvalidAtom(self)
elif m.group('simple') is not None:
op = None
cpv = cp = m.group(_atom_re.groupindex['simple'] + 1)
- slot = m.group(_atom_re.groups - 1)
+ slot = m.group(_atom_re.groups - 2)
+ repo = m.group(_atom_re.groups - 1)
use_str = m.group(_atom_re.groups)
if m.group(_atom_re.groupindex['simple'] + 2) is not None:
raise InvalidAtom(self)
+
else:
raise AssertionError(_("required group not found in atom: '%s'") % self)
self.__dict__['cp'] = cp
self.__dict__['cpv'] = cpv
+ self.__dict__['repo'] = repo
self.__dict__['slot'] = slot
self.__dict__['operator'] = op
self.__dict__['extended_syntax'] = extended_syntax
+ if not (repo is None or allow_repo):
+ raise InvalidAtom(self)
+
if use_str is not None:
if _use is not None:
use = _use
else:
use = _use_dep(use_str[1:-1].split(","))
- without_use = Atom(m.group('without_use'))
+ without_use = Atom(m.group('without_use'), allow_repo=allow_repo)
else:
use = None
without_use = self
atom += ":%s" % self.slot
use_dep = self.use.evaluate_conditionals(use)
atom += str(use_dep)
- return Atom(atom, unevaluated_atom=self, _use=use_dep)
+ return Atom(atom, unevaluated_atom=self, allow_repo=(self.repo is not None), _use=use_dep)
def violated_conditionals(self, other_use, is_valid_flag, parent_use=None):
"""
atom += ":%s" % self.slot
use_dep = self.use.violated_conditionals(other_use, is_valid_flag, parent_use)
atom += str(use_dep)
- return Atom(atom, unevaluated_atom=self, _use=use_dep)
+ return Atom(atom, unevaluated_atom=self, allow_repo=(self.repo is not None), _use=use_dep)
def _eval_qa_conditionals(self, use_mask, use_force):
if not (self.use and self.use.conditional):
atom += ":%s" % self.slot
use_dep = self.use._eval_qa_conditionals(use_mask, use_force)
atom += str(use_dep)
- return Atom(atom, unevaluated_atom=self, _use=use_dep)
+ return Atom(atom, unevaluated_atom=self, allow_repo=(self.repo is not None), _use=use_dep)
def __copy__(self):
"""Immutable, so returns self."""
slot = getattr(mydep, "slot", False)
if slot is not False:
return slot
- colon = mydep.find(":")
+
+ #remove repo_name if present
+ mydep = mydep.split(_repo_separator)[0]
+
+ colon = mydep.find(_slot_separator)
if colon != -1:
bracket = mydep.find("[", colon)
if bracket == -1:
return mydep[colon+1:bracket]
return None
+def dep_getrepo(mydep):
+ """
+ Retrieve the repo on a depend.
+
+ Example usage:
+ >>> dep_getrepo('app-misc/test::repository')
+ 'repository'
+
+ @param mydep: The depstring to retrieve the repository of
+ @type mydep: String
+ @rtype: String
+ @return: The repository name
+ """
+ repo = getattr(mydep, "repo", False)
+ if repo is not False:
+ return repo
+
+ metadata = getattr(mydep, "metadata", False)
+ if metadata:
+ repo = metadata.get('repository', False)
+ if repo is not False:
+ return repo
+
+ colon = mydep.find(_repo_separator)
+ if colon != -1:
+ bracket = mydep.find("[", colon)
+ if bracket == -1:
+ return mydep[colon+2:]
+ else:
+ return mydep[colon+2:bracket]
+ return None
def remove_slot(mydep):
"""
Removes dep components from the right side of an atom:
* slot
* use
* repo
+ And repo_name from the left side.
"""
- colon = mydep.find(":")
+ colon = mydep.find(_slot_separator)
if colon != -1:
mydep = mydep[:colon]
else:
# 2.1.3 A slot name may contain any of the characters [A-Za-z0-9+_.-].
# It must not begin with a hyphen or a dot.
+_slot_separator = ":"
_slot = r'([\w+][\w+.-]*)'
_slot_re = re.compile('^' + _slot + '$', re.VERBOSE)
_use = r'\[.*\]'
_op = r'([=~]|[><]=?)'
+_repo_separator = "::"
+_repo_name = r'[\w+][\w+.-]*'
+_repo = r'(?:' + _repo_separator + '(' + _repo_name + ')' + ')?'
_atom_re = re.compile('^(?P<without_use>(?:' +
'(?P<op>' + _op + _cpv + ')|' +
'(?P<star>=' + _cpv + r'\*)|' +
- '(?P<simple>' + _cp + '))(:' + _slot + ')?)(' + _use + ')?$', re.VERBOSE)
+ '(?P<simple>' + _cp + '))' +
+ '(' + _slot_separator + _slot + ')?' + _repo + ')(' + _use + ')?$', re.VERBOSE)
_extended_cat = r'[\w+*][\w+.*-]*'
_extended_pkg = r'[\w+*][\w+*-]*?'
_valid_use_re = re.compile(r'^[A-Za-z0-9][A-Za-z0-9+_@-]*$')
-def isvalidatom(atom, allow_blockers=False, allow_wildcard=False):
+def isvalidatom(atom, allow_blockers=False, allow_wildcard=False, allow_repo=False):
"""
Check to see if a depend atom is valid
"""
try:
if not isinstance(atom, Atom):
- atom = Atom(atom, allow_wildcard=allow_wildcard)
+ atom = Atom(atom, allow_wildcard=allow_wildcard, allow_repo=allow_repo)
if not allow_blockers and atom.blocker:
return False
return True
@return: The package category/package-name
"""
if not isinstance(mydep, Atom):
- mydep = Atom(mydep)
+ mydep = Atom(mydep, allow_wildcard=True, allow_repo=True)
return mydep.cp
else:
mydep = mydep[1:]
if not isinstance(mydep, Atom):
- mydep = Atom(mydep, allow_wildcard=True)
+ mydep = Atom(mydep, allow_wildcard=True, allow_repo=True)
mycpv = mydep.cpv
mycpv_cps = catpkgsplit(mycpv) # Can be None if not specific
if use_config_mismatch:
continue
+ mylist.append(x)
+ if mydep.repo:
+ candidate_list = mylist
+ mylist = []
+ for x in candidate_list:
+ repo = getattr(x, "repo", False)
+ if repo is False:
+ repo = dep_getrepo(x)
+ if repo is not None and repo != mydep.repo:
+ continue
mylist.append(x)
+
return mylist
def human_readable_required_use(required_use):
tests = (
( "=sys-apps/portage-2.1-r1:0[doc,a=,!b=,c?,!d?,-e]",
- ('=', 'sys-apps/portage', '2.1-r1', '0', '[doc,a=,!b=,c?,!d?,-e]'), False ),
+ ('=', 'sys-apps/portage', '2.1-r1', '0', '[doc,a=,!b=,c?,!d?,-e]', None), False, False ),
( "=sys-apps/portage-2.1-r1*:0[doc]",
- ('=*', 'sys-apps/portage', '2.1-r1', '0', '[doc]'), False ),
+ ('=*', 'sys-apps/portage', '2.1-r1', '0', '[doc]', None), False, False ),
( "sys-apps/portage:0[doc]",
- (None, 'sys-apps/portage', None, '0', '[doc]'), False ),
+ (None, 'sys-apps/portage', None, '0', '[doc]', None), False, False ),
( "sys-apps/portage:0[doc]",
- (None, 'sys-apps/portage', None, '0', '[doc]'), False ),
+ (None, 'sys-apps/portage', None, '0', '[doc]', None), False, False ),
( "*/*",
- (None, '*/*', None, None, None), True ),
+ (None, '*/*', None, None, None, None), True, False ),
( "sys-apps/*",
- (None, 'sys-apps/*', None, None, None), True ),
+ (None, 'sys-apps/*', None, None, None, None), True, False ),
( "*/portage",
- (None, '*/portage', None, None, None), True ),
+ (None, '*/portage', None, None, None, None), True, False ),
( "s*s-*/portage:1",
- (None, 's*s-*/portage', None, '1', None), True ),
+ (None, 's*s-*/portage', None, '1', None, None), True, False ),
( "*/po*ge:2",
- (None, '*/po*ge', None, '2', None), True ),
+ (None, '*/po*ge', None, '2', None, None), True, False ),
( "!dev-libs/A",
- (None, 'dev-libs/A', None, None, None), True ),
+ (None, 'dev-libs/A', None, None, None, None), True, True ),
( "!!dev-libs/A",
- (None, 'dev-libs/A', None, None, None), True ),
+ (None, 'dev-libs/A', None, None, None, None), True, True ),
( "!!dev-libs/A",
- (None, 'dev-libs/A', None, None, None), True ),
+ (None, 'dev-libs/A', None, None, None, None), True, True ),
( "dev-libs/A[foo(+)]",
- (None, 'dev-libs/A', None, None, "[foo(+)]"), True ),
+ (None, 'dev-libs/A', None, None, "[foo(+)]", None), True, True ),
( "dev-libs/A[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]",
- (None, 'dev-libs/A', None, None, "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]"), True ),
+ (None, 'dev-libs/A', None, None, "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", None), True, True ),
( "dev-libs/A:2[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]",
- (None, 'dev-libs/A', None, "2", "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]"), True ),
+ (None, 'dev-libs/A', None, "2", "[a(+),b(-)=,!c(+)=,d(-)?,!e(+)?,-f(-)]", None), True, True ),
+
+ ( "=sys-apps/portage-2.1-r1:0::repo_name[doc,a=,!b=,c?,!d?,-e]",
+ ('=', 'sys-apps/portage', '2.1-r1', '0', '[doc,a=,!b=,c?,!d?,-e]', 'repo_name'), False, True ),
+ ( "=sys-apps/portage-2.1-r1*:0::repo_name[doc]",
+ ('=*', 'sys-apps/portage', '2.1-r1', '0', '[doc]', 'repo_name'), False, True ),
+ ( "sys-apps/portage:0::repo_name[doc]",
+ (None, 'sys-apps/portage', None, '0', '[doc]', 'repo_name'), False, True ),
)
tests_xfail = (
- ( Atom("sys-apps/portage"), False ),
- ( "cat/pkg[a!]", False ),
- ( "cat/pkg[!a]", False ),
- ( "cat/pkg[!a!]", False ),
- ( "cat/pkg[!a-]", False ),
- ( "cat/pkg[-a=]", False ),
- ( "cat/pkg[-a?]", False ),
- ( "cat/pkg[-a!]", False ),
- ( "cat/pkg[=a]", False ),
- ( "cat/pkg[=a=]", False ),
- ( "cat/pkg[=a?]", False ),
- ( "cat/pkg[=a!]", False ),
- ( "cat/pkg[=a-]", False ),
- ( "cat/pkg[?a]", False ),
- ( "cat/pkg[?a=]", False ),
- ( "cat/pkg[?a?]", False ),
- ( "cat/pkg[?a!]", False ),
- ( "cat/pkg[?a-]", False ),
- ( "sys-apps/portage[doc]:0", False ),
- ( "*/*", False ),
- ( "sys-apps/*", False ),
- ( "*/portage", False ),
- ( "*/**", True ),
- ( "*/portage[use]", True ),
- ( "cat/pkg[a()]", False ),
- ( "cat/pkg[a(]", False ),
- ( "cat/pkg[a)]", False ),
- ( "cat/pkg[a(,b]", False ),
- ( "cat/pkg[a),b]", False ),
- ( "cat/pkg[a(*)]", False ),
- ( "cat/pkg[a(*)]", True ),
- ( "cat/pkg[a(+-)]", False ),
- ( "cat/pkg[a()]", False ),
- ( "cat/pkg[(+)a]", False ),
- ( "cat/pkg[a=(+)]", False ),
- ( "cat/pkg[!(+)a=]", False ),
- ( "cat/pkg[!a=(+)]", False ),
- ( "cat/pkg[a?(+)]", False ),
- ( "cat/pkg[!a?(+)]", False ),
- ( "cat/pkg[!(+)a?]", False ),
- ( "cat/pkg[-(+)a]", False ),
- ( "cat/pkg[a(+),-a]", False ),
- ( "cat/pkg[a(-),-a]", False ),
- ( "cat/pkg[-a,a(+)]", False ),
- ( "cat/pkg[-a,a(-)]", False ),
- ( "cat/pkg[-a(+),a(-)]", False ),
- ( "cat/pkg[-a(-),a(+)]", False ),
+ ( Atom("sys-apps/portage"), False, False ),
+ ( "cat/pkg[a!]", False, False ),
+ ( "cat/pkg[!a]", False, False ),
+ ( "cat/pkg[!a!]", False, False ),
+ ( "cat/pkg[!a-]", False, False ),
+ ( "cat/pkg[-a=]", False, False ),
+ ( "cat/pkg[-a?]", False, False ),
+ ( "cat/pkg[-a!]", False, False ),
+ ( "cat/pkg[=a]", False, False ),
+ ( "cat/pkg[=a=]", False, False ),
+ ( "cat/pkg[=a?]", False, False ),
+ ( "cat/pkg[=a!]", False, False ),
+ ( "cat/pkg[=a-]", False, False ),
+ ( "cat/pkg[?a]", False, False ),
+ ( "cat/pkg[?a=]", False, False ),
+ ( "cat/pkg[?a?]", False, False ),
+ ( "cat/pkg[?a!]", False, False ),
+ ( "cat/pkg[?a-]", False, False ),
+ ( "sys-apps/portage[doc]:0", False, False ),
+ ( "*/*", False, False ),
+ ( "sys-apps/*", False, False ),
+ ( "*/portage", False, False ),
+ ( "*/**", True, False ),
+ ( "*/portage[use]", True, False ),
+ ( "cat/pkg[a()]", False, False ),
+ ( "cat/pkg[a(]", False, False ),
+ ( "cat/pkg[a)]", False, False ),
+ ( "cat/pkg[a(,b]", False, False ),
+ ( "cat/pkg[a),b]", False, False ),
+ ( "cat/pkg[a(*)]", False, False ),
+ ( "cat/pkg[a(*)]", True, False ),
+ ( "cat/pkg[a(+-)]", False, False ),
+ ( "cat/pkg[a()]", False, False ),
+ ( "cat/pkg[(+)a]", False, False ),
+ ( "cat/pkg[a=(+)]", False, False ),
+ ( "cat/pkg[!(+)a=]", False, False ),
+ ( "cat/pkg[!a=(+)]", False, False ),
+ ( "cat/pkg[a?(+)]", False, False ),
+ ( "cat/pkg[!a?(+)]", False, False ),
+ ( "cat/pkg[!(+)a?]", False, False ),
+ ( "cat/pkg[-(+)a]", False, False ),
+ ( "cat/pkg[a(+),-a]", False, False ),
+ ( "cat/pkg[a(-),-a]", False, False ),
+ ( "cat/pkg[-a,a(+)]", False, False ),
+ ( "cat/pkg[-a,a(-)]", False, False ),
+ ( "cat/pkg[-a(+),a(-)]", False, False ),
+ ( "cat/pkg[-a(-),a(+)]", False, False ),
+ ( "sys-apps/portage[doc]::repo_name", False, False ),
+ ( "sys-apps/portage:0[doc]::repo_name", False, False ),
+ ( "sys-apps/portage[doc]:0::repo_name", False, False ),
+ ( "=sys-apps/portage-2.1-r1:0::repo_name[doc,a=,!b=,c?,!d?,-e]", False, False ),
+ ( "=sys-apps/portage-2.1-r1*:0::repo_name[doc]", False, False ),
+ ( "sys-apps/portage:0::repo_name[doc]", False, False ),
)
- for atom, parts, allow_wildcard in tests:
- a = Atom(atom, allow_wildcard=allow_wildcard)
- op, cp, ver, slot, use = parts
+ for atom, parts, allow_wildcard, allow_repo in tests:
+ a = Atom(atom, allow_wildcard=allow_wildcard, allow_repo=allow_repo)
+ op, cp, ver, slot, use, repo = parts
self.assertEqual( op, a.operator,
msg="Atom('%s').operator = %s == '%s'" % ( atom, a.operator, op ) )
self.assertEqual( cp, a.cp,
msg="Atom('%s').cpv = %s == '%s'" % ( atom, a.cpv, cpv ) )
self.assertEqual( slot, a.slot,
msg="Atom('%s').slot = %s == '%s'" % ( atom, a.slot, slot ) )
+ self.assertEqual( repo, a.repo,
+ msg="Atom('%s').repo == %s == '%s'" % ( atom, a.repo, repo ) )
+
if a.use:
returned_use = str(a.use)
else:
self.assertEqual( use, returned_use,
msg="Atom('%s').use = %s == '%s'" % ( atom, returned_use, use ) )
- for atom, allow_wildcard in tests_xfail:
- self.assertRaisesMsg(atom, (InvalidAtom, TypeError), Atom, atom, allow_wildcard=allow_wildcard)
+ for atom, allow_wildcard, allow_repo in tests_xfail:
+ self.assertRaisesMsg(atom, (InvalidAtom, TypeError), Atom, atom, \
+ allow_wildcard=allow_wildcard, allow_repo=allow_repo)
def test_intersects(self):
test_cases = (