summaryrefslogtreecommitdiff
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-10-10 01:58:52 +0000
committerZac Medico <zmedico@gentoo.org>2009-10-10 01:58:52 +0000
commit95cc5f51d17066b6abea5dccce9713878efd106d (patch)
tree97e60ca514c665fecf14f0989173f9ad5860d7ce /pym
parentMake the sets module private in this branch. (diff)
downloadportage-multirepo-95cc5f51d17066b6abea5dccce9713878efd106d.tar.gz
portage-multirepo-95cc5f51d17066b6abea5dccce9713878efd106d.tar.bz2
portage-multirepo-95cc5f51d17066b6abea5dccce9713878efd106d.zip
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
Diffstat (limited to 'pym')
-rw-r--r--pym/_emerge/BlockerDB.py2
-rw-r--r--pym/_emerge/Scheduler.py4
-rw-r--r--pym/_emerge/SetArg.py2
-rw-r--r--pym/_emerge/actions.py4
-rw-r--r--pym/_emerge/depgraph.py4
-rw-r--r--pym/_emerge/main.py2
-rw-r--r--pym/_emerge/unmerge.py4
-rw-r--r--pym/portage/_sets/__init__.py18
-rw-r--r--pym/portage/_sets/dbapi.py306
-rw-r--r--pym/portage/_sets/files.py188
-rw-r--r--pym/portage/_sets/profiles.py4
-rw-r--r--pym/portage/_sets/security.py87
-rw-r--r--pym/portage/_sets/shell.py45
-rw-r--r--pym/portage/glsa.py689
-rw-r--r--pym/portage/tests/sets/__init__.py0
-rw-r--r--pym/portage/tests/sets/files/__init__.py0
-rw-r--r--pym/portage/tests/sets/files/__test__0
-rw-r--r--pym/portage/tests/sets/files/testConfigFileSet.py33
-rw-r--r--pym/portage/tests/sets/files/testStaticFileSet.py28
-rw-r--r--pym/portage/tests/sets/shell/__init__.py0
-rw-r--r--pym/portage/tests/sets/shell/__test__0
-rw-r--r--pym/portage/tests/sets/shell/testShell.py29
22 files changed, 31 insertions, 1418 deletions
diff --git a/pym/_emerge/BlockerDB.py b/pym/_emerge/BlockerDB.py
index 8367ec65..ff1e525a 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 f2247578..0a9e8709 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 987965db..949bd6f7 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 eaf31b97..cb29dd1c 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 4a178a04..9938a72c 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 22e00819..40e0bcf2 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 4d2a546c..53699737 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 01ce6605..2298aef7 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 f2e7dd11..00000000
--- 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 e8650bec..cfa744d2 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<reponame>.+)\}.*')
- _repopath_sub = re.compile(r'\$\{repository:(?P<reponame>.+)\}')
-
- 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 da3a25e8..52261162 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 115c0f3b..00000000
--- 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 658353ef..00000000
--- 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 4684ea42..00000000
--- 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 <li> elements for a given <ol> or <ul> node.
-
- @type listnode: xml.dom.Node
- @param listnode: <ul> or <ol> list to get the elements for
- @rtype: List of Strings
- @return: a list that contains the value of the <li> elements
- """
- rValue = []
- if not listnode.nodeName in ["ul", "ol"]:
- raise GlsaFormatException("Invalid function call: listnode is not <ul> or <ol>")
- 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 <uri> and <mail>). 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 <vulnerable> or <unaffected> 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 <op><version>).
-
- @type versionNode: xml.dom.Node
- @param versionNode: a <vulnerable> or <unaffected> 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:
- # <revised>December 30, 2007: 02</revised>
- # <revised count="2">2007-12-30</revised>
- 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 e69de29b..00000000
--- a/pym/portage/tests/sets/__init__.py
+++ /dev/null
diff --git a/pym/portage/tests/sets/files/__init__.py b/pym/portage/tests/sets/files/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/pym/portage/tests/sets/files/__init__.py
+++ /dev/null
diff --git a/pym/portage/tests/sets/files/__test__ b/pym/portage/tests/sets/files/__test__
deleted file mode 100644
index e69de29b..00000000
--- a/pym/portage/tests/sets/files/__test__
+++ /dev/null
diff --git a/pym/portage/tests/sets/files/testConfigFileSet.py b/pym/portage/tests/sets/files/testConfigFileSet.py
deleted file mode 100644
index 95ea4f44..00000000
--- 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 138c99e5..00000000
--- 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 e69de29b..00000000
--- a/pym/portage/tests/sets/shell/__init__.py
+++ /dev/null
diff --git a/pym/portage/tests/sets/shell/__test__ b/pym/portage/tests/sets/shell/__test__
deleted file mode 100644
index e69de29b..00000000
--- a/pym/portage/tests/sets/shell/__test__
+++ /dev/null
diff --git a/pym/portage/tests/sets/shell/testShell.py b/pym/portage/tests/sets/shell/testShell.py
deleted file mode 100644
index 43d69599..00000000
--- 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)