Fix _set module imports for rename, add hardcoded config for system and world,
authorZac Medico <zmedico@gentoo.org>
Sat, 10 Oct 2009 01:58:52 +0000 (01:58 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 10 Oct 2009 01:58:52 +0000 (01:58 -0000)
and remove unused sets code.

svn path=/main/branches/2.1.7/; revision=14540

26 files changed:
bin/emaint
bin/glsa-check [deleted file]
bin/repoman
cnf/sets.conf [deleted file]
pym/_emerge/BlockerDB.py
pym/_emerge/Scheduler.py
pym/_emerge/SetArg.py
pym/_emerge/actions.py
pym/_emerge/depgraph.py
pym/_emerge/main.py
pym/_emerge/unmerge.py
pym/portage/_sets/__init__.py
pym/portage/_sets/dbapi.py [deleted file]
pym/portage/_sets/files.py
pym/portage/_sets/profiles.py
pym/portage/_sets/security.py [deleted file]
pym/portage/_sets/shell.py [deleted file]
pym/portage/glsa.py [deleted file]
pym/portage/tests/sets/__init__.py [deleted file]
pym/portage/tests/sets/files/__init__.py [deleted file]
pym/portage/tests/sets/files/__test__ [deleted file]
pym/portage/tests/sets/files/testConfigFileSet.py [deleted file]
pym/portage/tests/sets/files/testStaticFileSet.py [deleted file]
pym/portage/tests/sets/shell/__init__.py [deleted file]
pym/portage/tests/sets/shell/__test__ [deleted file]
pym/portage/tests/sets/shell/testShell.py [deleted file]

index 2626036e981734a612f1c273a073a2047c4e194d..e6d75c0a6506b79a78c7831420079066c908dc6e 100755 (executable)
@@ -32,7 +32,7 @@ class WorldHandler(object):
                self.not_installed = []
                self.invalid_category = []
                self.okay = []
-               from portage.sets import load_default_config
+               from portage._sets import load_default_config
                setconfig = load_default_config(portage.settings,
                        portage.db[portage.settings["ROOT"]])
                self._sets = setconfig.getSets()
@@ -44,7 +44,7 @@ class WorldHandler(object):
                self.found = os.access(self.world_file, os.R_OK)
                vardb = portage.db[myroot]["vartree"].dbapi
 
-               from portage.sets import SETPREFIX
+               from portage._sets import SETPREFIX
                sets = self._sets
                world_atoms = list(sets["world"])
                maxval = len(world_atoms)
diff --git a/bin/glsa-check b/bin/glsa-check
deleted file mode 100755 (executable)
index 19f451c..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-#!/usr/bin/python
-# Copyright 2008-2009 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Id$
-
-from __future__ import print_function
-
-import sys
-
-try:
-       import portage
-except ImportError:
-       from os import path as osp
-       sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
-       import portage
-
-from portage import os
-from portage.output import *
-
-from optparse import OptionGroup, OptionParser
-
-__program__ = "glsa-check"
-__author__ = "Marius Mauch <genone@gentoo.org>"
-__version__ = "1.0"
-
-def cb_version(*args, **kwargs):
-       """Callback for --version"""
-       sys.stderr.write("\n"+ __program__ + ", version " + __version__ + "\n")
-       sys.stderr.write("Author: " + __author__ + "\n")
-       sys.stderr.write("This program is licensed under the GPL, version 2\n\n")
-       sys.exit(0)
-
-# option parsing
-parser = OptionParser(usage="%prog <option> [glsa-list]",
-               version="%prog "+ __version__)
-parser.epilog = "glsa-list can contain an arbitrary number of GLSA ids," \
-               " filenames containing GLSAs or the special identifiers" \
-               " 'all', 'new' and 'affected'"
-
-modes = OptionGroup(parser, "Modes")
-modes.add_option("-l", "--list", action="store_const",
-               const="list", dest="mode",
-               help="List all unapplied GLSA")
-modes.add_option("-d", "--dump", action="store_const",
-               const="dump", dest="mode",
-               help="Show all information about the given GLSA")
-modes.add_option("", "--print", action="store_const",
-               const="dump", dest="mode",
-               help="Alias for --dump")
-modes.add_option("-t", "--test", action="store_const",
-               const="test", dest="mode",
-               help="Test if this system is affected by the given GLSA")
-modes.add_option("-p", "--pretend", action="store_const",
-               const="pretend", dest="mode",
-               help="Show the necessary commands to apply this GLSA")
-modes.add_option("-f", "--fix", action="store_const",
-               const="fix", dest="mode",
-               help="Try to auto-apply this GLSA (experimental)")
-modes.add_option("-i", "--inject", action="store_const", dest="mode",
-               help="Inject the given GLSA into the checkfile")
-modes.add_option("-m", "--mail", action="store_const",
-               const="mail", dest="mode",
-               help="Send a mail with the given GLSAs to the administrator")
-parser.add_option_group(modes)
-
-parser.remove_option("--version")
-parser.add_option("-V", "--version", action="callback",
-               callback=cb_version, help="Some information about this tool")
-parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
-               help="Print more information")
-parser.add_option("-n", "--nocolor", action="callback",
-               callback=lambda *args, **kwargs: nocolor(),
-               help="Disable colors")
-parser.add_option("-e", "--emergelike", action="store_false", dest="least_change",
-               help="Do not use a least-change algorithm")
-parser.add_option("-c", "--cve", action="store_true", dest="list_cve",
-               help="Show CAN ids in listing mode")
-
-options, params = parser.parse_args()
-
-mode = options.mode
-least_change = options.least_change
-list_cve = options.list_cve
-verbose = options.verbose
-
-# Sanity checking
-if mode is None:
-       sys.stderr.write("No mode given: what should I do?\n")
-       parser.print_help()
-       sys.exit(1)
-elif mode != "list" and not params:
-       sys.stderr.write("\nno GLSA given, so we'll do nothing for now. \n")
-       sys.stderr.write("If you want to run on all GLSA please tell me so \n")
-       sys.stderr.write("(specify \"all\" as parameter)\n\n")
-       parser.print_help()
-       sys.exit(1)
-elif mode in ["fix", "inject"] and os.geteuid() != 0:
-       # we need root priviledges for write access
-       sys.stderr.write("\nThis tool needs root access to "+options.mode+" this GLSA\n\n")
-       sys.exit(2)
-elif mode == "list" and not params:
-       params.append("new")
-
-# delay this for speed increase
-from portage.glsa import *
-
-vardb = portage.db[portage.settings["ROOT"]]["vartree"].dbapi
-portdb = portage.db["/"]["porttree"].dbapi
-
-# build glsa lists
-completelist = get_glsa_list(portage.settings)
-
-checklist = get_applied_glsas(portage.settings)
-todolist = [e for e in completelist if e not in checklist]
-
-glsalist = []
-if "new" in params:
-       glsalist = todolist
-       params.remove("new")
-       
-if "all" in params:
-       glsalist = completelist
-       params.remove("all")
-if "affected" in params:
-       # replaced completelist with todolist on request of wschlich
-       for x in todolist:
-               try:
-                       myglsa = Glsa(x, portage.settings, vardb, portdb)
-               except (GlsaTypeException, GlsaFormatException) as e:
-                       if verbose:
-                               sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (x, e)))
-                       continue
-               if myglsa.isVulnerable():
-                       glsalist.append(x)
-       params.remove("affected")
-
-# remove invalid parameters
-for p in params[:]:
-       if not (p in completelist or os.path.exists(p)):
-               sys.stderr.write(("(removing %s from parameter list as it isn't a valid GLSA specification)\n" % p))
-               params.remove(p)
-
-glsalist.extend([g for g in params if g not in glsalist])
-
-def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
-       fd2.write(white("[A]")+" means this GLSA was already applied,\n")
-       fd2.write(green("[U]")+" means the system is not affected and\n")
-       fd2.write(red("[N]")+" indicates that the system might be affected.\n\n")
-
-       myglsalist.sort()
-       for myid in myglsalist:
-               try:
-                       myglsa = Glsa(myid, portage.settings, vardb, portdb)
-               except (GlsaTypeException, GlsaFormatException) as e:
-                       if verbose:
-                               fd2.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
-                       continue
-               if myglsa.isApplied():
-                       status = "[A]"
-                       color = white
-               elif myglsa.isVulnerable():
-                       status = "[N]"
-                       color = red
-               else:
-                       status = "[U]"
-                       color = green
-
-               if verbose:
-                       access = ("[%-8s] " % myglsa.access)
-               else:
-                       access=""
-
-               fd1.write(color(myglsa.nr) + " " + color(status) + " " + color(access) + myglsa.title + " (")
-               if not verbose:
-                       for pkg in list(myglsa.packages)[:3]:
-                               fd1.write(" " + pkg + " ")
-                       if len(myglsa.packages) > 3:
-                               fd1.write("... ")
-               else:
-                       for pkg in myglsa.packages:
-                               mylist = vardb.match(portage.dep_getkey(str(pkg)))
-                               if len(mylist) > 0:
-                                       pkg = color(" ".join(mylist))
-                               fd1.write(" " + pkg + " ")
-
-               fd1.write(")")
-               if list_cve:
-                       fd1.write(" "+(",".join([r[:13] for r in myglsa.references if r[:4] in ["CAN-", "CVE-"]])))
-               fd1.write("\n")         
-       return 0
-
-if mode == "list":
-       sys.exit(summarylist(glsalist))
-
-# dump, fix, inject and fix are nearly the same code, only the glsa method call differs
-if mode in ["dump", "fix", "inject", "pretend"]:
-       for myid in glsalist:
-               try:
-                       myglsa = Glsa(myid, portage.settings, vardb, portdb)
-               except (GlsaTypeException, GlsaFormatException) as e:
-                       if verbose:
-                               sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
-                       continue
-               if mode == "dump":
-                       myglsa.dump()
-               elif mode == "fix":
-                       sys.stdout.write("fixing "+myid+"\n")
-                       mergelist = myglsa.getMergeList(least_change=least_change)
-                       for pkg in mergelist:
-                               sys.stdout.write(">>> merging "+pkg+"\n")
-                               # using emerge for the actual merging as it contains the dependency
-                               # code and we want to be consistent in behaviour. Also this functionality
-                               # will be integrated in emerge later, so it shouldn't hurt much.
-                               emergecmd = "emerge --oneshot " + portage.settings["EMERGE_OPTS"] + " =" + pkg
-                               if verbose:
-                                       sys.stderr.write(emergecmd+"\n")
-                               exitcode = os.system(emergecmd)
-                               # system() returns the exitcode in the high byte of a 16bit integer
-                               if exitcode >= 1<<8:
-                                       exitcode >>= 8
-                               if exitcode:
-                                       sys.exit(exitcode)
-                       myglsa.inject()
-               elif mode == "pretend":
-                       sys.stdout.write("Checking GLSA "+myid+"\n")
-                       mergelist = myglsa.getMergeList(least_change=least_change)
-                       if mergelist:
-                               sys.stdout.write("The following updates will be performed for this GLSA:\n")
-                               for pkg in mergelist:
-                                       oldver = None
-                                       for x in vardb.match(portage.dep_getkey(pkg)):
-                                               if vardb.aux_get(x, ["SLOT"]) == portdb.aux_get(pkg, ["SLOT"]):
-                                                       oldver = x
-                                       if oldver == None:
-                                               raise ValueError("could not find old version for package %s" % pkg)
-                                       oldver = oldver[len(portage.dep_getkey(oldver))+1:]
-                                       sys.stdout.write("     " + pkg + " (" + oldver + ")\n")
-                       else:
-                               sys.stdout.write("Nothing to do for this GLSA\n")
-               elif mode == "inject":
-                       sys.stdout.write("injecting " + myid + "\n")
-                       myglsa.inject()
-               sys.stdout.write("\n")
-       sys.exit(0)
-
-# test is a bit different as Glsa.test() produces no output
-if mode == "test":
-       outputlist = []
-       for myid in glsalist:
-               try:
-                       myglsa = Glsa(myid, portage.settings, vardb, portdb)
-               except (GlsaTypeException, GlsaFormatException) as e:
-                       if verbose:
-                               sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
-                       continue
-               if myglsa.isVulnerable():
-                       outputlist.append(str(myglsa.nr))
-       if len(outputlist) > 0:
-               sys.stderr.write("This system is affected by the following GLSAs:\n")
-               if verbose:
-                       summarylist(outputlist)
-               else:
-                       sys.stdout.write("\n".join(outputlist)+"\n")
-       else:
-               sys.stderr.write("This system is not affected by any of the listed GLSAs\n")
-       sys.exit(0)
-
-# mail mode as requested by solar
-if mode == "mail":
-       import portage.mail, socket
-       from io import StringIO
-       from email.mime.text import MIMEText
-       
-       # color doesn't make any sense for mail
-       nocolor()
-
-       if "PORTAGE_ELOG_MAILURI" in portage.settings:
-               myrecipient = portage.settings["PORTAGE_ELOG_MAILURI"].split()[0]
-       else:
-               myrecipient = "root@localhost"
-       
-       if "PORTAGE_ELOG_MAILFROM" in portage.settings:
-               myfrom = portage.settings["PORTAGE_ELOG_MAILFROM"]
-       else:
-               myfrom = "glsa-check"
-
-       mysubject = "[glsa-check] Summary for %s" % socket.getfqdn()
-
-       # need a file object for summarylist()
-       myfd = StringIO()
-       myfd.write("GLSA Summary report for host %s\n" % socket.getfqdn())
-       myfd.write("(Command was: %s)\n\n" % " ".join(sys.argv))
-       summarylist(glsalist, fd1=myfd, fd2=myfd)
-       summary = str(myfd.getvalue())
-       myfd.close()
-
-       myattachments = []
-       for myid in glsalist:
-               try:
-                       myglsa = Glsa(myid, portage.settings, vardb, portdb)
-               except (GlsaTypeException, GlsaFormatException) as e:
-                       if verbose:
-                               sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
-                       continue
-               myfd = StringIO()
-               myglsa.dump(outstream=myfd)
-               myattachments.append(MIMEText(str(myfd.getvalue()), _charset="utf8"))
-               myfd.close()
-               
-       mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, summary, myattachments)
-       portage.mail.send_mail(portage.settings, mymessage)
-               
-       sys.exit(0)
-       
-# something wrong here, all valid paths are covered with sys.exit()
-sys.stderr.write("nothing more to do\n")
-sys.exit(2)
index c764aed7f408a915763fe30dc8fa6ac9ea33a146..716a28334ea9be2d2a95f6be626966b096209e5f 100755 (executable)
@@ -55,7 +55,7 @@ except ImportError:
 
 from _emerge.Package import Package
 from _emerge.RootConfig import RootConfig
-from portage.sets import load_default_config
+from portage._sets import load_default_config
 
 import portage.checksum
 import portage.const
diff --git a/cnf/sets.conf b/cnf/sets.conf
deleted file mode 100644 (file)
index 79760a1..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-# WARNING: default set configuration, DO NOT CHANGE.
-# If you want to change anything redefine the relevant section in 
-# /etc/portage/sets.conf. Any changes to this file will be lost on the next 
-# portage update, and configuration errors here might upset portage in 
-# unexpected ways.
-
-# Not much that could be changed for world, so better leave it alone
-[world]
-class = portage.sets.files.WorldSet
-world-candidate = False
-
-# Same as for world, though later portage versions might use a different class
-[system]
-class = portage.sets.profiles.PackagesSystemSet
-world-candidate = False
-
-# For security there are multiple classes available, but differences are 
-# rather small (normally there should be no visible difference):
-# - AffectedSet: include all GLSAs that cover a vulnerable package
-# - NewAffectedSet: include all GLSAs that cover a vulnerable package and 
-#   haven't been applied previously
-# - NewGlsaSet: include all GLSAs that haven't been applied
-# - SecuritySet: include all GLSAs
-[security]
-class = portage.sets.security.NewAffectedSet
-world-candidate = False
-
-# A superset of the classic <parameter>world</parameter> target, a set created
-# by this class contains SLOT atoms to match all installed packages. Note that
-# use of this set makes it impossible for emerge to solve blockers by automatic
-# uninstallation of blocked packages.
-[installed]
-class = portage.sets.dbapi.EverythingSet
-world-candidate = False
-
-# The following treats all files in /etc/portage/sets as a package set called
-# '$filename'.
-[usersets]
-class = portage.sets.files.StaticFileSet
-multiset = true
-directory = /etc/portage/sets
-
-# Installed ebuilds that inherit from known live eclasses.
-[live-rebuild]
-class = portage.sets.dbapi.VariableSet
-world-candidate = False
-variable = INHERITED
-includes = bzr cvs darcs git mercurial subversion
-
-# Installed packages that own files inside /lib/modules.
-[module-rebuild]
-class = portage.sets.dbapi.OwnerSet
-world-candidate = False
-files = /lib/modules
-
-# Installed packages for which the highest visible ebuild
-# version is lower than the currently installed version.
-[downgrade]
-class = portage.sets.dbapi.DowngradeSet
-world-candidate = False
-
-# Installed packages for which there are no visible ebuilds
-# corresponding to the same $CATEGORY/$PN:$SLOT.
-[unavailable]
-class = portage.sets.dbapi.UnavailableSet
-world-candidate = False
index 8367ec6513a09e8f61b05f645f31d03006b4bca1..ff1e525a2fe352f6adaa76594d5974057424a129 100644 (file)
@@ -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
index f2247578b19faf8923e2f257608790e87f3a5daf..0a9e87096ad184a9342a4b5f2fc145768f96feea 100644 (file)
@@ -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
index 987965dbae0796eeae746d7ab0cdd7c8745306d0..949bd6f7bee94ee60301bf47d69544afbaee360a 100644 (file)
@@ -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)
index eaf31b9708bbedd4c056bb4e28ed3f7964a17091..cb29dd1c97883a08abc5056934d401d3eee263e5 100644 (file)
@@ -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
index 4a178a04e306089e5efae6f5031cf99e1a01b702..9938a72c6108318a1ead854a4a3f33f536ad42fa 100644 (file)
@@ -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
 
index 22e00819b1a7122db24cd74722312708cb7f2d36..40e0bcf2cfeeffd33a5b111aa34c489522fa8621 100644 (file)
@@ -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, \
index 4d2a546c5b2915bb8a3d8ace3916d6d2ab73280b..53699737e879d27bf5ac6d52aa9ad2afc50e0096 100644 (file)
@@ -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
index 01ce6605592151e1329ed11c02b20d061270e839..2298aef72488ff7da4359dcdb050fe1420ad2cec 100644 (file)
@@ -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 (file)
index f2e7dd1..0000000
+++ /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)
index e8650becdd3ce4d341d80b493921a50637f27bc4..cfa744d21f2f18b25b88f46b8087e2d4cc7f752f 100644 (file)
@@ -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"
index da3a25e866b0fd243d82eddb702bfac9b96b0c2f..52261162dbf14608d2802f342e6e93c6bc6e0ffb 100644 (file)
@@ -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 (file)
index 115c0f3..0000000
+++ /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 (file)
index 658353e..0000000
+++ /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 (file)
index 4684ea4..0000000
+++ /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 (file)
index e69de29..0000000
diff --git a/pym/portage/tests/sets/files/__init__.py b/pym/portage/tests/sets/files/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/pym/portage/tests/sets/files/__test__ b/pym/portage/tests/sets/files/__test__
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/pym/portage/tests/sets/files/testConfigFileSet.py b/pym/portage/tests/sets/files/testConfigFileSet.py
deleted file mode 100644 (file)
index 95ea4f4..0000000
+++ /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 (file)
index 138c99e..0000000
+++ /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 (file)
index e69de29..0000000
diff --git a/pym/portage/tests/sets/shell/__test__ b/pym/portage/tests/sets/shell/__test__
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/pym/portage/tests/sets/shell/testShell.py b/pym/portage/tests/sets/shell/testShell.py
deleted file mode 100644 (file)
index 43d6959..0000000
+++ /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)