From 95cc5f51d17066b6abea5dccce9713878efd106d Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 10 Oct 2009 01:58:52 +0000 Subject: Fix _set module imports for rename, add hardcoded config for system and world, and remove unused sets code. svn path=/main/branches/2.1.7/; revision=14540 --- pym/_emerge/BlockerDB.py | 2 +- pym/_emerge/Scheduler.py | 4 +- pym/_emerge/SetArg.py | 2 +- pym/_emerge/actions.py | 4 +- pym/_emerge/depgraph.py | 4 +- pym/_emerge/main.py | 2 +- pym/_emerge/unmerge.py | 4 +- pym/portage/_sets/__init__.py | 18 +- pym/portage/_sets/dbapi.py | 306 ---------- pym/portage/_sets/files.py | 188 +----- pym/portage/_sets/profiles.py | 4 +- pym/portage/_sets/security.py | 87 --- pym/portage/_sets/shell.py | 45 -- pym/portage/glsa.py | 689 ---------------------- pym/portage/tests/sets/__init__.py | 0 pym/portage/tests/sets/files/__init__.py | 0 pym/portage/tests/sets/files/__test__ | 0 pym/portage/tests/sets/files/testConfigFileSet.py | 33 -- pym/portage/tests/sets/files/testStaticFileSet.py | 28 - pym/portage/tests/sets/shell/__init__.py | 0 pym/portage/tests/sets/shell/__test__ | 0 pym/portage/tests/sets/shell/testShell.py | 29 - 22 files changed, 31 insertions(+), 1418 deletions(-) delete mode 100644 pym/portage/_sets/dbapi.py delete mode 100644 pym/portage/_sets/security.py delete mode 100644 pym/portage/_sets/shell.py delete mode 100644 pym/portage/glsa.py delete mode 100644 pym/portage/tests/sets/__init__.py delete mode 100644 pym/portage/tests/sets/files/__init__.py delete mode 100644 pym/portage/tests/sets/files/__test__ delete mode 100644 pym/portage/tests/sets/files/testConfigFileSet.py delete mode 100644 pym/portage/tests/sets/files/testStaticFileSet.py delete mode 100644 pym/portage/tests/sets/shell/__init__.py delete mode 100644 pym/portage/tests/sets/shell/__test__ delete mode 100644 pym/portage/tests/sets/shell/testShell.py (limited to 'pym') diff --git a/pym/_emerge/BlockerDB.py b/pym/_emerge/BlockerDB.py index 8367ec651..ff1e525a2 100644 --- a/pym/_emerge/BlockerDB.py +++ b/pym/_emerge/BlockerDB.py @@ -7,7 +7,7 @@ import sys import portage from portage import os from portage import digraph -from portage.sets.base import InternalPackageSet +from portage._sets.base import InternalPackageSet from _emerge.BlockerCache import BlockerCache from _emerge.FakeVartree import FakeVartree diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py index f2247578b..0a9e87096 100644 --- a/pym/_emerge/Scheduler.py +++ b/pym/_emerge/Scheduler.py @@ -19,8 +19,8 @@ from portage.cache.mappings import slot_dict_class from portage.elog.messages import eerror from portage.output import colorize, create_color_func, darkgreen, red bad = create_color_func("BAD") -from portage.sets import SETPREFIX -from portage.sets.base import InternalPackageSet +from portage._sets import SETPREFIX +from portage._sets.base import InternalPackageSet from portage.util import writemsg, writemsg_level from _emerge.BinpkgPrefetcher import BinpkgPrefetcher diff --git a/pym/_emerge/SetArg.py b/pym/_emerge/SetArg.py index 987965dba..949bd6f7b 100644 --- a/pym/_emerge/SetArg.py +++ b/pym/_emerge/SetArg.py @@ -3,7 +3,7 @@ # $Id$ from _emerge.DependencyArg import DependencyArg -from portage.sets import SETPREFIX +from portage._sets import SETPREFIX class SetArg(DependencyArg): def __init__(self, set=None, **kwargs): DependencyArg.__init__(self, **kwargs) diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index eaf31b970..cb29dd1c9 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -30,8 +30,8 @@ from portage.output import blue, bold, colorize, create_color_func, darkgreen, \ red, yellow good = create_color_func("GOOD") bad = create_color_func("BAD") -from portage.sets import load_default_config, SETPREFIX -from portage.sets.base import InternalPackageSet +from portage._sets import load_default_config, SETPREFIX +from portage._sets.base import InternalPackageSet from portage.util import cmp_sort_key, writemsg, writemsg_level from _emerge.clear_caches import clear_caches diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 4a178a04e..9938a72c6 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -18,8 +18,8 @@ from portage.dep import Atom from portage.output import bold, blue, colorize, create_color_func, darkblue, \ darkgreen, green, nc_len, red, teal, turquoise, yellow bad = create_color_func("BAD") -from portage.sets import SETPREFIX -from portage.sets.base import InternalPackageSet +from portage._sets import SETPREFIX +from portage._sets.base import InternalPackageSet from portage.util import cmp_sort_key, writemsg, writemsg_stdout from portage.util import writemsg_level diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py index 22e00819b..40e0bcf2c 100644 --- a/pym/_emerge/main.py +++ b/pym/_emerge/main.py @@ -33,7 +33,7 @@ import portage.exception from portage.data import secpass from portage.util import normalize_path as normpath from portage.util import writemsg, writemsg_level, writemsg_stdout -from portage.sets import SETPREFIX +from portage._sets import SETPREFIX from _emerge.actions import action_config, action_sync, action_metadata, \ action_regen, action_search, action_uninstall, action_info, action_build, \ diff --git a/pym/_emerge/unmerge.py b/pym/_emerge/unmerge.py index 4d2a546c5..53699737e 100644 --- a/pym/_emerge/unmerge.py +++ b/pym/_emerge/unmerge.py @@ -10,7 +10,7 @@ import textwrap import portage from portage import os from portage.output import bold, colorize, darkgreen, green -from portage.sets import SETPREFIX +from portage._sets import SETPREFIX from portage.util import cmp_sort_key from _emerge.emergelog import emergelog @@ -281,7 +281,7 @@ def unmerge(root_config, myopts, unmerge_action, vartree.dbapi.flush_cache() portage.locks.unlockdir(vdb_lock) - from portage.sets.base import EditablePackageSet + from portage._sets.base import EditablePackageSet # generate a list of package sets that are directly or indirectly listed in "world", # as there is no persistent list of "installed" sets diff --git a/pym/portage/_sets/__init__.py b/pym/portage/_sets/__init__.py index 01ce66055..2298aef72 100644 --- a/pym/portage/_sets/__init__.py +++ b/pym/portage/_sets/__init__.py @@ -35,7 +35,19 @@ class SetConfigError(Exception): class SetConfig(object): def __init__(self, paths, settings, trees): self._parser = SafeConfigParser() - self._parser.read(paths) + #self._parser.read(paths) + # The "paths" argument is ignored and the config for + # system and world sets is hardcoded below. + parser = self._parser + + parser.add_section("system") + parser.set("system", "class", "portage._sets.profiles.PackagesSystemSet") + parser.set("system", "world-candidate", "False") + + parser.add_section("world") + parser.set("world", "class", "portage._sets.files.WorldSet") + parser.set("world", "world-candidate", "False") + self.errors = [] self.psets = {} self.trees = trees @@ -76,7 +88,7 @@ class SetConfig(object): for sname in parser.sections(): # find classname for current section, default to file based sets if not parser.has_option(sname, "class"): - classname = "portage.sets.files.StaticFileSet" + classname = "portage._sets.files.StaticFileSet" else: classname = parser.get(sname, "class") @@ -85,7 +97,7 @@ class SetConfig(object): setclass = load_mod(classname) except (ImportError, AttributeError): try: - setclass = load_mod("portage.sets."+classname) + setclass = load_mod("portage._sets."+classname) except (ImportError, AttributeError): self.errors.append(_("Could not import '%(class)s' for section " "'%(section)s'") % {"class": classname, "section": sname}) diff --git a/pym/portage/_sets/dbapi.py b/pym/portage/_sets/dbapi.py deleted file mode 100644 index f2e7dd110..000000000 --- a/pym/portage/_sets/dbapi.py +++ /dev/null @@ -1,306 +0,0 @@ -# Copyright 2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -import time - -from portage import os -from portage.versions import catpkgsplit, catsplit, pkgcmp, best -from portage.dep import Atom -from portage.localization import _ -from portage.sets.base import PackageSet -from portage.sets import SetConfigError, get_boolean -import portage - -__all__ = ["CategorySet", "DowngradeSet", - "EverythingSet", "OwnerSet", "VariableSet"] - -class EverythingSet(PackageSet): - _operations = ["merge"] - description = "Package set which contains SLOT " + \ - "atoms to match all installed packages" - _filter = None - - def __init__(self, vdbapi): - super(EverythingSet, self).__init__() - self._db = vdbapi - - def load(self): - myatoms = [] - db_keys = ["SLOT"] - aux_get = self._db.aux_get - cp_list = self._db.cp_list - - for cp in self._db.cp_all(): - cpv_list = cp_list(cp) - - if len(cpv_list) > 1: - for cpv in cpv_list: - slot, = aux_get(cpv, db_keys) - atom = Atom("%s:%s" % (cp, slot)) - if self._filter: - if self._filter(atom): - myatoms.append(atom) - else: - myatoms.append(atom) - - else: - atom = Atom(cp) - if self._filter: - if self._filter(atom): - myatoms.append(atom) - else: - myatoms.append(atom) - - self._setAtoms(myatoms) - - def singleBuilder(self, options, settings, trees): - return EverythingSet(trees["vartree"].dbapi) - singleBuilder = classmethod(singleBuilder) - -class OwnerSet(PackageSet): - - _operations = ["merge", "unmerge"] - - description = "Package set which contains all packages " + \ - "that own one or more files." - - def __init__(self, vardb=None, files=None): - super(OwnerSet, self).__init__() - self._db = vardb - self._files = files - - def mapPathsToAtoms(self, paths): - rValue = set() - vardb = self._db - aux_get = vardb.aux_get - aux_keys = ["SLOT"] - for link, p in vardb._owners.iter_owners(paths): - cat, pn = catpkgsplit(link.mycpv)[:2] - slot, = aux_get(link.mycpv, aux_keys) - rValue.add("%s/%s:%s" % (cat, pn, slot)) - return rValue - - def load(self): - self._setAtoms(self.mapPathsToAtoms(self._files)) - - def singleBuilder(cls, options, settings, trees): - if not "files" in options: - raise SetConfigError(_("no files given")) - - return cls(vardb=trees["vartree"].dbapi, - files=frozenset(portage.util.shlex_split(options["files"]))) - - singleBuilder = classmethod(singleBuilder) - -class VariableSet(EverythingSet): - - _operations = ["merge", "unmerge"] - - description = "Package set which contains all packages " + \ - "that match specified values of a specified variable." - - def __init__(self, vardb, metadatadb=None, variable=None, includes=None, excludes=None): - super(VariableSet, self).__init__(vardb) - self._metadatadb = metadatadb - self._variable = variable - self._includes = includes - self._excludes = excludes - - 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 singleBuilder(cls, options, settings, trees): - - variable = options.get("variable") - if variable is None: - raise SetConfigError(_("missing required attribute: 'variable'")) - - includes = options.get("includes", "") - excludes = options.get("excludes", "") - - if not (includes or excludes): - raise SetConfigError(_("no includes or excludes given")) - - metadatadb = options.get("metadata-source", "vartree") - if not metadatadb in trees: - raise SetConfigError(_("invalid value '%s' for option metadata-source") % metadatadb) - - return cls(trees["vartree"].dbapi, - metadatadb=trees[metadatadb].dbapi, - excludes=frozenset(excludes.split()), - includes=frozenset(includes.split()), - variable=variable) - - singleBuilder = classmethod(singleBuilder) - -class DowngradeSet(PackageSet): - - _operations = ["merge", "unmerge"] - - description = "Package set which contains all packages " + \ - "for which the highest visible ebuild version is lower than " + \ - "the currently installed version." - - def __init__(self, portdb=None, vardb=None): - super(DowngradeSet, self).__init__() - self._portdb = portdb - self._vardb = vardb - - def load(self): - atoms = [] - xmatch = self._portdb.xmatch - xmatch_level = "bestmatch-visible" - cp_list = self._vardb.cp_list - aux_get = self._vardb.aux_get - aux_keys = ["SLOT"] - for cp in self._vardb.cp_all(): - for cpv in cp_list(cp): - slot, = aux_get(cpv, aux_keys) - slot_atom = "%s:%s" % (cp, slot) - ebuild = xmatch(xmatch_level, slot_atom) - if not ebuild: - continue - ebuild_split = catpkgsplit(ebuild)[1:] - installed_split = catpkgsplit(cpv)[1:] - if pkgcmp(installed_split, ebuild_split) > 0: - atoms.append(slot_atom) - - self._setAtoms(atoms) - - def singleBuilder(cls, options, settings, trees): - return cls(portdb=trees["porttree"].dbapi, - vardb=trees["vartree"].dbapi) - - singleBuilder = classmethod(singleBuilder) - -class UnavailableSet(EverythingSet): - - _operations = ["unmerge"] - - description = "Package set which contains all installed " + \ - "packages for which there are no visible ebuilds " + \ - "corresponding to the same $CATEGORY/$PN:$SLOT." - - def __init__(self, vardb, metadatadb=None): - super(UnavailableSet, self).__init__(vardb) - self._metadatadb = metadatadb - - def _filter(self, atom): - return not self._metadatadb.match(atom) - - def singleBuilder(cls, options, settings, trees): - - metadatadb = options.get("metadata-source", "porttree") - if not metadatadb in trees: - raise SetConfigError(_("invalid value '%s' for option " - "metadata-source") % (metadatadb,)) - - return cls(trees["vartree"].dbapi, - metadatadb=trees[metadatadb].dbapi) - - singleBuilder = classmethod(singleBuilder) - -class CategorySet(PackageSet): - _operations = ["merge", "unmerge"] - - def __init__(self, category, dbapi, only_visible=True): - super(CategorySet, self).__init__() - self._db = dbapi - self._category = category - self._check = only_visible - if only_visible: - s="visible" - else: - s="all" - self.description = "Package set containing %s packages of category %s" % (s, self._category) - - def load(self): - myatoms = [] - for cp in self._db.cp_all(): - if catsplit(cp)[0] == self._category: - if (not self._check) or len(self._db.match(cp)) > 0: - myatoms.append(cp) - self._setAtoms(myatoms) - - def _builderGetVisible(cls, options): - return get_boolean(options, "only_visible", True) - _builderGetVisible = classmethod(_builderGetVisible) - - def singleBuilder(cls, options, settings, trees): - if not "category" in options: - raise SetConfigError(_("no category given")) - - category = options["category"] - if not category in settings.categories: - raise SetConfigError(_("invalid category name '%s'") % category) - - visible = cls._builderGetVisible(options) - - return CategorySet(category, dbapi=trees["porttree"].dbapi, only_visible=visible) - singleBuilder = classmethod(singleBuilder) - - def multiBuilder(cls, options, settings, trees): - rValue = {} - - if "categories" in options: - categories = options["categories"].split() - invalid = set(categories).difference(settings.categories) - if invalid: - raise SetConfigError(_("invalid categories: %s") % ", ".join(list(invalid))) - else: - categories = settings.categories - - visible = cls._builderGetVisible(options) - name_pattern = options.get("name_pattern", "$category/*") - - if not "$category" in name_pattern and not "${category}" in name_pattern: - raise SetConfigError(_("name_pattern doesn't include $category placeholder")) - - for cat in categories: - myset = CategorySet(cat, trees["porttree"].dbapi, only_visible=visible) - myname = name_pattern.replace("$category", cat) - myname = myname.replace("${category}", cat) - rValue[myname] = myset - return rValue - multiBuilder = classmethod(multiBuilder) - -class AgeSet(EverythingSet): - _operations = ["merge", "unmerge"] - - def __init__(self, vardb, mode="older", age=7): - super(AgeSet, self).__init__(vardb) - self._mode = mode - self._age = age - - def _filter(self, atom): - - cpv = self._db.match(atom)[0] - path = self._db.getpath(cpv, filename="COUNTER") - age = (time.time() - os.stat(path).st_mtime) / (3600 * 24) - if ((self._mode == "older" and age <= self._age) \ - or (self._mode == "newer" and age >= self._age)): - return False - else: - return True - - def singleBuilder(cls, options, settings, trees): - mode = options.get("mode", "older") - if str(mode).lower() not in ["newer", "older"]: - raise SetConfigError(_("invalid 'mode' value %s (use either 'newer' or 'older')") % mode) - try: - age = int(options.get("age", "7")) - except ValueError as e: - raise SetConfigError(_("value of option 'age' is not an integer")) - return AgeSet(vardb=trees["vartree"].dbapi, mode=mode, age=age) - - singleBuilder = classmethod(singleBuilder) diff --git a/pym/portage/_sets/files.py b/pym/portage/_sets/files.py index e8650becd..cfa744d21 100644 --- a/pym/portage/_sets/files.py +++ b/pym/portage/_sets/files.py @@ -15,195 +15,13 @@ from portage.const import USER_CONFIG_PATH, WORLD_FILE, WORLD_SETS_FILE from portage.localization import _ from portage.locks import lockfile, unlockfile from portage import portage_gid -from portage.sets.base import PackageSet, EditablePackageSet -from portage.sets import SetConfigError, SETPREFIX, get_boolean +from portage._sets.base import PackageSet, EditablePackageSet +from portage._sets import SetConfigError, SETPREFIX, get_boolean from portage.env.loaders import ItemFileLoader, KeyListFileLoader from portage.env.validators import ValidAtomValidator from portage import dep_getkey, cpv_getkey -__all__ = ["StaticFileSet", "ConfigFileSet", "WorldSet"] - -class StaticFileSet(EditablePackageSet): - _operations = ["merge", "unmerge"] - _repopath_match = re.compile(r'.*\$\{repository:(?P.+)\}.*') - _repopath_sub = re.compile(r'\$\{repository:(?P.+)\}') - - def __init__(self, filename, greedy=False, dbapi=None): - super(StaticFileSet, self).__init__() - self._filename = filename - self._mtime = None - self.description = "Package set loaded from file %s" % self._filename - self.loader = ItemFileLoader(self._filename, self._validate) - if greedy and not dbapi: - self.errors.append(_("%s configured as greedy set, but no dbapi instance passed in constructor") % self._filename) - greedy = False - self.greedy = greedy - self.dbapi = dbapi - - metadata = grabfile(self._filename + ".metadata") - key = None - value = [] - for line in metadata: - line = line.strip() - if len(line) == 0 and key != None: - setattr(self, key, " ".join(value)) - key = None - elif line[-1] == ":" and key == None: - key = line[:-1].lower() - value = [] - elif key != None: - value.append(line) - else: - pass - else: - if key != None: - setattr(self, key, " ".join(value)) - - def _validate(self, atom): - return bool(atom[:1] == SETPREFIX or ValidAtomValidator(atom)) - - def write(self): - write_atomic(self._filename, "".join("%s\n" % (atom,) \ - for atom in sorted(chain(self._atoms, self._nonatoms)))) - - def load(self): - try: - mtime = os.stat(self._filename).st_mtime - except (OSError, IOError): - mtime = None - if (not self._loaded or self._mtime != mtime): - try: - data, errors = self.loader.load() - for fname in errors: - for e in errors[fname]: - self.errors.append(fname+": "+e) - except EnvironmentError as e: - if e.errno != errno.ENOENT: - raise - del e - data = {} - if self.greedy: - atoms = [] - for a in data: - matches = self.dbapi.match(a) - for cpv in matches: - atoms.append("%s:%s" % (cpv_getkey(cpv), - self.dbapi.aux_get(cpv, ["SLOT"])[0])) - # In addition to any installed slots, also try to pull - # in the latest new slot that may be available. - atoms.append(a) - else: - atoms = iter(data) - self._setAtoms(atoms) - self._mtime = mtime - - def singleBuilder(self, options, settings, trees): - if not "filename" in options: - raise SetConfigError(_("no filename specified")) - greedy = get_boolean(options, "greedy", False) - filename = options["filename"] - # look for repository path variables - match = self._repopath_match.match(filename) - if match: - try: - filename = self._repopath_sub.sub(trees["porttree"].dbapi.treemap[match.groupdict()["reponame"]], filename) - except KeyError: - raise SetConfigError(_("Could not find repository '%s'") % match.groupdict()["reponame"]) - return StaticFileSet(filename, greedy=greedy, dbapi=trees["vartree"].dbapi) - singleBuilder = classmethod(singleBuilder) - - def multiBuilder(self, options, settings, trees): - rValue = {} - directory = options.get("directory", - os.path.join(settings["PORTAGE_CONFIGROOT"], - USER_CONFIG_PATH, "sets")) - name_pattern = options.get("name_pattern", "${name}") - if not "$name" in name_pattern and not "${name}" in name_pattern: - raise SetConfigError(_("name_pattern doesn't include ${name} placeholder")) - greedy = get_boolean(options, "greedy", False) - # look for repository path variables - match = self._repopath_match.match(directory) - if match: - try: - directory = self._repopath_sub.sub(trees["porttree"].dbapi.treemap[match.groupdict()["reponame"]], directory) - except KeyError: - raise SetConfigError(_("Could not find repository '%s'") % match.groupdict()["reponame"]) - - try: - directory = _unicode_decode(directory, - encoding=_encodings['fs'], errors='strict') - # Now verify that we can also encode it. - _unicode_encode(directory, - encoding=_encodings['fs'], errors='strict') - except UnicodeError: - directory = _unicode_decode(directory, - encoding=_encodings['fs'], errors='replace') - raise SetConfigError( - _("Directory path contains invalid character(s) for encoding '%s': '%s'") \ - % (_encodings['fs'], directory)) - - if os.path.isdir(directory): - directory = normalize_path(directory) - - for parent, dirs, files in os.walk(directory): - try: - parent = _unicode_decode(parent, - encoding=_encodings['fs'], errors='strict') - except UnicodeDecodeError: - continue - for d in dirs[:]: - if d[:1] == '.': - dirs.remove(d) - for filename in files: - try: - filename = _unicode_decode(filename, - encoding=_encodings['fs'], errors='strict') - except UnicodeDecodeError: - continue - if filename[:1] == '.': - continue - if filename.endswith(".metadata"): - continue - filename = os.path.join(parent, - filename)[1 + len(directory):] - myname = name_pattern.replace("$name", filename) - myname = myname.replace("${name}", filename) - rValue[myname] = StaticFileSet( - os.path.join(directory, filename), - greedy=greedy, dbapi=trees["vartree"].dbapi) - return rValue - multiBuilder = classmethod(multiBuilder) - -class ConfigFileSet(PackageSet): - def __init__(self, filename): - super(ConfigFileSet, self).__init__() - self._filename = filename - self.description = "Package set generated from %s" % self._filename - self.loader = KeyListFileLoader(self._filename, ValidAtomValidator) - - def load(self): - data, errors = self.loader.load() - self._setAtoms(iter(data)) - - def singleBuilder(self, options, settings, trees): - if not "filename" in options: - raise SetConfigError(_("no filename specified")) - return ConfigFileSet(options["filename"]) - singleBuilder = classmethod(singleBuilder) - - def multiBuilder(self, options, settings, trees): - rValue = {} - directory = options.get("directory", - os.path.join(settings["PORTAGE_CONFIGROOT"], USER_CONFIG_PATH)) - name_pattern = options.get("name_pattern", "sets/package_$suffix") - if not "$suffix" in name_pattern and not "${suffix}" in name_pattern: - raise SetConfigError(_("name_pattern doesn't include $suffix placeholder")) - for suffix in ["keywords", "use", "mask", "unmask"]: - myname = name_pattern.replace("$suffix", suffix) - myname = myname.replace("${suffix}", suffix) - rValue[myname] = ConfigFileSet(os.path.join(directory, "package."+suffix)) - return rValue - multiBuilder = classmethod(multiBuilder) +__all__ = ["WorldSet",] class WorldSet(EditablePackageSet): description = "Set of packages that were directly installed by the user" diff --git a/pym/portage/_sets/profiles.py b/pym/portage/_sets/profiles.py index da3a25e86..52261162d 100644 --- a/pym/portage/_sets/profiles.py +++ b/pym/portage/_sets/profiles.py @@ -6,8 +6,8 @@ import logging from portage import os from portage.util import grabfile_package, stack_lists -from portage.sets.base import PackageSet -from portage.sets import get_boolean +from portage._sets.base import PackageSet +from portage._sets import get_boolean from portage.util import writemsg_level __all__ = ["PackagesSystemSet"] diff --git a/pym/portage/_sets/security.py b/pym/portage/_sets/security.py deleted file mode 100644 index 115c0f3bd..000000000 --- a/pym/portage/_sets/security.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright 2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -import portage.glsa as glsa -from portage.sets.base import PackageSet -from portage.versions import catpkgsplit, pkgcmp -from portage.sets import get_boolean - -__all__ = ["SecuritySet", "NewGlsaSet", "NewAffectedSet", "AffectedSet"] - -class SecuritySet(PackageSet): - _operations = ["merge"] - _skip_applied = False - - description = "package set that includes all packages possibly affected by a GLSA" - - def __init__(self, settings, vardbapi, portdbapi, least_change=True): - super(SecuritySet, self).__init__() - self._settings = settings - self._vardbapi = vardbapi - self._portdbapi = portdbapi - self._least_change = least_change - - def getGlsaList(self, skip_applied): - glsaindexlist = glsa.get_glsa_list(self._settings) - if skip_applied: - applied_list = glsa.get_applied_glsas(self._settings) - glsaindexlist = set(glsaindexlist).difference(applied_list) - glsaindexlist = list(glsaindexlist) - glsaindexlist.sort() - return glsaindexlist - - def load(self): - glsaindexlist = self.getGlsaList(self._skip_applied) - atomlist = [] - for glsaid in glsaindexlist: - myglsa = glsa.Glsa(glsaid, self._settings, self._vardbapi, self._portdbapi) - #print glsaid, myglsa.isVulnerable(), myglsa.isApplied(), myglsa.getMergeList() - if self.useGlsa(myglsa): - atomlist += ["="+x for x in myglsa.getMergeList(least_change=self._least_change)] - self._setAtoms(self._reduce(atomlist)) - - def _reduce(self, atomlist): - mydict = {} - for atom in atomlist[:]: - cpv = self._portdbapi.xmatch("match-all", atom)[0] - slot = self._portdbapi.aux_get(cpv, ["SLOT"])[0] - cps = "/".join(catpkgsplit(cpv)[0:2]) + ":" + slot - if not cps in mydict: - mydict[cps] = (atom, cpv) - else: - other_cpv = mydict[cps][1] - if pkgcmp(catpkgsplit(cpv)[1:], catpkgsplit(other_cpv)[1:]) > 0: - atomlist.remove(mydict[cps][0]) - mydict[cps] = (atom, cpv) - return atomlist - - def useGlsa(self, myglsa): - return True - - def updateAppliedList(self): - glsaindexlist = self.getGlsaList(True) - applied_list = glsa.get_applied_glsas(self._settings) - for glsaid in glsaindexlist: - myglsa = glsa.Glsa(glsaid, self._settings, self._vardbapi, self._portdbapi) - if not myglsa.isVulnerable() and not myglsa.nr in applied_list: - myglsa.inject() - - def singleBuilder(cls, options, settings, trees): - least_change = not get_boolean(options, "use_emerge_resolver", False) - return cls(settings, trees["vartree"].dbapi, trees["porttree"].dbapi, least_change=least_change) - singleBuilder = classmethod(singleBuilder) - -class NewGlsaSet(SecuritySet): - _skip_applied = True - description = "Package set that includes all packages possibly affected by an unapplied GLSA" - -class AffectedSet(SecuritySet): - description = "Package set that includes all packages affected by an unapplied GLSA" - - def useGlsa(self, myglsa): - return myglsa.isVulnerable() - -class NewAffectedSet(AffectedSet): - _skip_applied = True - description = "Package set that includes all packages affected by an unapplied GLSA" diff --git a/pym/portage/_sets/shell.py b/pym/portage/_sets/shell.py deleted file mode 100644 index 658353ef2..000000000 --- a/pym/portage/_sets/shell.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -import subprocess - -from portage import os -from portage import _unicode_decode -from portage.sets.base import PackageSet -from portage.sets import SetConfigError - -__all__ = ["CommandOutputSet"] - -class CommandOutputSet(PackageSet): - """This class creates a PackageSet from the output of a shell command. - The shell command should produce one atom per line, that is: - - >>> atom1 - atom2 - ... - atomN - - Args: - name: A string that identifies the set. - command: A string or sequence identifying the command to run - (see the subprocess.Popen documentaion for the format) - """ - _operations = ["merge", "unmerge"] - - def __init__(self, command): - super(CommandOutputSet, self).__init__() - self._command = command - self.description = "Package set generated from output of '%s'" % self._command - - def load(self): - pipe = subprocess.Popen(self._command, stdout=subprocess.PIPE, shell=True) - stdout, stderr = pipe.communicate() - if pipe.wait() == os.EX_OK: - self._setAtoms(_unicode_decode(stdout).splitlines()) - - def singleBuilder(self, options, settings, trees): - if not "command" in options: - raise SetConfigError("no command specified") - return CommandOutputSet(options["command"]) - singleBuilder = classmethod(singleBuilder) diff --git a/pym/portage/glsa.py b/pym/portage/glsa.py deleted file mode 100644 index 4684ea420..000000000 --- a/pym/portage/glsa.py +++ /dev/null @@ -1,689 +0,0 @@ -# Copyright 2003-2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -import codecs -import sys -try: - from urllib.request import urlopen as urllib_request_urlopen -except ImportError: - from urllib import urlopen as urllib_request_urlopen -import re -import xml.dom.minidom - -from portage import os -from portage import _encodings -from portage import _unicode_decode -from portage import _unicode_encode -from portage.versions import pkgsplit, catpkgsplit, pkgcmp, best -from portage.util import grabfile -from portage.const import CACHE_PATH -from portage.localization import _ - -# Note: the space for rgt and rlt is important !! -# FIXME: use slot deps instead, requires GLSA format versioning -opMapping = {"le": "<=", "lt": "<", "eq": "=", "gt": ">", "ge": ">=", - "rge": ">=~", "rle": "<=~", "rgt": " >~", "rlt": " <~"} -NEWLINE_ESCAPE = "!;\\n" # some random string to mark newlines that should be preserved -SPACE_ESCAPE = "!;_" # some random string to mark spaces that should be preserved - -def get_applied_glsas(settings): - """ - Return a list of applied or injected GLSA IDs - - @type settings: portage.config - @param settings: portage config instance - @rtype: list - @return: list of glsa IDs - """ - return grabfile(os.path.join(os.sep, settings["ROOT"], CACHE_PATH, "glsa")) - - -# TODO: use the textwrap module instead -def wrap(text, width, caption=""): - """ - Wraps the given text at column I{width}, optionally indenting - it so that no text is under I{caption}. It's possible to encode - hard linebreaks in I{text} with L{NEWLINE_ESCAPE}. - - @type text: String - @param text: the text to be wrapped - @type width: Integer - @param width: the column at which the text should be wrapped - @type caption: String - @param caption: this string is inserted at the beginning of the - return value and the paragraph is indented up to - C{len(caption)}. - @rtype: String - @return: the wrapped and indented paragraph - """ - rValue = "" - line = caption - text = text.replace(2*NEWLINE_ESCAPE, NEWLINE_ESCAPE+" "+NEWLINE_ESCAPE) - words = text.split() - indentLevel = len(caption)+1 - - for w in words: - if line != "" and line[-1] == "\n": - rValue += line - line = " "*indentLevel - if len(line)+len(w.replace(NEWLINE_ESCAPE, ""))+1 > width: - rValue += line+"\n" - line = " "*indentLevel+w.replace(NEWLINE_ESCAPE, "\n") - elif w.find(NEWLINE_ESCAPE) >= 0: - if len(line.strip()) > 0: - rValue += line+" "+w.replace(NEWLINE_ESCAPE, "\n") - else: - rValue += line+w.replace(NEWLINE_ESCAPE, "\n") - line = " "*indentLevel - else: - if len(line.strip()) > 0: - line += " "+w - else: - line += w - if len(line) > 0: - rValue += line.replace(NEWLINE_ESCAPE, "\n") - rValue = rValue.replace(SPACE_ESCAPE, " ") - return rValue - -def get_glsa_list(myconfig): - """ - Returns a list of all available GLSAs in the given repository - by comparing the filelist there with the pattern described in - the config. - - @type myconfig: portage.config - @param myconfig: Portage settings instance - - @rtype: List of Strings - @return: a list of GLSA IDs in this repository - """ - rValue = [] - - if "GLSA_DIR" in myconfig: - repository = myconfig["GLSA_DIR"] - else: - repository = os.path.join(myconfig["PORTDIR"], "metadata", "glsa") - - if not os.access(repository, os.R_OK): - return [] - dirlist = os.listdir(repository) - prefix = "glsa-" - suffix = ".xml" - - for f in dirlist: - try: - if f[:len(prefix)] == prefix: - rValue.append(f[len(prefix):-1*len(suffix)]) - except IndexError: - pass - return rValue - -def getListElements(listnode): - """ - Get all
  • elements for a given
      or
        node. - - @type listnode: xml.dom.Node - @param listnode:
          or
            list to get the elements for - @rtype: List of Strings - @return: a list that contains the value of the
          1. elements - """ - rValue = [] - if not listnode.nodeName in ["ul", "ol"]: - raise GlsaFormatException("Invalid function call: listnode is not
              or
                ") - for li in listnode.childNodes: - if li.nodeType != xml.dom.Node.ELEMENT_NODE: - continue - rValue.append(getText(li, format="strip")) - return rValue - -def getText(node, format): - """ - This is the main parser function. It takes a node and traverses - recursive over the subnodes, getting the text of each (and the - I{link} attribute for and ). Depending on the I{format} - parameter the text might be formatted by adding/removing newlines, - tabs and spaces. This function is only useful for the GLSA DTD, - it's not applicable for other DTDs. - - @type node: xml.dom.Node - @param node: the root node to start with the parsing - @type format: String - @param format: this should be either I{strip}, I{keep} or I{xml} - I{keep} just gets the text and does no formatting. - I{strip} replaces newlines and tabs with spaces and - replaces multiple spaces with one space. - I{xml} does some more formatting, depending on the - type of the encountered nodes. - @rtype: String - @return: the (formatted) content of the node and its subnodes - """ - rValue = "" - if format in ["strip", "keep"]: - if node.nodeName in ["uri", "mail"]: - rValue += node.childNodes[0].data+": "+node.getAttribute("link") - else: - for subnode in node.childNodes: - if subnode.nodeName == "#text": - rValue += subnode.data - else: - rValue += getText(subnode, format) - else: - for subnode in node.childNodes: - if subnode.nodeName == "p": - for p_subnode in subnode.childNodes: - if p_subnode.nodeName == "#text": - rValue += p_subnode.data.strip() - elif p_subnode.nodeName in ["uri", "mail"]: - rValue += p_subnode.childNodes[0].data - rValue += " ( "+p_subnode.getAttribute("link")+" )" - rValue += NEWLINE_ESCAPE - elif subnode.nodeName == "ul": - for li in getListElements(subnode): - rValue += "-"+SPACE_ESCAPE+li+NEWLINE_ESCAPE+" " - elif subnode.nodeName == "ol": - i = 0 - for li in getListElements(subnode): - i = i+1 - rValue += str(i)+"."+SPACE_ESCAPE+li+NEWLINE_ESCAPE+" " - elif subnode.nodeName == "code": - rValue += getText(subnode, format="keep").replace("\n", NEWLINE_ESCAPE) - if rValue[-1*len(NEWLINE_ESCAPE):] != NEWLINE_ESCAPE: - rValue += NEWLINE_ESCAPE - elif subnode.nodeName == "#text": - rValue += subnode.data - else: - raise GlsaFormatException(_("Invalid Tag found: "), subnode.nodeName) - if format == "strip": - rValue = rValue.strip(" \n\t") - rValue = re.sub("[\s]{2,}", " ", rValue) - return rValue.encode("utf_8") - -def getMultiTagsText(rootnode, tagname, format): - """ - Returns a list with the text of all subnodes of type I{tagname} - under I{rootnode} (which itself is not parsed) using the given I{format}. - - @type rootnode: xml.dom.Node - @param rootnode: the node to search for I{tagname} - @type tagname: String - @param tagname: the name of the tags to search for - @type format: String - @param format: see L{getText} - @rtype: List of Strings - @return: a list containing the text of all I{tagname} childnodes - """ - rValue = [] - for e in rootnode.getElementsByTagName(tagname): - rValue.append(getText(e, format)) - return rValue - -def makeAtom(pkgname, versionNode): - """ - creates from the given package name and information in the - I{versionNode} a (syntactical) valid portage atom. - - @type pkgname: String - @param pkgname: the name of the package for this atom - @type versionNode: xml.dom.Node - @param versionNode: a or Node that - contains the version information for this atom - @rtype: String - @return: the portage atom - """ - rValue = opMapping[versionNode.getAttribute("range")] \ - + pkgname \ - + "-" + getText(versionNode, format="strip") - try: - slot = versionNode.getAttribute("slot").strip() - except KeyError: - pass - else: - if slot and slot != "*": - rValue += ":" + slot - return str(rValue) - -def makeVersion(versionNode): - """ - creates from the information in the I{versionNode} a - version string (format ). - - @type versionNode: xml.dom.Node - @param versionNode: a or Node that - contains the version information for this atom - @rtype: String - @return: the version string - """ - rValue = opMapping[versionNode.getAttribute("range")] \ - + getText(versionNode, format="strip") - try: - slot = versionNode.getAttribute("slot").strip() - except KeyError: - pass - else: - if slot and slot != "*": - rValue += ":" + slot - return rValue - -def match(atom, dbapi, match_type="default"): - """ - wrapper that calls revisionMatch() or portage.dbapi.match() depending on - the given atom. - - @type atom: string - @param atom: a <~ or >~ atom or a normal portage atom that contains the atom to match against - @type dbapi: portage.dbapi - @param dbapi: one of the portage databases to use as information source - @type match_type: string - @param match_type: if != "default" passed as first argument to dbapi.xmatch - to apply the wanted visibility filters - - @rtype: list of strings - @return: a list with the matching versions - """ - if atom[2] == "~": - return revisionMatch(atom, dbapi, match_type=match_type) - elif match_type == "default" or not hasattr(dbapi, "xmatch"): - return dbapi.match(atom) - else: - return dbapi.xmatch(match_type, atom) - -def revisionMatch(revisionAtom, dbapi, match_type="default"): - """ - handler for the special >~, >=~, <=~ and <~ atoms that are supposed to behave - as > and < except that they are limited to the same version, the range only - applies to the revision part. - - @type revisionAtom: string - @param revisionAtom: a <~ or >~ atom that contains the atom to match against - @type dbapi: portage.dbapi - @param dbapi: one of the portage databases to use as information source - @type match_type: string - @param match_type: if != "default" passed as first argument to portdb.xmatch - to apply the wanted visibility filters - - @rtype: list of strings - @return: a list with the matching versions - """ - if match_type == "default" or not hasattr(dbapi, "xmatch"): - if ":" in revisionAtom: - mylist = dbapi.match(re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:])) - else: - mylist = dbapi.match(re.sub("-r[0-9]+$", "", revisionAtom[2:])) - else: - if ":" in revisionAtom: - mylist = dbapi.xmatch(match_type, re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:])) - else: - mylist = dbapi.xmatch(match_type, re.sub("-r[0-9]+$", "", revisionAtom[2:])) - rValue = [] - for v in mylist: - r1 = pkgsplit(v)[-1][1:] - r2 = pkgsplit(revisionAtom[3:])[-1][1:] - if eval(r1+" "+revisionAtom[0:2]+" "+r2): - rValue.append(v) - 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 format_date(datestr): - """ - Takes a date (announced, revised) date from a GLSA and formats - it as readable text (i.e. "January 1, 2008"). - - @type date: String - @param date: the date string to reformat - @rtype: String - @return: a reformatted string, or the original string - if it cannot be reformatted. - """ - splitdate = datestr.split("-", 2) - if len(splitdate) != 3: - return datestr - - # This cannot raise an error as we use () instead of [] - splitdate = (int(x) for x in splitdate) - - from datetime import date - try: - d = date(*splitdate) - except ValueError: - return datestr - - # TODO We could format to local date format '%x' here? - return _unicode_decode(d.strftime("%B %d, %Y"), - encoding=_encodings['content'], errors='replace') - -# simple Exception classes to catch specific errors -class GlsaTypeException(Exception): - def __init__(self, doctype): - Exception.__init__(self, "wrong DOCTYPE: %s" % doctype) - -class GlsaFormatException(Exception): - pass - -class GlsaArgumentException(Exception): - pass - -# GLSA xml data wrapper class -class Glsa: - """ - This class is a wrapper for the XML data and provides methods to access - and display the contained data. - """ - def __init__(self, myid, myconfig, vardbapi, portdbapi): - """ - Simple constructor to set the ID, store the config and gets the - XML data by calling C{self.read()}. - - @type myid: String - @param myid: String describing the id for the GLSA object (standard - GLSAs have an ID of the form YYYYMM-nn) or an existing - filename containing a GLSA. - @type myconfig: portage.config - @param myconfig: the config that should be used for this object. - @type vardbapi: portage.dbapi.vartree.vardbapi - @param vardbapi: installed package repository - @type portdbapi: portage.dbapi.porttree.portdbapi - @param portdbapi: ebuild repository - """ - myid = _unicode_decode(myid, - encoding=_encodings['content'], errors='strict') - if re.match(r'\d{6}-\d{2}', myid): - self.type = "id" - elif os.path.exists(myid): - self.type = "file" - else: - raise GlsaArgumentException(_("Given ID %s isn't a valid GLSA ID or filename.") % myid) - self.nr = myid - self.config = myconfig - self.vardbapi = vardbapi - self.portdbapi = portdbapi - self.read() - - def read(self): - """ - Here we build the filename from the config and the ID and pass - it to urllib to fetch it from the filesystem or a remote server. - - @rtype: None - @return: None - """ - if "GLSA_DIR" in self.config: - repository = "file://" + self.config["GLSA_DIR"]+"/" - else: - repository = "file://" + self.config["PORTDIR"] + "/metadata/glsa/" - if self.type == "file": - myurl = "file://"+self.nr - else: - myurl = repository + "glsa-%s.xml" % str(self.nr) - self.parse(urllib_request_urlopen(myurl)) - return None - - def parse(self, myfile): - """ - This method parses the XML file and sets up the internal data - structures by calling the different helper functions in this - module. - - @type myfile: String - @param myfile: Filename to grab the XML data from - @rtype: None - @returns: None - """ - self.DOM = xml.dom.minidom.parse(myfile) - if not self.DOM.doctype: - raise GlsaTypeException(None) - elif self.DOM.doctype.systemId == "http://www.gentoo.org/dtd/glsa.dtd": - self.dtdversion = 0 - elif self.DOM.doctype.systemId == "http://www.gentoo.org/dtd/glsa-2.dtd": - self.dtdversion = 2 - else: - raise GlsaTypeException(self.DOM.doctype.systemId) - myroot = self.DOM.getElementsByTagName("glsa")[0] - if self.type == "id" and myroot.getAttribute("id") != self.nr: - raise GlsaFormatException(_("filename and internal id don't match:") + myroot.getAttribute("id") + " != " + self.nr) - - # the simple (single, required, top-level, #PCDATA) tags first - self.title = getText(myroot.getElementsByTagName("title")[0], format="strip") - self.synopsis = getText(myroot.getElementsByTagName("synopsis")[0], format="strip") - self.announced = format_date(getText(myroot.getElementsByTagName("announced")[0], format="strip")) - - count = 1 - # Support both formats of revised: - # December 30, 2007: 02 - # 2007-12-30 - revisedEl = myroot.getElementsByTagName("revised")[0] - self.revised = getText(revisedEl, format="strip") - if ((sys.hexversion >= 0x3000000 and "count" in revisedEl.attributes) or - (sys.hexversion < 0x3000000 and revisedEl.attributes.has_key("count"))): - count = revisedEl.getAttribute("count") - elif (self.revised.find(":") >= 0): - (self.revised, count) = self.revised.split(":") - - self.revised = format_date(self.revised) - - try: - self.count = int(count) - except ValueError: - # TODO should this raise a GlsaFormatException? - self.count = 1 - - # now the optional and 0-n toplevel, #PCDATA tags and references - try: - self.access = getText(myroot.getElementsByTagName("access")[0], format="strip") - except IndexError: - self.access = "" - self.bugs = getMultiTagsText(myroot, "bug", format="strip") - self.references = getMultiTagsText(myroot.getElementsByTagName("references")[0], "uri", format="keep") - - # and now the formatted text elements - self.description = getText(myroot.getElementsByTagName("description")[0], format="xml") - self.workaround = getText(myroot.getElementsByTagName("workaround")[0], format="xml") - self.resolution = getText(myroot.getElementsByTagName("resolution")[0], format="xml") - self.impact_text = getText(myroot.getElementsByTagName("impact")[0], format="xml") - self.impact_type = myroot.getElementsByTagName("impact")[0].getAttribute("type") - try: - self.background = getText(myroot.getElementsByTagName("background")[0], format="xml") - except IndexError: - self.background = "" - - # finally the interesting tags (product, affected, package) - self.glsatype = myroot.getElementsByTagName("product")[0].getAttribute("type") - self.product = getText(myroot.getElementsByTagName("product")[0], format="strip") - self.affected = myroot.getElementsByTagName("affected")[0] - self.packages = {} - for p in self.affected.getElementsByTagName("package"): - name = p.getAttribute("name") - if name not in self.packages: - self.packages[name] = [] - tmp = {} - tmp["arch"] = p.getAttribute("arch") - tmp["auto"] = (p.getAttribute("auto") == "yes") - tmp["vul_vers"] = [makeVersion(v) for v in p.getElementsByTagName("vulnerable")] - tmp["unaff_vers"] = [makeVersion(v) for v in p.getElementsByTagName("unaffected")] - tmp["vul_atoms"] = [makeAtom(name, v) for v in p.getElementsByTagName("vulnerable")] - tmp["unaff_atoms"] = [makeAtom(name, v) for v in p.getElementsByTagName("unaffected")] - self.packages[name].append(tmp) - # TODO: services aren't really used yet - self.services = self.affected.getElementsByTagName("service") - return None - - def dump(self, outstream=sys.stdout): - """ - Dumps a plaintext representation of this GLSA to I{outfile} or - B{stdout} if it is ommitted. You can specify an alternate - I{encoding} if needed (default is latin1). - - @type outstream: File - @param outfile: Stream that should be used for writing - (defaults to sys.stdout) - """ - width = 76 - outstream.write(("GLSA %s: \n%s" % (self.nr, self.title)).center(width)+"\n") - outstream.write((width*"=")+"\n") - outstream.write(wrap(self.synopsis, width, caption=_("Synopsis: "))+"\n") - outstream.write(_("Announced on: %s\n") % self.announced) - outstream.write(_("Last revised on: %s : %02d\n\n") % (self.revised, self.count)) - if self.glsatype == "ebuild": - for k in self.packages: - pkg = self.packages[k] - for path in pkg: - vul_vers = "".join(path["vul_vers"]) - unaff_vers = "".join(path["unaff_vers"]) - outstream.write(_("Affected package: %s\n") % k) - outstream.write(_("Affected archs: ")) - if path["arch"] == "*": - outstream.write(_("All\n")) - else: - outstream.write("%s\n" % path["arch"]) - outstream.write(_("Vulnerable: %s\n") % vul_vers) - outstream.write(_("Unaffected: %s\n\n") % unaff_vers) - elif self.glsatype == "infrastructure": - pass - if len(self.bugs) > 0: - outstream.write(_("\nRelated bugs: ")) - for i in range(0, len(self.bugs)): - outstream.write(self.bugs[i]) - if i < len(self.bugs)-1: - outstream.write(", ") - else: - outstream.write("\n") - if self.background: - outstream.write("\n"+wrap(self.background, width, caption=_("Background: "))) - outstream.write("\n"+wrap(self.description, width, caption=_("Description: "))) - outstream.write("\n"+wrap(self.impact_text, width, caption=_("Impact: "))) - outstream.write("\n"+wrap(self.workaround, width, caption=_("Workaround: "))) - outstream.write("\n"+wrap(self.resolution, width, caption=_("Resolution: "))) - myreferences = "" - for r in self.references: - myreferences += (r.replace(" ", SPACE_ESCAPE)+NEWLINE_ESCAPE+" ") - outstream.write("\n"+wrap(myreferences, width, caption=_("References: "))) - outstream.write("\n") - - def isVulnerable(self): - """ - Tests if the system is affected by this GLSA by checking if any - vulnerable package versions are installed. Also checks for affected - architectures. - - @rtype: Boolean - @returns: True if the system is affected, False if not - """ - rValue = False - for k in self.packages: - pkg = self.packages[k] - for path in pkg: - if path["arch"] == "*" or self.config["ARCH"] in path["arch"].split(): - for v in path["vul_atoms"]: - rValue = rValue \ - or (len(match(v, self.vardbapi)) > 0 \ - and getMinUpgrade(path["vul_atoms"], path["unaff_atoms"], \ - self.portdbapi, self.vardbapi)) - return rValue - - def isApplied(self): - """ - Looks if the GLSA IDis in the GLSA checkfile to check if this - GLSA was already applied. - - @rtype: Boolean - @returns: True if the GLSA was applied, False if not - """ - return (self.nr in get_applied_glsas(self.config)) - - def inject(self): - """ - Puts the ID of this GLSA into the GLSA checkfile, so it won't - show up on future checks. Should be called after a GLSA is - applied or on explicit user request. - - @rtype: None - @returns: None - """ - if not self.isApplied(): - checkfile = codecs.open( - _unicode_encode(os.path.join(os.sep, self.config["ROOT"], - CACHE_PATH, "glsa"), - encoding=_encodings['fs'], errors='strict'), - mode='a+', encoding=_encodings['content'], errors='strict') - checkfile.write(self.nr+"\n") - checkfile.close() - return None - - def getMergeList(self, least_change=True): - """ - Returns the list of package-versions that have to be merged to - apply this GLSA properly. The versions are as low as possible - while avoiding downgrades (see L{getMinUpgrade}). - - @type least_change: Boolean - @param least_change: True if the smallest possible upgrade should be selected, - False for an emerge-like algorithm - @rtype: List of Strings - @return: list of package-versions that have to be merged - """ - rValue = [] - for pkg in self.packages: - for path in self.packages[pkg]: - update = getMinUpgrade(path["vul_atoms"], path["unaff_atoms"], \ - self.portdbapi, self.vardbapi, minimize=least_change) - if update: - rValue.append(update) - return rValue diff --git a/pym/portage/tests/sets/__init__.py b/pym/portage/tests/sets/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/pym/portage/tests/sets/files/__init__.py b/pym/portage/tests/sets/files/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/pym/portage/tests/sets/files/__test__ b/pym/portage/tests/sets/files/__test__ deleted file mode 100644 index e69de29bb..000000000 diff --git a/pym/portage/tests/sets/files/testConfigFileSet.py b/pym/portage/tests/sets/files/testConfigFileSet.py deleted file mode 100644 index 95ea4f44a..000000000 --- a/pym/portage/tests/sets/files/testConfigFileSet.py +++ /dev/null @@ -1,33 +0,0 @@ -# testConfigFileSet.py -- Portage Unit Testing Functionality -# Copyright 2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -import tempfile - -from portage import os -from portage.tests import TestCase, test_cps -from portage.sets.files import ConfigFileSet - -class ConfigFileSetTestCase(TestCase): - """Simple Test Case for ConfigFileSet""" - - def setUp(self): - fd, self.testfile = tempfile.mkstemp(suffix=".testdata", prefix=self.__class__.__name__, text=True) - f = os.fdopen(fd, 'w') - for i in range(0, len(test_cps)): - atom = test_cps[i] - if i % 2 == 0: - f.write(atom + ' abc def\n') - else: - f.write(atom + '\n') - f.close() - - def tearDown(self): - os.unlink(self.testfile) - - def testConfigStaticFileSet(self): - s = ConfigFileSet(self.testfile) - s.load() - self.assertEqual(set(test_cps), s.getAtoms()) - diff --git a/pym/portage/tests/sets/files/testStaticFileSet.py b/pym/portage/tests/sets/files/testStaticFileSet.py deleted file mode 100644 index 138c99e5e..000000000 --- a/pym/portage/tests/sets/files/testStaticFileSet.py +++ /dev/null @@ -1,28 +0,0 @@ -# testStaticFileSet.py -- Portage Unit Testing Functionality -# Copyright 2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -import tempfile - -from portage import os -from portage.tests import TestCase, test_cps -from portage.sets.files import StaticFileSet - -class StaticFileSetTestCase(TestCase): - """Simple Test Case for StaticFileSet""" - - def setUp(self): - fd, self.testfile = tempfile.mkstemp(suffix=".testdata", prefix=self.__class__.__name__, text=True) - f = os.fdopen(fd, 'w') - f.write("\n".join(test_cps)) - f.close() - - def tearDown(self): - os.unlink(self.testfile) - - def testSampleStaticFileSet(self): - s = StaticFileSet(self.testfile) - s.load() - self.assertEqual(set(test_cps), s.getAtoms()) - diff --git a/pym/portage/tests/sets/shell/__init__.py b/pym/portage/tests/sets/shell/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/pym/portage/tests/sets/shell/__test__ b/pym/portage/tests/sets/shell/__test__ deleted file mode 100644 index e69de29bb..000000000 diff --git a/pym/portage/tests/sets/shell/testShell.py b/pym/portage/tests/sets/shell/testShell.py deleted file mode 100644 index 43d69599a..000000000 --- a/pym/portage/tests/sets/shell/testShell.py +++ /dev/null @@ -1,29 +0,0 @@ -# testCommandOututSet.py -- Portage Unit Testing Functionality -# Copyright 2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -from portage.process import find_binary -from portage.tests import TestCase, test_cps -from portage.sets.shell import CommandOutputSet - -class CommandOutputSetTestCase(TestCase): - """Simple Test Case for CommandOutputSet""" - - def setUp(self): - pass - - def tearDown(self): - pass - - def testCommand(self): - - input = set(test_cps) - command = find_binary("bash") - command += " -c '" - for a in input: - command += " echo -e \"%s\" ; " % a - command += "'" - s = CommandOutputSet(command) - atoms = s.getAtoms() - self.assertEqual(atoms, input) -- cgit v1.2.3-1-g7c22