def testParenReduce(self): test_cases = ( ("A", ["A"]), ("( A )", ["A"]), ("|| ( A B )", ["||", ["A", "B"]]), ("|| ( A || ( B C ) )", ["||", ["A", "||", ["B", "C"]]]), ("|| ( A || ( B C D ) )", ["||", ["A", "||", ["B", "C", "D"]]]), ("|| ( A || ( B || ( C D ) E ) )", ["||", ["A", "||", ["B", "||", ["C", "D"], "E"]]]), ("a? ( A )", ["a?", ["A"]]), ("( || ( ( ( A ) B ) ) )", ["A", "B"]), ("( || ( || ( ( A ) B ) ) )", ["||", ["A", "B"]]), ("|| ( A )", ["A"]), ("( || ( || ( || ( A ) foo? ( B ) ) ) )", ["||", ["A", "foo?", ["B"]]]), ("( || ( || ( bar? ( A ) || ( foo? ( B ) ) ) ) )", ["||", ["bar?", ["A"], "foo?", ["B"]]]), ("A || ( ) foo? ( ) B", ["A", "B"]), ("|| ( A ) || ( B )", ["A", "B"]), ("foo? ( A ) foo? ( B )", ["foo?", ["A"], "foo?", ["B"]]), ("|| ( ( A B ) C )", ["||", [["A", "B"], "C"]]), ("|| ( ( A B ) ( C ) )", ["||", [["A", "B"], "C"]]), # test USE dep defaults for bug #354003 (">=dev-lang/php-5.2[pcre(+)]", [">=dev-lang/php-5.2[pcre(+)]"]), ) test_cases_xfail = ( "( A", "A )", "||( A B )", "|| (A B )", "|| ( A B)", "|| ( A B", "|| A B )", "|| A B", "|| ( A B ) )", "|| || B C", "|| ( A B || )", "a? A", "( || ( || || ( A ) foo? ( B ) ) )", "( || ( || bar? ( A ) foo? ( B ) ) )", ) for dep_str, expected_result in test_cases: self.assertEqual(paren_reduce(dep_str, _deprecation_warn=False), expected_result, "input: '%s' result: %s != %s" % (dep_str, paren_reduce(dep_str, _deprecation_warn=False), expected_result)) for dep_str in test_cases_xfail: self.assertRaisesMsg(dep_str, InvalidDependString, paren_reduce, dep_str, _deprecation_warn=False)
def testParenReduce(self): test_cases = ( ("A", ["A"]), ("( A )", ["A"]), ("|| ( A B )", ["||", ["A", "B"]]), ("|| ( A || ( B C ) )", ["||", ["A", "||", ["B", "C"]]]), ("|| ( A || ( B C D ) )", ["||", ["A", "||", ["B", "C", "D"]]]), ("|| ( A || ( B || ( C D ) E ) )", ["||", ["A", "||", ["B", "||", ["C", "D"], "E"]]]), ("a? ( A )", ["a?", ["A"]]), ("( || ( ( ( A ) B ) ) )", ["A", "B"]), ("( || ( || ( ( A ) B ) ) )", ["||", ["A", "B"]]), ("|| ( A )", ["A"]), ("( || ( || ( || ( A ) foo? ( B ) ) ) )", ["||", ["A", "foo?", ["B"]]]), ("( || ( || ( bar? ( A ) || ( foo? ( B ) ) ) ) )", ["||", ["bar?", ["A"], "foo?", ["B"]]]), ("A || ( ) foo? ( ) B", ["A", "B"]), ("|| ( A ) || ( B )", ["A", "B"]), ("foo? ( A ) foo? ( B )", ["foo?", ["A"], "foo?", ["B"]]), ("|| ( ( A B ) C )", ["||", [["A", "B"], "C"]]), ("|| ( ( A B ) ( C ) )", ["||", [["A", "B"], "C"]]), # test USE dep defaults for bug #354003 (">=dev-lang/php-5.2[pcre(+)]", [">=dev-lang/php-5.2[pcre(+)]"]), ) test_cases_xfail = ( "( A", "A )", "||( A B )", "|| (A B )", "|| ( A B)", "|| ( A B", "|| A B )", "|| A B", "|| ( A B ) )", "|| || B C", "|| ( A B || )", "a? A", "( || ( || || ( A ) foo? ( B ) ) )", "( || ( || bar? ( A ) foo? ( B ) ) )", ) for dep_str, expected_result in test_cases: self.assertEqual( paren_reduce(dep_str, _deprecation_warn=False), expected_result, "input: '%s' result: %s != %s" % (dep_str, paren_reduce( dep_str, _deprecation_warn=False), expected_result)) for dep_str in test_cases_xfail: self.assertRaisesMsg(dep_str, InvalidDependString, paren_reduce, dep_str, _deprecation_warn=False)
def testParenReduce(self): test_cases = ( ( "A", ["A"]), ( "( A )", ["A"]), ( "|| ( A B )", [ "||", ["A", "B"] ]), ( "|| ( A || ( B C ) )", [ "||", ["A", "||", ["B", "C"]]]), ( "|| ( A || ( B C D ) )", [ "||", ["A", "||", ["B", "C", "D"]] ]), ( "|| ( A || ( B || ( C D ) E ) )", [ "||", ["A", "||", ["B", "||", ["C", "D"], "E"]] ]), ( "a? ( A )", ["a?", ["A"]]), ( "( || ( ( ( A ) B ) ) )", ["A", "B"]), ( "( || ( || ( ( A ) B ) ) )", [ "||", ["A", "B"] ]), ( "|| ( A )", ["A"]), ( "( || ( || ( || ( A ) foo? ( B ) ) ) )", [ "||", ["A", "foo?", ["B"] ]]), ( "( || ( || ( bar? ( A ) || ( foo? ( B ) ) ) ) )", [ "||", ["bar?", ["A"], "foo?", ["B"] ]]), ( "A || ( ) foo? ( ) B", ["A", "B"]), ( "|| ( A ) || ( B )", ["A", "B"]), ( "foo? ( A ) foo? ( B )", ["foo?", ["A"], "foo?", ["B"]]), ( "|| ( ( A B ) C )", [ "||", [ ["A", "B"], "C"] ]), ( "|| ( ( A B ) ( C ) )", [ "||", [ ["A", "B"], "C"] ]), ) test_cases_xfail = ( "( A", "A )", "||( A B )", "|| (A B )", "|| ( A B)", "|| ( A B", "|| A B )", "|| A B", "|| ( A B ) )", "|| || B C", "|| ( A B || )", "a? A", ( "( || ( || || ( A ) foo? ( B ) ) )"), ( "( || ( || bar? ( A ) foo? ( B ) ) )"), ) for dep_str, expected_result in test_cases: self.assertEqual(paren_reduce(dep_str), expected_result, "input: '%s' result: %s != %s" % (dep_str, paren_reduce(dep_str), expected_result)) for dep_str in test_cases_xfail: self.assertRaisesMsg(dep_str, InvalidDependString, paren_reduce, dep_str)
def testParenReduce(self): test_cases = ( ("A", ["A"]), ("( A )", ["A"]), ("|| ( A B )", ["||", ["A", "B"]]), ("|| ( A || ( B C ) )", ["||", ["A", "||", ["B", "C"]]]), ("|| ( A || ( B C D ) )", ["||", ["A", "||", ["B", "C", "D"]]]), ("|| ( A || ( B || ( C D ) E ) )", ["||", ["A", "||", ["B", "||", ["C", "D"], "E"]]]), ("a? ( A )", ["a?", ["A"]]), ("( || ( ( ( A ) B ) ) )", ["A", "B"]), ("( || ( || ( ( A ) B ) ) )", ["||", ["A", "B"]]), ("|| ( A )", ["A"]), ("( || ( || ( || ( A ) foo? ( B ) ) ) )", ["||", ["A", "foo?", ["B"]]]), ("( || ( || ( bar? ( A ) || ( foo? ( B ) ) ) ) )", ["||", ["bar?", ["A"], "foo?", ["B"]]]), ("A || ( ) foo? ( ) B", ["A", "B"]), ("|| ( A ) || ( B )", ["A", "B"]), ("foo? ( A ) foo? ( B )", ["foo?", ["A"], "foo?", ["B"]]), ("|| ( ( A B ) C )", ["||", [["A", "B"], "C"]]), ("|| ( ( A B ) ( C ) )", ["||", [["A", "B"], "C"]]), ) test_cases_xfail = ( "( A", "A )", "||( A B )", "|| (A B )", "|| ( A B)", "|| ( A B", "|| A B )", "|| A B", "|| ( A B ) )", "|| || B C", "|| ( A B || )", "a? A", ("( || ( || || ( A ) foo? ( B ) ) )"), ("( || ( || bar? ( A ) foo? ( B ) ) )"), ) for dep_str, expected_result in test_cases: self.assertEqual( paren_reduce(dep_str), expected_result, "input: '%s' result: %s != %s" % (dep_str, paren_reduce(dep_str), expected_result)) for dep_str in test_cases_xfail: self.assertRaisesMsg(dep_str, InvalidDependString, paren_reduce, dep_str)
def _eval_use_flags(self, cpv, metadata): use = frozenset(metadata["USE"].split()) raw_use = use iuse = set(f.lstrip("-+") for f in metadata["IUSE"].split()) use = [f for f in use if f in iuse] use.sort() metadata["USE"] = " ".join(use) from portage.dep import paren_reduce, use_reduce, \ paren_normalize, paren_enclose for k in self._pkgindex_use_evaluated_keys: try: deps = paren_reduce(metadata[k]) deps = use_reduce(deps, uselist=raw_use) deps = paren_normalize(deps) deps = paren_enclose(deps) except portage.exception.InvalidDependString as e: writemsg("%s: %s\n" % (k, str(e)), noiselevel=-1) raise if k in _vdb_use_conditional_atoms: v_split = [] for x in deps.split(): try: x = portage.dep.Atom(x) except portage.exception.InvalidAtom: v_split.append(x) else: v_split.append(str(x.evaluate_conditionals(raw_use))) deps = ' '.join(v_split) metadata[k] = deps
def testSrcUri(self): tests = [ ( "0", "http://foo/bar -> blah.tbz2" , False ), ( "1", "http://foo/bar -> blah.tbz2" , False ), ( "2", "|| ( http://foo/bar -> blah.tbz2 )" , False ), ( "2", "http://foo/bar -> blah.tbz2" , True ), ( "2", "foo? ( http://foo/bar -> blah.tbz2 )" , True ), ( "2", "http://foo/bar -> foo? ( ftp://foo/a )" , False ), ( "2", "http://foo/bar -> bar.tbz2 foo? ( ftp://foo/a )" , True ), ( "2", "http://foo/bar blah.tbz2 ->" , False ), ( "2", "-> http://foo/bar blah.tbz2 )" , False ), ( "2", "http://foo/bar ->" , False ), ( "2", "http://foo/bar -> foo? ( http://foo.com/foo )" , False ), ( "2", "foo? ( http://foo/bar -> ) blah.tbz2" , False ), ( "2", "http://foo/bar -> foo/blah.tbz2" , False ), ( "2", "http://foo.com/foo http://foo/bar -> blah.tbz2" , True ), ] for eapi, src_uri, valid in tests: try: _src_uri_validate("cat/pkg-1", eapi, paren_reduce(src_uri)) except InvalidDependString: self.assertEqual(valid, False) else: self.assertEqual(valid, True)
def __getitem__(self, k): v = _PackageMetadataWrapperBase.__getitem__(self, k) if k in self._use_conditional_keys: if self._pkg.root_config.settings.local_config and '?' in v: try: v = paren_enclose( paren_normalize( use_reduce(paren_reduce(v), uselist=self._pkg.use.enabled))) except portage.exception.InvalidDependString: # This error should already have been registered via # self._pkg._invalid_metadata(). pass else: self[k] = v elif k == 'USE' and not self._pkg.built: if not v: # This is lazy because it's expensive. pkgsettings = self._pkg.root_config.trees[ 'porttree'].dbapi.doebuild_settings pkgsettings.setcpv(self._pkg) v = pkgsettings["PORTAGE_USE"] self['USE'] = v return v
def _aux_parse(self, arg): try: lic = use_reduce(arg, matchall=True, flat=True) except TypeError: # portage-2.1.8 compat from portage.dep import paren_reduce lic = use_reduce(paren_reduce(arg, tokenize=True), matchall=True) lic = set(lic) lic.discard('||') lic.update(k for k, v in self.groups.items() if lic & v) return lic
def main(input_args): """Parse input and run the program""" short_opts = "h" long_opts = ('help') try: module_opts, queries = gnu_getopt(input_args, short_opts, long_opts) except GetoptError as err: sys.stderr.write(pp.error("Module %s" % err)) print() print_help(with_description=False) sys.exit(2) parse_module_options(module_opts) if not queries or len(queries) > 1: print_help() sys.exit(2) # # Output # query = Query(queries[0]) matches = query.find(include_masked=True, in_installed=False) if not matches: raise errors.GentoolkitNoMatches(query) matches.sort() matches.reverse() if CONFIG['verbose']: print(matches[0].ebuild_path()) print() pkgdeps = matches[0].deps deps = pkgdeps.get_all_depends(raw=True) deps = paren_reduce(deps) if CONFIG['verbose']: print(deps) print() kwdict = parse_list(deps) if CONFIG['verbose']: print() if not kwdict == None: print(' '.join(kwdict.values())) else: print()
def __setitem__(self, k, v): _PackageMetadataWrapperBase.__setitem__(self, k, v) if k in self._wrapped_keys: getattr(self, "_set_" + k.lower())(k, v) elif k in self._use_conditional_keys: try: reduced = use_reduce(paren_reduce(v), matchall=1) except portage.exception.InvalidDependString as e: self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, e)) else: if reduced and k == 'PROVIDE': for x in portage.flatten(reduced): if not isvalidatom(x): self._pkg._invalid_metadata( k + ".syntax", "%s: %s" % (k, x))
def __setitem__(self, k, v): _PackageMetadataWrapperBase.__setitem__(self, k, v) if k in self._wrapped_keys: getattr(self, "_set_" + k.lower())(k, v) elif k in self._use_conditional_keys: try: reduced = use_reduce(paren_reduce(v), matchall=1) except portage.exception.InvalidDependString as e: self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, e)) else: if reduced and k == 'PROVIDE': for x in portage.flatten(reduced): if not isvalidatom(x): self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, x))
def testUseReduce(self): tests = ( ('|| ( x y )', True ), ('|| x', False ), ('foo? ( x y )', True ), ('foo? ( bar? x y )', False ), ('foo? x', False ), ) for dep_str, valid in tests: try: use_reduce(paren_reduce(dep_str), matchall=True) except InvalidDependString: self.assertEqual(valid, False) else: self.assertEqual(valid, True)
def testUseReduce(self): tests = ( ('|| ( x y )', True), ('|| x', False), ('foo? ( x y )', True), ('foo? ( bar? x y )', False), ('foo? x', False), ) for dep_str, valid in tests: try: use_reduce(paren_reduce(dep_str), matchall=True) except InvalidDependString: self.assertEqual(valid, False) else: self.assertEqual(valid, True)
def _parser(self, deps, use_conditional=None, depth=0): """?DEPEND file parser. @rtype: list @return: L{gentoolkit.atom.Atom} objects """ result = [] if depth == 0: deps = paren_reduce(deps) for tok in deps: if tok == '||': continue if tok[-1] == '?': use_conditional = tok[:-1] continue if isinstance(tok, list): sub_r = self._parser(tok, use_conditional, depth=depth + 1) result.extend(sub_r) use_conditional = None continue # FIXME: This is a quick fix for bug #299260. # A better fix is to not discard blockers in the parser, # but to check for atom.blocker in whatever equery/depends # (in this case) and ignore them there. # TODO: Test to see how much a performance impact ignoring # blockers here rather than checking for atom.blocker has. if tok[0] == '!': # We're not interested in blockers continue # skip it if it's empty if tok and tok != '': atom = Atom(tok) if use_conditional is not None: atom.use_conditional = use_conditional result.append(atom) else: message = "dependencies.py: _parser() found an empty " +\ "dep string token for: %s, deps= %s" raise errors.GentoolkitInvalidAtom(message % (self.cpv, deps)) return result
def _parser(self, deps, use_conditional=None, depth=0): """?DEPEND file parser. @rtype: list @return: L{gentoolkit.atom.Atom} objects """ result = [] if depth == 0: deps = paren_reduce(deps) for tok in deps: if tok == '||': continue if tok[-1] == '?': use_conditional = tok[:-1] continue if isinstance(tok, list): sub_r = self._parser(tok, use_conditional, depth=depth+1) result.extend(sub_r) use_conditional = None continue # FIXME: This is a quick fix for bug #299260. # A better fix is to not discard blockers in the parser, # but to check for atom.blocker in whatever equery/depends # (in this case) and ignore them there. # TODO: Test to see how much a performance impact ignoring # blockers here rather than checking for atom.blocker has. if tok[0] == '!': # We're not interested in blockers continue # skip it if it's empty if tok and tok != '': atom = Atom(tok) if use_conditional is not None: atom.use_conditional = use_conditional result.append(atom) else: message = "dependencies.py: _parser() found an empty " +\ "dep string token for: %s, deps= %s" raise errors.GentoolkitInvalidAtom(message %(self.cpv, deps)) return result
def __getitem__(self, k): v = _PackageMetadataWrapperBase.__getitem__(self, k) if k in self._use_conditional_keys: if self._pkg.root_config.settings.local_config and '?' in v: try: v = paren_enclose(paren_normalize(use_reduce( paren_reduce(v), uselist=self._pkg.use.enabled))) except portage.exception.InvalidDependString: # This error should already have been registered via # self._pkg._invalid_metadata(). pass else: self[k] = v elif k == 'USE' and not self._pkg.built: if not v: # This is lazy because it's expensive. pkgsettings = self._pkg.root_config.trees[ 'porttree'].dbapi.doebuild_settings pkgsettings.setcpv(self._pkg) v = pkgsettings["PORTAGE_USE"] self['USE'] = v return v
def __iter__(self): if self._deps is None: self._deps = paren_reduce(self._depstr) return PortageBaseDep.__iter__(self)
def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, use_cache=1, use_binaries=0, myroot="/", trees=None): """Takes a depend string and parses the condition.""" edebug = mysettings.get("PORTAGE_DEBUG", None) == "1" #check_config_instance(mysettings) if trees is None: trees = globals()["db"] if use=="yes": if myuse is None: #default behavior myusesplit = mysettings["PORTAGE_USE"].split() else: myusesplit = myuse # We've been given useflags to use. #print "USE FLAGS PASSED IN." #print myuse #if "bindist" in myusesplit: # print "BINDIST is set!" #else: # print "BINDIST NOT set." else: #we are being run by autouse(), don't consult USE vars yet. # WE ALSO CANNOT USE SETTINGS myusesplit=[] #convert parenthesis to sublists try: mysplit = paren_reduce(depstring) except InvalidDependString as e: return [0, str(e)] mymasks = set() useforce = set() useforce.add(mysettings["ARCH"]) if use == "all": # This masking/forcing is only for repoman. In other cases, relevant # masking/forcing should have already been applied via # config.regenerate(). Also, binary or installed packages may have # been built with flags that are now masked, and it would be # inconsistent to mask them now. Additionally, myuse may consist of # flags from a parent package that is being merged to a $ROOT that is # different from the one that mysettings represents. mymasks.update(mysettings.usemask) mymasks.update(mysettings.archlist()) mymasks.discard(mysettings["ARCH"]) useforce.update(mysettings.useforce) useforce.difference_update(mymasks) try: mysplit = use_reduce(mysplit, uselist=myusesplit, masklist=mymasks, matchall=(use=="all"), excludeall=useforce) except InvalidDependString as e: return [0, str(e)] # Do the || conversions mysplit = dep_opconvert(mysplit) if mysplit == []: #dependencies were reduced to nothing return [1,[]] # Recursively expand new-style virtuals so as to # collapse one or more levels of indirection. try: mysplit = _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, use=use, mode=mode, myuse=myuse, use_force=useforce, use_mask=mymasks, use_cache=use_cache, use_binaries=use_binaries, myroot=myroot, trees=trees) except ParseError as e: return [0, str(e)] mysplit2=mysplit[:] mysplit2=dep_wordreduce(mysplit2,mysettings,mydbapi,mode,use_cache=use_cache) if mysplit2 is None: return [0, _("Invalid token")] writemsg("\n\n\n", 1) writemsg("mysplit: %s\n" % (mysplit), 1) writemsg("mysplit2: %s\n" % (mysplit2), 1) try: selected_atoms = dep_zapdeps(mysplit, mysplit2, myroot, use_binaries=use_binaries, trees=trees) except InvalidAtom as e: if portage.dep._dep_check_strict: raise # This shouldn't happen. # dbapi.match() failed due to an invalid atom in # the dependencies of an installed package. return [0, _("Invalid atom: '%s'") % (e,)] return [1, selected_atoms]
def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, use_cache=1, use_binaries=0, myroot="/", trees=None): """Takes a depend string and parses the condition.""" edebug = mysettings.get("PORTAGE_DEBUG", None) == "1" #check_config_instance(mysettings) if trees is None: trees = globals()["db"] if use == "yes": if myuse is None: #default behavior myusesplit = mysettings["PORTAGE_USE"].split() else: myusesplit = myuse # We've been given useflags to use. #print "USE FLAGS PASSED IN." #print myuse #if "bindist" in myusesplit: # print "BINDIST is set!" #else: # print "BINDIST NOT set." else: #we are being run by autouse(), don't consult USE vars yet. # WE ALSO CANNOT USE SETTINGS myusesplit = [] #convert parenthesis to sublists try: mysplit = paren_reduce(depstring) except InvalidDependString as e: return [0, str(e)] mymasks = set() useforce = set() useforce.add(mysettings["ARCH"]) if use == "all": # This masking/forcing is only for repoman. In other cases, relevant # masking/forcing should have already been applied via # config.regenerate(). Also, binary or installed packages may have # been built with flags that are now masked, and it would be # inconsistent to mask them now. Additionally, myuse may consist of # flags from a parent package that is being merged to a $ROOT that is # different from the one that mysettings represents. mymasks.update(mysettings.usemask) mymasks.update(mysettings.archlist()) mymasks.discard(mysettings["ARCH"]) useforce.update(mysettings.useforce) useforce.difference_update(mymasks) try: mysplit = use_reduce(mysplit, uselist=myusesplit, masklist=mymasks, matchall=(use == "all"), excludeall=useforce) except InvalidDependString as e: return [0, str(e)] # Do the || conversions mysplit = dep_opconvert(mysplit) if mysplit == []: #dependencies were reduced to nothing return [1, []] # Recursively expand new-style virtuals so as to # collapse one or more levels of indirection. try: mysplit = _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, use=use, mode=mode, myuse=myuse, use_force=useforce, use_mask=mymasks, use_cache=use_cache, use_binaries=use_binaries, myroot=myroot, trees=trees) except ParseError as e: return [0, str(e)] mysplit2 = mysplit[:] mysplit2 = dep_wordreduce(mysplit2, mysettings, mydbapi, mode, use_cache=use_cache) if mysplit2 is None: return [0, _("Invalid token")] writemsg("\n\n\n", 1) writemsg("mysplit: %s\n" % (mysplit), 1) writemsg("mysplit2: %s\n" % (mysplit2), 1) try: selected_atoms = dep_zapdeps(mysplit, mysplit2, myroot, use_binaries=use_binaries, trees=trees) except InvalidAtom as e: if portage.dep._dep_check_strict: raise # This shouldn't happen. # dbapi.match() failed due to an invalid atom in # the dependencies of an installed package. return [0, _("Invalid atom: '%s'") % (e, )] return [1, selected_atoms]