def getMinUpgrade(vulnerableList, unaffectedList, portdbapi, vardbapi, minimize=True): """ Checks if the systemstate is matching an atom in I{vulnerableList} and returns string describing the lowest version for the package that matches an atom in I{unaffectedList} and is greater than the currently installed version or None if the system is not affected. Both I{vulnerableList} and I{unaffectedList} should have the same base package. @type vulnerableList: List of Strings @param vulnerableList: atoms matching vulnerable package versions @type unaffectedList: List of Strings @param unaffectedList: atoms matching unaffected package versions @type portdbapi: portage.dbapi.porttree.portdbapi @param portdbapi: Ebuild repository @type vardbapi: portage.dbapi.vartree.vardbapi @param vardbapi: Installed package repository @type minimize: Boolean @param minimize: True for a least-change upgrade, False for emerge-like algorithm @rtype: String | None @return: the lowest unaffected version that is greater than the installed version. """ rValue = None v_installed = [] u_installed = [] for v in vulnerableList: v_installed += match(v, vardbapi) for u in unaffectedList: u_installed += match(u, vardbapi) install_unaffected = True for i in v_installed: if i not in u_installed: install_unaffected = False if install_unaffected: return rValue for u in unaffectedList: mylist = match(u, portdbapi, match_type="match-all") for c in mylist: i = best(v_installed) if vercmp(c.version, i.version) > 0 \ and (rValue == None \ or not match("="+rValue, portdbapi) \ or (minimize ^ (vercmp(c.version, rValue.version) > 0)) \ and match("="+c, portdbapi)) \ and portdbapi.aux_get(c, ["SLOT"]) == vardbapi.aux_get(best(v_installed), ["SLOT"]): rValue = c return rValue
def getMinUpgrade(vulnerableList, unaffectedList, portdbapi, vardbapi, minimize=True): """ Checks if the systemstate is matching an atom in I{vulnerableList} and returns string describing the lowest version for the package that matches an atom in I{unaffectedList} and is greater than the currently installed version or None if the system is not affected. Both I{vulnerableList} and I{unaffectedList} should have the same base package. @type vulnerableList: List of Strings @param vulnerableList: atoms matching vulnerable package versions @type unaffectedList: List of Strings @param unaffectedList: atoms matching unaffected package versions @type portdbapi: portage.dbapi.porttree.portdbapi @param portdbapi: Ebuild repository @type vardbapi: portage.dbapi.vartree.vardbapi @param vardbapi: Installed package repository @type minimize: Boolean @param minimize: True for a least-change upgrade, False for emerge-like algorithm @rtype: String | None @return: the lowest unaffected version that is greater than the installed version. """ rValue = None v_installed = [] u_installed = [] for v in vulnerableList: v_installed += match(v, vardbapi) for u in unaffectedList: u_installed += match(u, vardbapi) install_unaffected = True for i in v_installed: if i not in u_installed: install_unaffected = False if install_unaffected: return rValue for u in unaffectedList: mylist = match(u, portdbapi, match_type="match-all") for c in mylist: c_pv = catpkgsplit(c) i_pv = catpkgsplit(best(v_installed)) if pkgcmp(c_pv[1:], i_pv[1:]) > 0 \ and (rValue == None \ or not match("="+rValue, portdbapi) \ or (minimize ^ (pkgcmp(c_pv[1:], catpkgsplit(rValue)[1:]) > 0)) \ and match("="+c, portdbapi)) \ and portdbapi.aux_get(c, ["SLOT"]) == vardbapi.aux_get(best(v_installed), ["SLOT"]): rValue = c_pv[0]+"/"+c_pv[1]+"-"+c_pv[2] if c_pv[3] != "r0": # we don't like -r0 for display rValue += "-"+c_pv[3] return rValue
def getMinUpgrade(vulnerableList, unaffectedList, portdbapi, vardbapi, minimize=True): """ Checks if the systemstate is matching an atom in I{vulnerableList} and returns string describing the lowest version for the package that matches an atom in I{unaffectedList} and is greater than the currently installed version or None if the system is not affected. Both I{vulnerableList} and I{unaffectedList} should have the same base package. @type vulnerableList: List of Strings @param vulnerableList: atoms matching vulnerable package versions @type unaffectedList: List of Strings @param unaffectedList: atoms matching unaffected package versions @type portdbapi: portage.dbapi.porttree.portdbapi @param portdbapi: Ebuild repository @type vardbapi: portage.dbapi.vartree.vardbapi @param vardbapi: Installed package repository @type minimize: Boolean @param minimize: True for a least-change upgrade, False for emerge-like algorithm @rtype: String | None @return: the lowest unaffected version that is greater than the installed version. """ rValue = None v_installed = [] u_installed = [] for v in vulnerableList: v_installed += match(v, vardbapi) for u in unaffectedList: u_installed += match(u, vardbapi) install_unaffected = True for i in v_installed: if i not in u_installed: install_unaffected = False if install_unaffected: return rValue for u in unaffectedList: mylist = match(u, portdbapi, match_type="match-all") for c in mylist: i = best(v_installed) if vercmp(c.version, i.version) > 0 \ and (rValue == None \ or not match("="+rValue, portdbapi) \ or (minimize ^ (vercmp(c.version, rValue.version) > 0)) \ and match("="+c, portdbapi)) \ and portdbapi._pkg_str(c, None).slot == vardbapi._pkg_str(best(v_installed), None).slot: rValue = c return rValue
def _insert_slot(self, pkg, pkg_info, myinslotlist): """Adds slot info to the message @returns addl: formatted slot info @returns myoldbest: installed version list Modifies self.counters.downgrades, self.counters.upgrades, self.counters.binary """ addl = " " + pkg_info.fetch_symbol if not cpvequal(pkg.cpv, best([pkg.cpv] + [x.cpv for x in myinslotlist])): # Downgrade in slot addl += turquoise("U")+blue("D") if pkg_info.ordered: self.counters.downgrades += 1 if pkg.type_name == "binary": self.counters.binary += 1 else: # Update in slot addl += turquoise("U") + " " if pkg_info.ordered: self.counters.upgrades += 1 if pkg.type_name == "binary": self.counters.binary += 1 return addl
def _get_installed_best(self, pkg, pkg_info): """ we need to use "--emptrytree" testing here rather than "empty" param testing because "empty" param is used for -u, where you still *do* want to see when something is being upgraded. @param pkg: _emerge.Package.Package instance @param pkg_info: dictionay @rtype addl, myoldbest: list, myinslotlist: list Modifies self.counters.reinst, self.counters.new """ myoldbest = [] myinslotlist = None installed_versions = self.vardb.match_pkgs(pkg.cp) if self.vardb.cpv_exists(pkg.cpv): pkg_info.attr_display.replace = True installed_version = self.vardb.match_pkgs(pkg.cpv)[0] if not self.quiet_repo_display and installed_version.repo != pkg.repo: myoldbest = [installed_version] if pkg_info.ordered: if pkg_info.merge: self.counters.reinst += 1 # filter out old-style virtual matches elif installed_versions and \ installed_versions[0].cp == pkg.cp: myinslotlist = self.vardb.match_pkgs(pkg.slot_atom) # If this is the first install of a new-style virtual, we # need to filter out old-style virtual matches. if myinslotlist and \ myinslotlist[0].cp != pkg.cp: myinslotlist = None if myinslotlist: myoldbest = myinslotlist[:] if not cpvequal( pkg.cpv, best([pkg.cpv] + [x.cpv for x in myinslotlist])): # Downgrade in slot pkg_info.attr_display.new_version = True pkg_info.attr_display.downgrade = True if pkg_info.ordered: self.counters.downgrades += 1 else: # Update in slot pkg_info.attr_display.new_version = True if pkg_info.ordered: self.counters.upgrades += 1 else: myoldbest = installed_versions pkg_info.attr_display.new = True pkg_info.attr_display.new_slot = True if pkg_info.ordered: self.counters.newslot += 1 if self.conf.changelog: self.do_changelog(pkg, pkg_info) else: pkg_info.attr_display.new = True if pkg_info.ordered: self.counters.new += 1 return myoldbest, myinslotlist
def delete(pkgs, unmask, mask, dbapi): if not isinstance(unmask, UnmaskFile): unmask = UnmaskFile(unmask) for pkg in pkgs: matches = dbapi.xmatch('match-visible', pkg) if not matches: print('No packages match %s.' % pkg) continue while len(matches) > 0: bm = best(matches) try: (r, b) = find_cpv_match(unmask, bm, dbapi = dbapi) except ValueError: print('No mask for %s found.' % bm) else: print('Removing unmask for %s.' % bm) r.remove(b) # Feel free to remove an empty repository. if not r: unmask.remove(r) break matches.remove(bm) else: print("No '%s' suitable for un-unmasking found." % pkg) return (unmask, mask)
def _insert_slot(self, pkg, pkg_info, myinslotlist): """Adds slot info to the message @returns addl: formatted slot info @returns myoldbest: installed version list Modifies self.counters.downgrades, self.counters.upgrades, self.counters.binary """ addl = " " + pkg_info.fetch_symbol if not cpvequal(pkg.cpv, best([pkg.cpv] + [x.cpv for x in myinslotlist])): # Downgrade in slot addl += turquoise("U") + blue("D") if pkg_info.ordered: self.counters.downgrades += 1 if pkg.type_name == "binary": self.counters.binary += 1 else: # Update in slot addl += turquoise("U") + " " if pkg_info.ordered: self.counters.upgrades += 1 if pkg.type_name == "binary": self.counters.binary += 1 return addl
def _get_installed_best(self, pkg, pkg_info): """ we need to use "--emptrytree" testing here rather than "empty" param testing because "empty" param is used for -u, where you still *do* want to see when something is being upgraded. @param pkg: _emerge.Package.Package instance @param pkg_info: dictionay @rtype addl, myoldbest: list, myinslotlist: list Modifies self.counters.reinst, self.counters.new """ myoldbest = [] myinslotlist = None installed_versions = self.vardb.match_pkgs(pkg.cp) if self.vardb.cpv_exists(pkg.cpv): pkg_info.attr_display.replace = True installed_version = pkg_info.previous_pkg if installed_version.slot != pkg.slot or installed_version.sub_slot != pkg.sub_slot or \ not self.quiet_repo_display and installed_version.repo != pkg.repo: myoldbest = [installed_version] if pkg_info.ordered: if pkg_info.merge: self.counters.reinst += 1 # filter out old-style virtual matches elif installed_versions and \ installed_versions[0].cp == pkg.cp: myinslotlist = self.vardb.match_pkgs(pkg.slot_atom) # If this is the first install of a new-style virtual, we # need to filter out old-style virtual matches. if myinslotlist and \ myinslotlist[0].cp != pkg.cp: myinslotlist = None if myinslotlist: myoldbest = myinslotlist[:] if not cpvequal(pkg.cpv, best([pkg.cpv] + [x.cpv for x in myinslotlist])): # Downgrade in slot pkg_info.attr_display.new_version = True pkg_info.attr_display.downgrade = True if pkg_info.ordered: self.counters.downgrades += 1 else: # Update in slot pkg_info.attr_display.new_version = True if pkg_info.ordered: self.counters.upgrades += 1 else: myoldbest = installed_versions pkg_info.attr_display.new = True pkg_info.attr_display.new_slot = True if pkg_info.ordered: self.counters.newslot += 1 if self.conf.changelog: self.do_changelog(pkg, pkg_info) else: pkg_info.attr_display.new = True if pkg_info.ordered: self.counters.new += 1 return myoldbest, myinslotlist
def __call__(self, argv): """ @return: tuple of (stdout, stderr, returncode) """ # Python 3: # cmd, root, *args = argv cmd = argv[0] root = argv[1] args = argv[2:] warnings = [] warnings_str = '' db = self.get_db() eapi = self.settings.get('EAPI') root = normalize_path(root or os.sep).rstrip(os.sep) + os.sep if root not in db: return ('', '%s: Invalid ROOT: %s\n' % (cmd, root), 3) portdb = db[root]["porttree"].dbapi vardb = db[root]["vartree"].dbapi if cmd in ('best_version', 'has_version'): try: atom = Atom(args[0], allow_repo=False) except InvalidAtom: return ('', '%s: Invalid atom: %s\n' % (cmd, args[0]), 2) try: atom = Atom(args[0], allow_repo=False, eapi=eapi) except InvalidAtom as e: warnings.append("QA Notice: %s: %s" % (cmd, e)) use = self.settings.get('PORTAGE_BUILT_USE') if use is None: use = self.settings['PORTAGE_USE'] use = frozenset(use.split()) atom = atom.evaluate_conditionals(use) if warnings: warnings_str = self._elog('eqawarn', warnings) if cmd == 'has_version': if vardb.match(atom): returncode = 0 else: returncode = 1 return ('', warnings_str, returncode) elif cmd == 'best_version': m = best(vardb.match(atom)) return ('%s\n' % m, warnings_str, 0) else: return ('', 'Invalid command: %s\n' % cmd, 3)
def get_effective(self, k): if k not in self.effective_cache: pkgs = self.dbapi.xmatch('match-all', k) if pkgs: flags = self._aux_parse( self.dbapi.aux_get(best(pkgs), (self.aux_key, ))[0]) else: flags = () self.effective_cache[k] = frozenset(flags) return self.effective_cache[k]
def add(pkgs, unmask, mask, dbapi): if mask is None: mask = MaskFile(MaskMerge(dbapi)) elif isinstance(mask, MaskMerge): mask = MaskFile(mask) if not isinstance(unmask, UnmaskFile): unmask = UnmaskFile(unmask) for pkg in pkgs: matches = dbapi.xmatch('match-all', pkg) if not matches: print('No packages match %s.' % pkg) continue skipping = False while len(matches) > 0: bm = best(matches) ms = getmaskingstatus(bm) if skipping: if ms: print("(if you'd like to unmask the older version,\n pass <=%s instead)" % bm) break elif not ms: print('%s is visible, skipping the atom.' % bm) skipping = True elif ms != ['package.mask']: print('%s is masked by: %s; skipping.' % (bm, ', '.join(ms))) else: mr = getmaskingreason(bm).splitlines(True) if not mr[0].startswith('#'): raise AssertionError("getmaskingreason() didn't return a comment") try: (r, b) = find_cpv_match(mask, bm, mr, dbapi) except ValueError: print('Unable to find a matching mask for %s.' % bm) else: print('Unmasking %s.' % bm) try: ur = unmask[r.name] except KeyError: ur = unmask.MaskRepo(r.name) unmask.append(ur) ur.append(b) break matches.remove(bm) else: print("No '%s' suitable for unmasking found." % pkg) return (unmask, mask)
def _filter(self, atom): ebuild = best(self._metadatadb.match(atom)) if not ebuild: return False values, = self._metadatadb.aux_get(ebuild, [self._variable]) values = values.split() if self._includes and not self._includes.intersection(values): return False if self._excludes and self._excludes.intersection(values): return False return True
def __call__(self, argv): """ @returns: tuple of (stdout, stderr, returncode) """ cmd, root, atom_str = argv eapi = self.settings.get('EAPI') allow_repo = eapi_has_repo_deps(eapi) try: atom = Atom(atom_str, allow_repo=allow_repo) except InvalidAtom: return ('', 'invalid atom: %s\n' % atom_str, 2) warnings = [] try: atom = Atom(atom_str, allow_repo=allow_repo, eapi=eapi) except InvalidAtom as e: warnings.append(_unicode_decode("QA Notice: %s: %s") % (cmd, e)) use = self.settings.get('PORTAGE_BUILT_USE') if use is None: use = self.settings['PORTAGE_USE'] use = frozenset(use.split()) atom = atom.evaluate_conditionals(use) db = self._db if db is None: db = portage.db warnings_str = '' if warnings: warnings_str = self._elog('eqawarn', warnings) root = normalize_path(root).rstrip(os.path.sep) + os.path.sep if root not in db: return ('', 'invalid ROOT: %s\n' % root, 2) vardb = db[root]["vartree"].dbapi if cmd == 'has_version': if vardb.match(atom): returncode = 0 else: returncode = 1 return ('', warnings_str, returncode) elif cmd == 'best_version': m = best(vardb.match(atom)) return ('%s\n' % m, warnings_str, 0) else: return ('', 'invalid command: %s\n' % cmd, 2)
def __call__(self, argv): """ @returns: tuple of (stdout, stderr, returncode) """ # Note that $USE is passed via IPC in order to ensure that # we have the correct value for built/installed packages, # since the config class doesn't currently provide a way # to access built/installed $USE that would work in all # possible scenarios. cmd, root, atom, use = argv try: atom = Atom(atom) except InvalidAtom: return ('', 'invalid atom: %s\n' % atom, 2) use = frozenset(use.split()) atom = atom.evaluate_conditionals(use) db = self._db if db is None: db = portage.db root = normalize_path(root).rstrip(os.path.sep) + os.path.sep if root not in db: return ('', 'invalid ROOT: %s\n' % root, 2) vardb = db[root]["vartree"].dbapi if cmd == 'has_version': if vardb.match(atom): returncode = 0 else: returncode = 1 return ('', '', returncode) elif cmd == 'best_version': m = best(vardb.match(atom)) return ('%s\n' % m, '', 0) else: return ('', 'invalid command: %s\n' % cmd, 2)
def __call__(self, argv): """ @return: tuple of (stdout, stderr, returncode) """ # Python 3: # cmd, root, *args = argv cmd = argv[0] root = argv[1] args = argv[2:] warnings = [] warnings_str = '' db = self.get_db() eapi = self.settings.get('EAPI') root = normalize_path(root or os.sep).rstrip(os.sep) + os.sep if root not in db: return ('', '%s: Invalid ROOT: %s\n' % (cmd, root), 3) portdb = db[root]["porttree"].dbapi vardb = db[root]["vartree"].dbapi if cmd in ('best_version', 'has_version'): allow_repo = eapi_has_repo_deps(eapi) try: atom = Atom(args[0], allow_repo=allow_repo) except InvalidAtom: return ('', '%s: Invalid atom: %s\n' % (cmd, args[0]), 2) try: atom = Atom(args[0], allow_repo=allow_repo, eapi=eapi) except InvalidAtom as e: warnings.append("QA Notice: %s: %s" % (cmd, e)) use = self.settings.get('PORTAGE_BUILT_USE') if use is None: use = self.settings['PORTAGE_USE'] use = frozenset(use.split()) atom = atom.evaluate_conditionals(use) if warnings: warnings_str = self._elog('eqawarn', warnings) if cmd == 'has_version': if vardb.match(atom): returncode = 0 else: returncode = 1 return ('', warnings_str, returncode) elif cmd == 'best_version': m = best(vardb.match(atom)) return ('%s\n' % m, warnings_str, 0) elif cmd in ('master_repositories', 'repository_path', 'available_eclasses', 'eclass_path', 'license_path'): repo = _repo_name_re.match(args[0]) if repo is None: return ('', '%s: Invalid repository: %s\n' % (cmd, args[0]), 2) try: repo = portdb.repositories[args[0]] except KeyError: return ('', warnings_str, 1) if cmd == 'master_repositories': return ('%s\n' % ' '.join(x.name for x in repo.masters), warnings_str, 0) elif cmd == 'repository_path': return ('%s\n' % repo.location, warnings_str, 0) elif cmd == 'available_eclasses': return ('%s\n' % ' '.join(sorted(repo.eclass_db.eclasses)), warnings_str, 0) elif cmd == 'eclass_path': try: eclass = repo.eclass_db.eclasses[args[1]] except KeyError: return ('', warnings_str, 1) return ('%s\n' % eclass.location, warnings_str, 0) elif cmd == 'license_path': paths = reversed([ os.path.join(x.location, 'licenses', args[1]) for x in list(repo.masters) + [repo] ]) for path in paths: if os.path.exists(path): return ('%s\n' % path, warnings_str, 0) return ('', warnings_str, 1) else: return ('', 'Invalid command: %s\n' % cmd, 3)
def __call__(self, argv): """ @return: tuple of (stdout, stderr, returncode) """ # Python 3: # cmd, root, *args = argv cmd = argv[0] root = argv[1] args = argv[2:] warnings = [] warnings_str = '' db = self.get_db() eapi = self.settings.get('EAPI') root = normalize_path(root or os.sep).rstrip(os.sep) + os.sep if root not in db: return ('', '%s: Invalid ROOT: %s\n' % (cmd, root), 3) portdb = db[root]["porttree"].dbapi vardb = db[root]["vartree"].dbapi if cmd in ('best_version', 'has_version'): allow_repo = eapi_has_repo_deps(eapi) try: atom = Atom(args[0], allow_repo=allow_repo) except InvalidAtom: return ('', '%s: Invalid atom: %s\n' % (cmd, args[0]), 2) try: atom = Atom(args[0], allow_repo=allow_repo, eapi=eapi) except InvalidAtom as e: warnings.append("QA Notice: %s: %s" % (cmd, e)) use = self.settings.get('PORTAGE_BUILT_USE') if use is None: use = self.settings['PORTAGE_USE'] use = frozenset(use.split()) atom = atom.evaluate_conditionals(use) if warnings: warnings_str = self._elog('eqawarn', warnings) if cmd == 'has_version': if vardb.match(atom): returncode = 0 else: returncode = 1 return ('', warnings_str, returncode) elif cmd == 'best_version': m = best(vardb.match(atom)) return ('%s\n' % m, warnings_str, 0) elif cmd in ('master_repositories', 'repository_path', 'available_eclasses', 'eclass_path', 'license_path'): repo = _repo_name_re.match(args[0]) if repo is None: return ('', '%s: Invalid repository: %s\n' % (cmd, args[0]), 2) try: repo = portdb.repositories[args[0]] except KeyError: return ('', warnings_str, 1) if cmd == 'master_repositories': return ('%s\n' % ' '.join(x.name for x in repo.masters), warnings_str, 0) elif cmd == 'repository_path': return ('%s\n' % repo.location, warnings_str, 0) elif cmd == 'available_eclasses': return ('%s\n' % ' '.join(sorted(repo.eclass_db.eclasses)), warnings_str, 0) elif cmd == 'eclass_path': try: eclass = repo.eclass_db.eclasses[args[1]] except KeyError: return ('', warnings_str, 1) return ('%s\n' % eclass.location, warnings_str, 0) elif cmd == 'license_path': paths = reversed([os.path.join(x.location, 'licenses', args[1]) for x in list(repo.masters) + [repo]]) for path in paths: if os.path.exists(path): return ('%s\n' % path, warnings_str, 0) return ('', warnings_str, 1) else: return ('', 'Invalid command: %s\n' % cmd, 3)
def __call__(self, argv): """ @return: tuple of (stdout, stderr, returncode) """ # Python 3: # cmd, root, *args = argv cmd = argv[0] root = argv[1] args = argv[2:] warnings = [] warnings_str = "" db = self.get_db() eapi = self.settings.get("EAPI") root = normalize_path(root or os.sep).rstrip(os.sep) + os.sep if root not in db: return ("", "%s: Invalid ROOT: %s\n" % (cmd, root), 3) portdb = db[root]["porttree"].dbapi vardb = db[root]["vartree"].dbapi if cmd in ("best_version", "has_version"): allow_repo = eapi_has_repo_deps(eapi) try: atom = Atom(args[0], allow_repo=allow_repo) except InvalidAtom: return ("", "%s: Invalid atom: %s\n" % (cmd, args[0]), 2) try: atom = Atom(args[0], allow_repo=allow_repo, eapi=eapi) except InvalidAtom as e: warnings.append("QA Notice: %s: %s" % (cmd, e)) use = self.settings.get("PORTAGE_BUILT_USE") if use is None: use = self.settings["PORTAGE_USE"] use = frozenset(use.split()) atom = atom.evaluate_conditionals(use) if warnings: warnings_str = self._elog("eqawarn", warnings) if cmd == "has_version": if vardb.match(atom): returncode = 0 else: returncode = 1 return ("", warnings_str, returncode) if cmd == "best_version": m = best(vardb.match(atom)) return ("%s\n" % m, warnings_str, 0) if cmd in ( "master_repositories", "repository_path", "available_eclasses", "eclass_path", "license_path", ): repo = _repo_name_re.match(args[0]) if repo is None: return ("", "%s: Invalid repository: %s\n" % (cmd, args[0]), 2) try: repo = portdb.repositories[args[0]] except KeyError: return ("", warnings_str, 1) if cmd == "master_repositories": return ( "%s\n" % " ".join(x.name for x in repo.masters), warnings_str, 0, ) if cmd == "repository_path": return ("%s\n" % repo.location, warnings_str, 0) if cmd == "available_eclasses": return ( "%s\n" % " ".join(sorted(repo.eclass_db.eclasses)), warnings_str, 0, ) if cmd == "eclass_path": try: eclass = repo.eclass_db.eclasses[args[1]] except KeyError: return ("", warnings_str, 1) return ("%s\n" % eclass.location, warnings_str, 0) if cmd == "license_path": paths = reversed([ os.path.join(x.location, "licenses", args[1]) for x in list(repo.masters) + [repo] ]) for path in paths: if os.path.exists(path): return ("%s\n" % path, warnings_str, 0) return ("", warnings_str, 1) return ("", "Invalid command: %s\n" % cmd, 3)
def __call__(self, argv): """ @return: tuple of (stdout, stderr, returncode) """ # Python 3: # cmd, root, *args = argv cmd = argv[0] root = argv[1] args = argv[2:] warnings = [] warnings_str = "" db = self.get_db() eapi = self.settings.get("EAPI") root = normalize_path(root).rstrip(os.path.sep) + os.path.sep if root not in db: return ("", "%s: Invalid ROOT: %s\n" % (cmd, root), 3) portdb = db[root]["porttree"].dbapi vardb = db[root]["vartree"].dbapi if cmd in ("best_version", "has_version"): allow_repo = eapi_has_repo_deps(eapi) try: atom = Atom(args[0], allow_repo=allow_repo) except InvalidAtom: return ("", "%s: Invalid atom: %s\n" % (cmd, args[0]), 2) try: atom = Atom(args[0], allow_repo=allow_repo, eapi=eapi) except InvalidAtom as e: warnings.append(_unicode_decode("QA Notice: %s: %s") % (cmd, e)) use = self.settings.get("PORTAGE_BUILT_USE") if use is None: use = self.settings["PORTAGE_USE"] use = frozenset(use.split()) atom = atom.evaluate_conditionals(use) if warnings: warnings_str = self._elog("eqawarn", warnings) if cmd == "has_version": if vardb.match(atom): returncode = 0 else: returncode = 1 return ("", warnings_str, returncode) elif cmd == "best_version": m = best(vardb.match(atom)) return ("%s\n" % m, warnings_str, 0) elif cmd in ("master_repositories", "repository_path", "available_eclasses", "eclass_path", "license_path"): repo = _repo_name_re.match(args[0]) if repo is None: return ("", "%s: Invalid repository: %s\n" % (cmd, args[0]), 2) try: repo = portdb.repositories[args[0]] except KeyError: return ("", warnings_str, 1) if cmd == "master_repositories": return ("%s\n" % " ".join(x.name for x in repo.masters), warnings_str, 0) elif cmd == "repository_path": return ("%s\n" % repo.location, warnings_str, 0) elif cmd == "available_eclasses": return ("%s\n" % " ".join(sorted(repo.eclass_db.eclasses)), warnings_str, 0) elif cmd == "eclass_path": try: eclass = repo.eclass_db.eclasses[args[1]] except KeyError: return ("", warnings_str, 1) return ("%s\n" % eclass.location, warnings_str, 0) elif cmd == "license_path": paths = reversed([os.path.join(x.location, "licenses", args[1]) for x in list(repo.masters) + [repo]]) for path in paths: if os.path.exists(path): return ("%s\n" % path, warnings_str, 0) return ("", warnings_str, 1) else: return ("", "Invalid command: %s\n" % cmd, 3)