def _get_pkg_atoms(self, failed_pkgs, pkg_atoms, pkg_invalid_entries): """ Get the package atoms for the specified failed packages. @param failed_pkgs: failed packages to iterate @type failed_pkgs: dict @param pkg_atoms: add package atoms to this set @type pkg_atoms: set @param pkg_invalid_entries: add any packages that are invalid to this set @type pkg_invalid_entries: set """ portdb = portage.db[portage.root]['porttree'].dbapi for failed_pkg in failed_pkgs: # validate pkg name pkg_name = '%s' % failed_pkg.replace(MERGING_IDENTIFIER, '') pkg_atom = '=%s' % pkg_name if not isvalidatom(pkg_atom): pkg_invalid_entries.add("'%s' is an invalid package atom." % pkg_atom) if not portdb.cpv_exists(pkg_name): pkg_invalid_entries.add( "'%s' does not exist in the ebuild repository." % pkg_name) pkg_atoms.add(pkg_atom)
def _get_pkg_atoms(self, failed_pkgs, pkg_atoms, pkg_invalid_entries): """ Get the package atoms for the specified failed packages. @param failed_pkgs: failed packages to iterate @type failed_pkgs: dict @param pkg_atoms: add package atoms to this set @type pkg_atoms: set @param pkg_invalid_entries: add any packages that are invalid to this set @type pkg_invalid_entries: set """ portdb = portage.db[portage.root]['porttree'].dbapi for failed_pkg in failed_pkgs: # validate pkg name pkg_name = '%s' % failed_pkg.replace(MERGING_IDENTIFIER, '') pkg_atom = '=%s' % pkg_name if not isvalidatom(pkg_atom): pkg_invalid_entries.add("'%s' is an invalid package atom." % pkg_atom) if not portdb.cpv_exists(pkg_name): pkg_invalid_entries.add( "'%s' does not exist in the portage tree." % pkg_name) pkg_atoms.add(pkg_atom)
def check(self): if not isvalidatom(self.cpv): print('%s:%d: error: not a valid portage atom: %s' % (self.path.name, self.line_no, self.cpv)) return False # https://www.funtoo.org/Portage_API p = portage.db[portage.root]["porttree"].dbapi resolved_ebuild = p.xmatch(origdep=self.cpv, level='bestmatch-visible') if not resolved_ebuild: print('%s:%d: error: portage atom not in any repo: %s' % (self.path.name, self.line_no, self.cpv)) return False def filtered_use(uses): for use in uses: if use[0] in ('+', '-'): yield use[1:] else: yield use ebuild_uses = set( filtered_use(p.aux_get(resolved_ebuild, ['IUSE'])[0].split())) given_uses = set(filtered_use(self.uses)) unknown_uses = given_uses - ebuild_uses if unknown_uses: print('%s:%d: error: "%s" not a valid use flag: %s' % (self.path.name, self.line_no, ' '.join(unknown_uses), self.line)) print('└─ available USE flags: %s' % ' '.join(ebuild_uses)) return False return True
def dep_expand(mydep, mydb=None, use_cache=1, settings=None): ''' @rtype: Atom ''' if not len(mydep): return mydep if mydep[0]=="*": mydep=mydep[1:] orig_dep = mydep if isinstance(orig_dep, Atom): mydep = orig_dep.cp else: mydep = orig_dep has_cat = '/' in orig_dep if not has_cat: alphanum = re.search(r'\w', orig_dep) if alphanum: mydep = orig_dep[:alphanum.start()] + "null/" + \ orig_dep[alphanum.start():] try: mydep = Atom(mydep) except InvalidAtom: # Missing '=' prefix is allowed for backward compatibility. if not isvalidatom("=" + mydep): raise mydep = Atom('=' + mydep) orig_dep = '=' + orig_dep if not has_cat: null_cat, pn = catsplit(mydep.cp) mydep = pn else: mydep = mydep.cp expanded = cpv_expand(mydep, mydb=mydb, use_cache=use_cache, settings=settings) return Atom(orig_dep.replace(mydep, expanded, 1))
def get_maintainers(atom: str, portdir: str = '/usr/portage') -> tuple: """ Checks the metadata for given package and returns tuple of maintainer emails. :param atom: package atom to check :type: atom: str :param portdir: path to portage tree :type portdir: str :returns: tuple of ('*****@*****.**', ...) :rtype: tuple """ assert isinstance(atom, str) assert isinstance(portdir, str) assert os.path.isdir(portdir) assert dep.isvalidatom(atom) maintainers = [] metadata_path = os.path.join(portdir, atom, 'metadata.xml') if not os.path.exists(metadata_path): raise FileNotFoundError('Metadata file not found: %s' % metadata_path) xml = portage.xml.metadata.MetaDataXML(metadata_path, '/usr/portage/metadata/projects.xml') for maintainer in xml.maintainers(): maintainers.append(maintainer.email) return tuple(maintainers)
def is_valid_package_atom(x, allow_repo=False, allow_build_id=True): if "/" not in x.split(":")[0]: x2 = insert_category_into_atom(x, 'cat') if x2 != None: x = x2 return isvalidatom(x, allow_blockers=False, allow_repo=allow_repo, allow_build_id=allow_build_id)
def check(self): if not isvalidatom(self.cpv): print('%s:%d: error: not a valid portage atom: %s' % (self.path.name, self.line_no, self.cpv)) return False actual_ebuild = portage.db[portage.root]["porttree"].dbapi.xmatch( origdep=self.cpv, level='bestmatch-visible' ) if not actual_ebuild: print('%s:%d: error: portage atom not in any repo: %s' % (self.path.name, self.line_no, self.cpv)) return False def filtered_use(uses): for use in uses: if use[0] in ('+', '-'): yield use[1:] else: yield use permitted_uses = set(filtered_use( portage.db[portage.root]["porttree"].dbapi.aux_get(actual_ebuild, ['IUSE'])[0].split() )) supplied_uses = set(filtered_use(self.uses)) unknown_uses = supplied_uses - permitted_uses if unknown_uses: print('%s:%d: error: "%s" not a valid use flag: %s %s' % ( self.path.name, self.line_no, ' '.join(unknown_uses), self.cpv, ' '.join(self.uses)) ) print('└─ available USE flags: %s' % ' '.join(permitted_uses)) return False return True
def _get_pkg_atoms(self, failed_pkgs, pkg_atoms, pkg_invalid_entries): """ Get the package atoms for the specified failed packages. @param failed_pkgs: failed packages to iterate @type failed_pkgs: dict @param pkg_atoms: append package atoms to this set @type pkg_atoms: set @param pkg_invalid_entries: append any packages that are invalid to this set @type pkg_invalid_entries: set """ emerge_config = load_emerge_config() portdb = emerge_config.target_config.trees['porttree'].dbapi for failed_pkg in failed_pkgs: # validate pkg name pkg_name = '%s' % failed_pkg.replace(MERGING_IDENTIFIER, '') pkg_atom = '=%s' % pkg_name if not isvalidatom(pkg_atom): pkg_invalid_entries.append("'%s' is an invalid package atom." % pkg_atom) if not portdb.cpv_exists(pkg_name): pkg_invalid_entries.append( "'%s' does not exist in the portage tree." % pkg_name) pkg_atoms.add(pkg_atom)
def is_valid_package_atom(x, allow_repo=False, allow_build_id=True): if "/" not in x.split(":")[0]: x2 = insert_category_into_atom(x, "cat") if x2 != None: x = x2 return isvalidatom(x, allow_blockers=False, allow_repo=allow_repo, allow_build_id=allow_build_id)
def __init__(self, st): """An atom is initialized from an atom string""" if not isvalidatom(st): st = '=' + st cp = dep_getkey(st) self.ver = dep_getcpv(st)[len(cp) + 1:] # +1 to strip the leading '-' slashparts = cp.split("/") self.category = slashparts[0] self.name = slashparts[1]
def PackagesFileValidator(atom): """ This function mutates atoms that begin with - or * It then checks to see if that atom is valid, and if so returns True, else it returns False. Args: atom: a string representing an atom such as sys-apps/portage-2.1 """ if atom.startswith("*") or atom.startswith("-"): atom = atom[1:] if not isvalidatom(atom): return False return True
def find_atom(summary: str) -> str or None: """ Searches a bug summary line for something that looks like a package atom. :param summary: bug summary line to search :type summary: str :returns: unqualified package atom (CP) :rtype: str or None """ assert isinstance(summary, str) match = line_atom.search(summary) try: atom = match.group(1) except AttributeError: # we still dont' have an atom return None if atom.endswith(':'): atom = atom[:-1] if not dep.isvalidatom(atom): # try prepending an '=' if not dep.isvalidatom('='+atom): # it's not a valid atom return None if not dep.isjustname(atom): atom = portage.getCPFromCPV(atom) # check if we've listed all atoms yet and create the list if not global package_list if package_list is None: package_list = portage.portdb.cp_all() if atom in package_list: return atom else: return None
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 is_valid_atom(cls, atom): """ Return True if atom is valid portage =category/pn-pv. :param atom: category/package-version :type atom: string :returns: bool **Example:** >>> PortageUtils.is_valid_atom('=dev-python/foobar-1.0') True >>> PortageUtils.is_valid_atom('=foobar-1.0') False """ return bool(portage_dep.isvalidatom(atom))
def dep_expand(mydep, mydb=None, use_cache=1, settings=None): ''' @rtype: Atom ''' orig_dep = mydep if isinstance(orig_dep, Atom): has_cat = True else: if not mydep: return mydep if mydep[0] == "*": mydep = mydep[1:] orig_dep = mydep has_cat = '/' in orig_dep.split(':')[0] if not has_cat: alphanum = re.search(r'\w', orig_dep) if alphanum: mydep = orig_dep[:alphanum.start()] + "null/" + \ orig_dep[alphanum.start():] try: mydep = Atom(mydep, allow_repo=True) except InvalidAtom: # Missing '=' prefix is allowed for backward compatibility. if not isvalidatom("=" + mydep, allow_repo=True): raise mydep = Atom('=' + mydep, allow_repo=True) orig_dep = '=' + orig_dep if not has_cat: null_cat, pn = catsplit(mydep.cp) mydep = pn if has_cat: # Optimize most common cases to avoid calling cpv_expand. if not mydep.cp.startswith("virtual/"): return mydep if not hasattr(mydb, "cp_list") or \ mydb.cp_list(mydep.cp): return mydep # Fallback to legacy cpv_expand for old-style PROVIDE virtuals. mydep = mydep.cp expanded = cpv_expand(mydep, mydb=mydb, use_cache=use_cache, settings=settings) return Atom(orig_dep.replace(mydep, expanded, 1), allow_repo=True)
def read_config_files(): global toskip, from_date # # Read ebuilds to skip in the re-compilation # fd = open(conf_toskip, 'r') toskip_lines = fd.readlines() fd.close() for atom in toskip_lines: # Whitespace cleanup atom = re.sub('\s+', '', atom) if not re.match('^#.*|^$', atom) and isvalidatom(atom): toskip.append(dep_getcpv(atom)) # # Read from_date value from the config file # if os.path.isfile(conf_fromdate): fd = open(conf_fromdate, 'r') from_date = fd.readline() fd.close() else: raise EwoError("The starting point has not been set!\nPlease specify it using -s option first")
def stablerdeps(atom, config): """ Find packages with stable versions which depend on atom We query the tinderbox at http://qa-reports.gentoo.org/output/genrdeps/rindex/ for this purpose. The result is a list of pairs of package atoms and a list of necessary useflags """ tinderbox = config['tinderbox-url'] # File structure on this tinderbox equals that in the tree # Problem: The rdeps can be version dependent # nothing we can do about this here... socket.setdefaulttimeout(45) try: download = urlopen(tinderbox + atom).read().decode('utf-8') except HTTPError as e: # Cleanup the timeout: socket.setdefaulttimeout(None) if e.code == 404: # 404 is OK, the package has no stable rdeps return [] else: # Some other error should not occur: print("Non 404 Error on accessing the tinderbox") sys.exit(1) # If we are here everything is fine, cleanup the timeout: socket.setdefaulttimeout(None) # The result is a "\n" separated list of packages : useflags packlist = download.rstrip().split("\n") # Split at : to see if useflags are necessary splitlist2 = [p.split(":") for p in packlist] # Fill with empty useflags if nothing is given: splitlist = [] for s in splitlist2: if len(s) == 1: splitlist.append([s[0], [" "]]) else: splitlist.append([s[0], s[1].split("+")]) d = dict([]) for s in splitlist: # Saves necessary useflags under package names, removing duplicates. if isvalidatom('=' + s[0]): d[gP(s[0]).packageCatName()] = s[1] outlist2 = [[k, d[k]] for k in list(d.keys())] outlist = [] # outlist2 is set up at this point. It contains all candidates. To cut it down we sample # randomly without replacement until the list is empty or we have config['rdeps'] many. # We are calling eix for each package to work around issues with --stable: # What we should do with a future version of eix is to do this in a single run # or fork multiple eix instances while ((len(outlist2) > 0) and (len(outlist) < config['rdeps'])): # Warning: sample returns a list, even if only one sample [samp] = random.sample(outlist2, 1) # Drop the one we selected outlist2.remove(samp) eixcall = ["eix", "--stable", "--only-names", "--exact", samp[0]] p2 = Popen(eixcall, stdout=PIPE) out = p2.communicate()[0].decode('utf-8') if out == '': continue else: outlist.append(samp) if len(outlist2) > 0: print("More than " + str(config['rdeps']) + " stable rdeps for " + atom + ", took a sample. \n") return outlist
def testIsValidAtom(self): test_cases = ( IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("=sys-apps/portage-2.1", True), IsValidAtomTestCase("=sys-apps/portage-2.1*", True), IsValidAtomTestCase(">=sys-apps/portage-2.1", True), IsValidAtomTestCase("<=sys-apps/portage-2.1", True), IsValidAtomTestCase(">sys-apps/portage-2.1", True), IsValidAtomTestCase("<sys-apps/portage-2.1", True), IsValidAtomTestCase("~sys-apps/portage-2.1", True), IsValidAtomTestCase("sys-apps/portage:foo", True), IsValidAtomTestCase("sys-apps/portage-2.1:foo", False), IsValidAtomTestCase("sys-apps/portage-2.1:", False), IsValidAtomTestCase("sys-apps/portage-2.1:", False), IsValidAtomTestCase("sys-apps/portage-2.1:[foo]", False), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo[bar?,!baz?,!doc=,build=]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[doc?]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!doc?]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[doc=]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!doc=]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!doc]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!-doc]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!-doc=]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!-doc?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc=]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc!=]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc=]", False), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo[bar][-baz][doc?][!build?]", False), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?]", True), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?,]", False), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo[,bar,-baz,doc?,!build?]", False), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo[bar,-baz][doc?,!build?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[bar][doc,build]", False), IsValidAtomTestCase(">~cate-gory/foo-1.0", False), IsValidAtomTestCase(">~category/foo-1.0", False), IsValidAtomTestCase("<~category/foo-1.0", False), IsValidAtomTestCase("###cat/foo-1.0", False), IsValidAtomTestCase("~sys-apps/portage", False), IsValidAtomTestCase("portage", False), IsValidAtomTestCase("=portage", False), IsValidAtomTestCase(">=portage-2.1", False), IsValidAtomTestCase("~portage-2.1", False), IsValidAtomTestCase("=portage-2.1*", False), IsValidAtomTestCase("null/portage", True), IsValidAtomTestCase("null/portage*:0", False), IsValidAtomTestCase(">=null/portage-2.1", True), IsValidAtomTestCase(">=null/portage", False), IsValidAtomTestCase(">null/portage", False), IsValidAtomTestCase("=null/portage*", False), IsValidAtomTestCase("=null/portage", False), IsValidAtomTestCase("~null/portage", False), IsValidAtomTestCase("<=null/portage", False), IsValidAtomTestCase("<null/portage", False), IsValidAtomTestCase("~null/portage-2.1", True), IsValidAtomTestCase("=null/portage-2.1*", True), IsValidAtomTestCase("null/portage-2.1*", False), IsValidAtomTestCase("app-doc/php-docs-20071125", False), IsValidAtomTestCase("app-doc/php-docs-20071125-r2", False), IsValidAtomTestCase("=foo/bar-1-r1-1-r1", False), IsValidAtomTestCase("foo/-z-1", False), # These are invalid because pkg name must not end in hyphen # followed by numbers IsValidAtomTestCase("=foo/bar-1-r1-1-r1", False), IsValidAtomTestCase("=foo/bar-123-1", False), IsValidAtomTestCase("=foo/bar-123-1*", False), IsValidAtomTestCase("foo/bar-123", False), IsValidAtomTestCase("=foo/bar-123-1-r1", False), IsValidAtomTestCase("=foo/bar-123-1-r1*", False), IsValidAtomTestCase("foo/bar-123-r1", False), IsValidAtomTestCase("foo/bar-1", False), IsValidAtomTestCase("=foo/bar--baz-1-r1", True), IsValidAtomTestCase("=foo/bar-baz--1-r1", True), IsValidAtomTestCase("=foo/bar-baz---1-r1", True), IsValidAtomTestCase("=foo/bar-baz---1", True), IsValidAtomTestCase("=foo/bar-baz-1--r1", False), IsValidAtomTestCase("games-strategy/ufo2000", True), IsValidAtomTestCase("~games-strategy/ufo2000-0.1", True), IsValidAtomTestCase("=media-libs/x264-20060810", True), IsValidAtomTestCase("foo/b", True), IsValidAtomTestCase("app-text/7plus", True), IsValidAtomTestCase("foo/666", True), IsValidAtomTestCase("=dev-libs/poppler-qt3-0.11*", True), #Testing atoms with repositories IsValidAtomTestCase("sys-apps/portage::repo_123-name", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.1::repo", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.1*::repo", True, allow_repo=True), IsValidAtomTestCase("sys-apps/portage:foo::repo", True, allow_repo=True), IsValidAtomTestCase("sys-apps/portage-2.1:foo::repo", False, allow_repo=True), IsValidAtomTestCase("sys-apps/portage-2.1:::repo", False, allow_repo=True), IsValidAtomTestCase("sys-apps/portage-2.1:::repo[foo]", False, allow_repo=True), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo::repo[bar?,!baz?,!doc=,build=]", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[doc?]", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[!doc]", False, allow_repo=True), IsValidAtomTestCase("###cat/foo-1.0::repo", False, allow_repo=True), IsValidAtomTestCase("~sys-apps/portage::repo", False, allow_repo=True), IsValidAtomTestCase("portage::repo", False, allow_repo=True), IsValidAtomTestCase("=portage::repo", False, allow_repo=True), IsValidAtomTestCase("null/portage::repo", True, allow_repo=True), IsValidAtomTestCase("app-doc/php-docs-20071125::repo", False, allow_repo=True), IsValidAtomTestCase("=foo/bar-1-r1-1-r1::repo", False, allow_repo=True), IsValidAtomTestCase("sys-apps/portage::repo_123-name", False, allow_repo=False), IsValidAtomTestCase("=sys-apps/portage-2.1::repo", False, allow_repo=False), IsValidAtomTestCase("=sys-apps/portage-2.1*::repo", False, allow_repo=False), IsValidAtomTestCase("sys-apps/portage:foo::repo", False, allow_repo=False), IsValidAtomTestCase( "=sys-apps/portage-2.2*:foo::repo[bar?,!baz?,!doc=,build=]", False, allow_repo=False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[doc?]", False, allow_repo=False), IsValidAtomTestCase("null/portage::repo", False, allow_repo=False), # Testing repo atoms with eapi # If allow_repo is None, it should be overwritten by eapi IsValidAtomTestCase("sys-apps/portage::repo", True, allow_repo=None), IsValidAtomTestCase("sys-apps/portage::repo", False, allow_repo=None, eapi="5"), IsValidAtomTestCase("sys-apps/portage::repo", True, allow_repo=None, eapi="5-progress"), IsValidAtomTestCase("sys-apps/portage::repo", False, allow_repo=None, eapi="7"), # If allow_repo is not None, it should not be overwritten by eapi IsValidAtomTestCase("sys-apps/portage::repo", False, allow_repo=False), IsValidAtomTestCase("sys-apps/portage::repo", False, allow_repo=False, eapi="5"), IsValidAtomTestCase("sys-apps/portage::repo", False, allow_repo=False, eapi="5-progress"), IsValidAtomTestCase("sys-apps/portage::repo", False, allow_repo=False, eapi="7"), IsValidAtomTestCase("sys-apps/portage::repo", True, allow_repo=True), IsValidAtomTestCase("sys-apps/portage::repo", True, allow_repo=True, eapi="5"), IsValidAtomTestCase("sys-apps/portage::repo", True, allow_repo=True, eapi="5-progress"), IsValidAtomTestCase("sys-apps/portage::repo", True, allow_repo=True, eapi="7"), IsValidAtomTestCase("virtual/ffmpeg:0/53", True), IsValidAtomTestCase("virtual/ffmpeg:0/53=", True), IsValidAtomTestCase("virtual/ffmpeg:0/53*", False), IsValidAtomTestCase("virtual/ffmpeg:=", True), IsValidAtomTestCase("virtual/ffmpeg:0=", True), IsValidAtomTestCase("virtual/ffmpeg:*", True), IsValidAtomTestCase("virtual/ffmpeg:0*", False), IsValidAtomTestCase("virtual/ffmpeg:0", True), # Wildcard atoms IsValidAtomTestCase("*/portage-2.1", False, allow_wildcard=True), ) for test_case in test_cases: if test_case.expected: atom_type = "valid" else: atom_type = "invalid" self.assertEqual(bool( isvalidatom(test_case.atom, allow_wildcard=test_case.allow_wildcard, allow_repo=test_case.allow_repo, allow_build_id=test_case.allow_build_id, eapi=test_case.eapi)), test_case.expected, msg="isvalidatom(%s) != %s" % (test_case.atom, test_case.expected))
def is_valid_package_atom(x, allow_repo=False): if "/" not in x: x2 = insert_category_into_atom(x, 'cat') if x2 != None: x = x2 return isvalidatom(x, allow_blockers=False, allow_repo=allow_repo)
def stablerdeps (package, config): """ Find packages with stable versions which depend on atom We query the tinderbox at http://qa-reports.gentoo.org/output/genrdeps/rindex/ for this purpose. The result is a list of pairs of package atoms and a list of necessary useflags """ tinderbox = config['tinderbox-url'] # File structure on this tinderbox equals that in the tree # Problem: The rdeps can be version dependent # nothing we can do about this here... atom = package.packageCatName() socket.setdefaulttimeout(45) try: download = urlopen(tinderbox + atom).read().decode('utf-8') except HTTPError as e: # Cleanup the timeout: socket.setdefaulttimeout(None) if e.code == 404: # 404 is OK, the package has no stable rdeps return [] else: # Some other error should not occur: print("Non 404 Error on accessing the tinderbox") sys.exit (1) # If we are here everything is fine, cleanup the timeout: socket.setdefaulttimeout(None) # The result is a "\n" separated list of packages : useflags packlist = download.rstrip().split("\n") # Split at : to see if useflags are necessary splitlist2 = [p.split(":") for p in packlist] # Fill with empty useflags if nothing is given: splitlist = [] for s in splitlist2: if len(s) == 1: splitlist.append([s[0],[" "]]) else: splitlist.append([s[0],s[1].split("+")]) d = dict([]) for s in splitlist: # Saves necessary useflags under package names, removing duplicates. if isvalidatom('=' + s[0]): d[gP(s[0]).packageCatName()] = s[1] outlist2 = [[k, d[k]] for k in list(d.keys())] outlist = [] # outlist2 is set up at this point. It contains all candidates. To cut it down we sample # randomly without replacement until the list is empty or we have config['rdeps'] many. # We are calling eix for each package to work around issues with --stable: # What we should do with a future version of eix is to do this in a single run # or fork multiple eix instances while ((len (outlist2) > 0) and (len(outlist) < config['rdeps'])): # Warning: sample returns a list, even if only one sample [samp]=random.sample(outlist2, 1) # Drop the one we selected outlist2.remove(samp) eixcall = ["eix", "--stable", "--only-names", "--exact", samp[0]] p2 = Popen(eixcall, stdout=PIPE) out = p2.communicate()[0].decode('utf-8') if out == '': continue else : outlist.append(samp) if len(outlist2) > 0: print("More than " + str(config['rdeps']) + " stable rdeps for " + atom + ", took a sample. \n") return outlist
def isValid(self): return isvalidatom(self.atom)
def testIsValidAtom(self): tests = [ ( "sys-apps/portage", True ), ( "=sys-apps/portage-2.1", True ), ( "=sys-apps/portage-2.1*", True ), ( ">=sys-apps/portage-2.1", True ), ( "<=sys-apps/portage-2.1", True ), ( ">sys-apps/portage-2.1", True ), ( "<sys-apps/portage-2.1", True ), ( "~sys-apps/portage-2.1", True ), ( "sys-apps/portage:foo", True ), ( "sys-apps/portage-2.1:foo", False ), ( "sys-apps/portage-2.1:", False ), ( "sys-apps/portage-2.1:[foo]", False ), ( "=sys-apps/portage-2.2*:foo[bar?,!baz?,!doc=,build=]", True ), ( "=sys-apps/portage-2.2*:foo[doc?]", True ), ( "=sys-apps/portage-2.2*:foo[!doc?]", True ), ( "=sys-apps/portage-2.2*:foo[doc=]", True ), ( "=sys-apps/portage-2.2*:foo[!doc=]", True ), ( "=sys-apps/portage-2.2*:foo[!doc]", False ), ( "=sys-apps/portage-2.2*:foo[!-doc]", False ), ( "=sys-apps/portage-2.2*:foo[!-doc=]", False ), ( "=sys-apps/portage-2.2*:foo[!-doc?]", False ), ( "=sys-apps/portage-2.2*:foo[-doc?]", False ), ( "=sys-apps/portage-2.2*:foo[-doc=]", False ), ( "=sys-apps/portage-2.2*:foo[-doc!=]", False ), ( "=sys-apps/portage-2.2*:foo[-doc=]", False ), ( "=sys-apps/portage-2.2*:foo[bar][-baz][doc?][!build?]", False ), ( "=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?]", True ), ( "=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?,]", False ), ( "=sys-apps/portage-2.2*:foo[,bar,-baz,doc?,!build?]", False ), ( "=sys-apps/portage-2.2*:foo[bar,-baz][doc?,!build?]", False ), ( "=sys-apps/portage-2.2*:foo[bar][doc,build]", False ), ( ">~cate-gory/foo-1.0", False ), ( ">~category/foo-1.0", False ), ( "<~category/foo-1.0", False ), ( "###cat/foo-1.0", False ), ( "~sys-apps/portage", False ), ( "portage", False ), ( "=portage", False ), ( ">=portage-2.1", False ), ( "~portage-2.1", False ), ( "=portage-2.1*", False ), ( "null/portage", True ), ( "null/portage*:0", False ), ( ">=null/portage-2.1", True ), ( ">=null/portage", False ), ( ">null/portage", False ), ( "=null/portage*", False ), ( "=null/portage", False ), ( "~null/portage", False ), ( "<=null/portage", False ), ( "<null/portage", False ), ( "~null/portage-2.1", True ), ( "=null/portage-2.1*", True ), ( "null/portage-2.1*", False ), ( "app-doc/php-docs-20071125", False), ( "app-doc/php-docs-20071125-r2", False), ( "=foo/bar-1-r1-1-r1", False ), ( "foo/-z-1", False ), # These are invalid because pkg name must not end in hyphen # followed by numbers ( "=foo/bar-1-r1-1-r1", False ), ( "=foo/bar-123-1", False ), ( "=foo/bar-123-1*", False ), ( "foo/bar-123", False ), ( "=foo/bar-123-1-r1", False ), ( "=foo/bar-123-1-r1*", False ), ( "foo/bar-123-r1", False ), ( "foo/bar-1", False ), ( "=foo/bar--baz-1-r1", True ), ( "=foo/bar-baz--1-r1", True ), ( "=foo/bar-baz---1-r1", True ), ( "=foo/bar-baz---1", True ), ( "=foo/bar-baz-1--r1", False ), ( "games-strategy/ufo2000", True ), ( "~games-strategy/ufo2000-0.1", True ), ( "=media-libs/x264-20060810", True ), ( "foo/b", True ), ( "app-text/7plus", True ), ( "foo/666", True ), ( "=dev-libs/poppler-qt3-0.11*", True ), ] for test in tests: if test[1]: atom_type = "valid" else: atom_type = "invalid" self.assertEqual( bool(isvalidatom( test[0] )), test[1], msg="isvalidatom(%s) != %s" % ( test[0], test[1] ) )
def testIsValidAtom(self): tests = [ ("sys-apps/portage", True), ("=sys-apps/portage-2.1", True), ("=sys-apps/portage-2.1*", True), (">=sys-apps/portage-2.1", True), ("<=sys-apps/portage-2.1", True), (">sys-apps/portage-2.1", True), ("<sys-apps/portage-2.1", True), ("~sys-apps/portage-2.1", True), ("sys-apps/portage:foo", True), ("sys-apps/portage-2.1:foo", False), ("sys-apps/portage-2.1:", False), ("sys-apps/portage-2.1:[foo]", False), ("=sys-apps/portage-2.2*:foo[bar?,!baz?,!doc=,build=]", True), ("=sys-apps/portage-2.2*:foo[doc?]", True), ("=sys-apps/portage-2.2*:foo[!doc?]", True), ("=sys-apps/portage-2.2*:foo[doc=]", True), ("=sys-apps/portage-2.2*:foo[!doc=]", True), ("=sys-apps/portage-2.2*:foo[!doc]", False), ("=sys-apps/portage-2.2*:foo[!-doc]", False), ("=sys-apps/portage-2.2*:foo[!-doc=]", False), ("=sys-apps/portage-2.2*:foo[!-doc?]", False), ("=sys-apps/portage-2.2*:foo[-doc?]", False), ("=sys-apps/portage-2.2*:foo[-doc=]", False), ("=sys-apps/portage-2.2*:foo[-doc!=]", False), ("=sys-apps/portage-2.2*:foo[-doc=]", False), ("=sys-apps/portage-2.2*:foo[bar][-baz][doc?][!build?]", False), ("=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?]", True), ("=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?,]", False), ("=sys-apps/portage-2.2*:foo[,bar,-baz,doc?,!build?]", False), ("=sys-apps/portage-2.2*:foo[bar,-baz][doc?,!build?]", False), ("=sys-apps/portage-2.2*:foo[bar][doc,build]", False), (">~cate-gory/foo-1.0", False), (">~category/foo-1.0", False), ("<~category/foo-1.0", False), ("###cat/foo-1.0", False), ("~sys-apps/portage", False), ("portage", False), ("=portage", False), (">=portage-2.1", False), ("~portage-2.1", False), ("=portage-2.1*", False), ("null/portage", True), ("null/portage*:0", False), (">=null/portage-2.1", True), (">=null/portage", False), (">null/portage", False), ("=null/portage*", False), ("=null/portage", False), ("~null/portage", False), ("<=null/portage", False), ("<null/portage", False), ("~null/portage-2.1", True), ("=null/portage-2.1*", True), ("null/portage-2.1*", False), ("app-doc/php-docs-20071125", False), ("app-doc/php-docs-20071125-r2", False), ("=foo/bar-1-r1-1-r1", False), ("foo/-z-1", False), # These are invalid because pkg name must not end in hyphen # followed by numbers ("=foo/bar-1-r1-1-r1", False), ("=foo/bar-123-1", False), ("=foo/bar-123-1*", False), ("foo/bar-123", False), ("=foo/bar-123-1-r1", False), ("=foo/bar-123-1-r1*", False), ("foo/bar-123-r1", False), ("foo/bar-1", False), ("=foo/bar--baz-1-r1", True), ("=foo/bar-baz--1-r1", True), ("=foo/bar-baz---1-r1", True), ("=foo/bar-baz---1", True), ("=foo/bar-baz-1--r1", False), ("games-strategy/ufo2000", True), ("~games-strategy/ufo2000-0.1", True), ("=media-libs/x264-20060810", True), ("foo/b", True), ("app-text/7plus", True), ("foo/666", True), ("=dev-libs/poppler-qt3-0.11*", True), ] for test in tests: if test[1]: atom_type = "valid" else: atom_type = "invalid" self.assertEqual(bool(isvalidatom(test[0])), test[1], msg="isvalidatom(%s) != %s" % (test[0], test[1]))
def testIsValidAtom(self): test_cases = ( IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("=sys-apps/portage-2.1", True), IsValidAtomTestCase("=sys-apps/portage-2.1*", True), IsValidAtomTestCase(">=sys-apps/portage-2.1", True), IsValidAtomTestCase("<=sys-apps/portage-2.1", True), IsValidAtomTestCase(">sys-apps/portage-2.1", True), IsValidAtomTestCase("<sys-apps/portage-2.1", True), IsValidAtomTestCase("~sys-apps/portage-2.1", True), IsValidAtomTestCase("sys-apps/portage:foo", True), IsValidAtomTestCase("sys-apps/portage-2.1:foo", False), IsValidAtomTestCase("sys-apps/portage-2.1:", False), IsValidAtomTestCase("sys-apps/portage-2.1:", False), IsValidAtomTestCase("sys-apps/portage-2.1:[foo]", False), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("sys-apps/portage", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[bar?,!baz?,!doc=,build=]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[doc?]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!doc?]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[doc=]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!doc=]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!doc]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!-doc]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!-doc=]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[!-doc?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc=]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc!=]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[-doc=]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[bar][-baz][doc?][!build?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?]", True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[bar,-baz,doc?,!build?,]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[,bar,-baz,doc?,!build?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[bar,-baz][doc?,!build?]", False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo[bar][doc,build]", False), IsValidAtomTestCase(">~cate-gory/foo-1.0", False), IsValidAtomTestCase(">~category/foo-1.0", False), IsValidAtomTestCase("<~category/foo-1.0", False), IsValidAtomTestCase("###cat/foo-1.0", False), IsValidAtomTestCase("~sys-apps/portage", False), IsValidAtomTestCase("portage", False), IsValidAtomTestCase("=portage", False), IsValidAtomTestCase(">=portage-2.1", False), IsValidAtomTestCase("~portage-2.1", False), IsValidAtomTestCase("=portage-2.1*", False), IsValidAtomTestCase("null/portage", True), IsValidAtomTestCase("null/portage*:0", False), IsValidAtomTestCase(">=null/portage-2.1", True), IsValidAtomTestCase(">=null/portage", False), IsValidAtomTestCase(">null/portage", False), IsValidAtomTestCase("=null/portage*", False), IsValidAtomTestCase("=null/portage", False), IsValidAtomTestCase("~null/portage", False), IsValidAtomTestCase("<=null/portage", False), IsValidAtomTestCase("<null/portage", False), IsValidAtomTestCase("~null/portage-2.1", True), IsValidAtomTestCase("=null/portage-2.1*", True), IsValidAtomTestCase("null/portage-2.1*", False), IsValidAtomTestCase("app-doc/php-docs-20071125", False), IsValidAtomTestCase("app-doc/php-docs-20071125-r2", False), IsValidAtomTestCase("=foo/bar-1-r1-1-r1", False), IsValidAtomTestCase("foo/-z-1", False), # These are invalid because pkg name must not end in hyphen # followed by numbers IsValidAtomTestCase("=foo/bar-1-r1-1-r1", False), IsValidAtomTestCase("=foo/bar-123-1", False), IsValidAtomTestCase("=foo/bar-123-1*", False), IsValidAtomTestCase("foo/bar-123", False), IsValidAtomTestCase("=foo/bar-123-1-r1", False), IsValidAtomTestCase("=foo/bar-123-1-r1*", False), IsValidAtomTestCase("foo/bar-123-r1", False), IsValidAtomTestCase("foo/bar-1", False), IsValidAtomTestCase("=foo/bar--baz-1-r1", True), IsValidAtomTestCase("=foo/bar-baz--1-r1", True), IsValidAtomTestCase("=foo/bar-baz---1-r1", True), IsValidAtomTestCase("=foo/bar-baz---1", True), IsValidAtomTestCase("=foo/bar-baz-1--r1", False), IsValidAtomTestCase("games-strategy/ufo2000", True), IsValidAtomTestCase("~games-strategy/ufo2000-0.1", True), IsValidAtomTestCase("=media-libs/x264-20060810", True), IsValidAtomTestCase("foo/b", True), IsValidAtomTestCase("app-text/7plus", True), IsValidAtomTestCase("foo/666", True), IsValidAtomTestCase("=dev-libs/poppler-qt3-0.11*", True), # Testing atoms with repositories IsValidAtomTestCase("sys-apps/portage::repo_123-name", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.1::repo", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.1*::repo", True, allow_repo=True), IsValidAtomTestCase("sys-apps/portage:foo::repo", True, allow_repo=True), IsValidAtomTestCase("sys-apps/portage-2.1:foo::repo", False, allow_repo=True), IsValidAtomTestCase("sys-apps/portage-2.1:::repo", False, allow_repo=True), IsValidAtomTestCase("sys-apps/portage-2.1:::repo[foo]", False, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[bar?,!baz?,!doc=,build=]", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[doc?]", True, allow_repo=True), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[!doc]", False, allow_repo=True), IsValidAtomTestCase("###cat/foo-1.0::repo", False, allow_repo=True), IsValidAtomTestCase("~sys-apps/portage::repo", False, allow_repo=True), IsValidAtomTestCase("portage::repo", False, allow_repo=True), IsValidAtomTestCase("=portage::repo", False, allow_repo=True), IsValidAtomTestCase("null/portage::repo", True, allow_repo=True), IsValidAtomTestCase("app-doc/php-docs-20071125::repo", False, allow_repo=True), IsValidAtomTestCase("=foo/bar-1-r1-1-r1::repo", False, allow_repo=True), IsValidAtomTestCase("sys-apps/portage::repo_123-name", False, allow_repo=False), IsValidAtomTestCase("=sys-apps/portage-2.1::repo", False, allow_repo=False), IsValidAtomTestCase("=sys-apps/portage-2.1*::repo", False, allow_repo=False), IsValidAtomTestCase("sys-apps/portage:foo::repo", False, allow_repo=False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[bar?,!baz?,!doc=,build=]", False, allow_repo=False), IsValidAtomTestCase("=sys-apps/portage-2.2*:foo::repo[doc?]", False, allow_repo=False), IsValidAtomTestCase("null/portage::repo", False, allow_repo=False), IsValidAtomTestCase("virtual/ffmpeg:0/53", True), IsValidAtomTestCase("virtual/ffmpeg:0/53=", True), IsValidAtomTestCase("virtual/ffmpeg:0/53*", False), IsValidAtomTestCase("virtual/ffmpeg:=", True), IsValidAtomTestCase("virtual/ffmpeg:0=", True), IsValidAtomTestCase("virtual/ffmpeg:*", True), IsValidAtomTestCase("virtual/ffmpeg:0*", False), IsValidAtomTestCase("virtual/ffmpeg:0", True), ) for test_case in test_cases: if test_case.expected: atom_type = "valid" else: atom_type = "invalid" self.assertEqual( bool( isvalidatom( test_case.atom, allow_wildcard=test_case.allow_wildcard, allow_repo=test_case.allow_repo ) ), test_case.expected, msg="isvalidatom(%s) != %s" % (test_case.atom, test_case.expected), )
def isValid(self): if fnmatch.fnmatch(self.format, '1.*'): return isvalidatom(self.atom, eapi='0') if fnmatch.fnmatch(self.format, '2.*'): return isvalidatom(self.atom, eapi='5') return isvalidatom(self.atom)
def isValid(self): if fnmatch.fnmatch(self.format, "1.*"): return isvalidatom(self.atom, eapi="0") if fnmatch.fnmatch(self.format, "2.*"): return isvalidatom(self.atom, eapi="5") return isvalidatom(self.atom)
def process(app, appname, portage, craft, indent): print("%sProcessing %s" % (indent, app)) ebuild = "%s-17.08.1.ebuild" % app qtdeps = [] frameworksdeps = [] kdeappsdeps = [] otherdeps = [] qtre = re.compile("\$\(add_qt_dep ([^)]+)\)") frameworksre = re.compile("\$\(add_frameworks_dep ([^)]+)\)") kdeappsre = re.compile("\$\(add_kdeapps_dep ([^)]+)\)") optionalre = re.compile("^[^\?]+\?") with open(os.path.join(portage, app, ebuild), 'r') as ebuildfile: allfile = ebuildfile.read() dependencies = re.search("DEPEND=\"[^\"]*\"", allfile) if dependencies: deplines = dependencies.group(0).split("\n") del deplines[0] # The first one is always spurious del deplines[-1] # The last one is always spurious for d in deplines: depline = d.strip() qtmatch = qtre.match(depline) frameworksmatch = frameworksre.match(depline) kdeappsmatch = kdeappsre.match(depline) if qtmatch: qtdeps.append(qtmatch.group(1)) elif frameworksmatch: frameworksdeps.append(frameworksmatch.group(1)) elif kdeappsmatch: appname = kdeappsmatch.group(1) with subprocess.Popen([ "find", os.path.join(craft, "kde", "applications"), "-name", appname ], stdout=subprocess.PIPE) as find: craftdep = find.stdout.read().decode("utf-8").strip() if len(craftdep) == 0: if not process(appname, appname, portage, craft, "%s\t" % indent): print("%sCould not add application %s, skipping" % (indent, appname)) return False kdeappsdeps.append(appname) elif optionalre.match(depline): print("%sOptional dep %s" % (indent, depline)) else: if portage_dep.isvalidatom(depline): packagename = portage_dep.dep_getkey(depline).split( "/")[1] # TODO be smart about these types of mappings if packagename == "eigen": packagename = "eigen3" with subprocess.Popen( ["find", craft, "-name", packagename], stdout=subprocess.PIPE) as find: craftdep = find.stdout.read().decode( "utf-8").strip() if len(craftdep) > 0: otherdeps.append(craftdep[len(craft):]) else: print("%sDependency %s not found, skipping" % (indent, packagename)) return False else: print("%sGarbage: %s" % (indent, depline)) fixedframeworks = [] for f in frameworksdeps: with subprocess.Popen(["find", craft, "-name", f], stdout=subprocess.PIPE) as find: fixedframeworks.append( find.stdout.read().decode("utf-8").strip()[len(craft):]) qtdepsstr = "\n".join([ " self.runtimeDependencies[\"libs/qt5/%s\"] = \"default\"" % q for q in qtdeps ]) frameworksdepsstr = "\n".join([ " self.runtimeDependencies[\"%s\"] = \"default\"" % f for f in fixedframeworks ]) kdeappsdepsstr = "\n".join([ " self.runtimeDependencies[\"kde/applications/%s\"] = \"default\"" % k for k in kdeappsdeps ]) otherdepsstr = "\n".join([ " self.runtimeDependencies[\"%s\"] = \"default\"" % o for o in otherdeps ]) recipe = template % { "appname": appname, "qtdeps": qtdepsstr, "frameworksdeps": frameworksdepsstr, "otherdeps": otherdepsstr } outdir = os.path.join(craft, "kde", "applications", app) os.mkdir(outdir) with open(os.path.join(outdir, "%s.py" % app), 'w') as out: out.write(recipe) return True