summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Mauch <genone@gentoo.org>2007-07-16 12:35:32 +0000
committerMarius Mauch <genone@gentoo.org>2007-07-16 12:35:32 +0000
commitc94b9c585dc0b2433f18642b8ab02f28c4d0941a (patch)
tree260b667c701bf1526f0c96136fc5811d81cc5a24
parent4c16649d121dca977b3c569f03c5d1b194b635d4 (diff)
downloadportage-c94b9c585dc0b2433f18642b8ab02f28c4d0941a.tar.gz
portage-c94b9c585dc0b2433f18642b8ab02f28c4d0941a.tar.bz2
portage-c94b9c585dc0b2433f18642b8ab02f28c4d0941a.zip
replace emerge.AtomSet with portage.sets.InternalPackageSet
svn path=/main/trunk/; revision=7279
-rw-r--r--pym/emerge/__init__.py94
-rw-r--r--pym/portage/elog/mod_mail.py15
-rw-r--r--pym/portage/sets/__init__.py84
3 files changed, 104 insertions, 89 deletions
diff --git a/pym/emerge/__init__.py b/pym/emerge/__init__.py
index 541be2c15..ab9b683c6 100644
--- a/pym/emerge/__init__.py
+++ b/pym/emerge/__init__.py
@@ -52,6 +52,7 @@ import portage.exception
from portage.data import secpass
from portage.util import normalize_path as normpath
from portage.util import writemsg
+from portage.sets import InternalPackageSet
from itertools import chain, izip
from UserDict import DictMixin
@@ -566,7 +567,7 @@ def clean_world(vardb, cpv):
"""Remove a package from the world file when unmerged."""
world_set = WorldSet(vardb.settings)
world_set.lock()
- world_set.load()
+ world_set.xload()
worldlist = list(world_set)
mykey = portage.cpv_getkey(cpv)
newworldlist = []
@@ -591,74 +592,20 @@ def clean_world(vardb, cpv):
world_set.save()
world_set.unlock()
-class AtomSet(object):
- def __init__(self, atoms=None):
- self._atoms = {}
- if atoms:
- self.update(atoms)
- def clear(self):
- self._atoms.clear()
- def add(self, atom):
- cp = portage.dep_getkey(atom)
- cp_list = self._atoms.get(cp)
- if cp_list is None:
- cp_list = []
- self._atoms[cp] = cp_list
- if atom not in cp_list:
- cp_list.append(atom)
- def update(self, atoms):
- for atom in atoms:
- self.add(atom)
- def __contains__(self, atom):
- cp = portage.dep_getkey(atom)
- if cp in self._atoms and atom in self._atoms[cp]:
- return True
- return False
- def findAtomForPackage(self, cpv, metadata):
- """Return the best match for a given package from the arguments, or
- None if there are no matches. This matches virtual arguments against
- the PROVIDE metadata. This can raise an InvalidDependString exception
- if an error occurs while parsing PROVIDE."""
- cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
- cp = portage.dep_getkey(cpv)
- atoms = self._atoms.get(cp)
- if atoms:
- best_match = portage.best_match_to_list(cpv_slot, atoms)
- if best_match:
- return best_match
- if not metadata["PROVIDE"]:
- return None
- provides = portage.flatten(portage.dep.use_reduce(
- portage.dep.paren_reduce(metadata["PROVIDE"]),
- uselist=metadata["USE"].split()))
- for provide in provides:
- provided_cp = portage.dep_getkey(provide)
- atoms = self._atoms.get(provided_cp)
- if atoms:
- transformed_atoms = [atom.replace(provided_cp, cp) for atom in atoms]
- best_match = portage.best_match_to_list(cpv_slot, transformed_atoms)
- if best_match:
- return atoms[transformed_atoms.index(best_match)]
- return None
- def __iter__(self):
- for atoms in self._atoms.itervalues():
- for atom in atoms:
- yield atom
-
-class SystemSet(AtomSet):
+class SystemSet(InternalPackageSet):
def __init__(self, settings, **kwargs):
- AtomSet.__init__(self, **kwargs)
+ InternalPackageSet.__init__(self, **kwargs)
self.update(getlist(settings, "system"))
-class WorldSet(AtomSet):
+class WorldSet(InternalPackageSet):
def __init__(self, settings, **kwargs):
- AtomSet.__init__(self, **kwargs)
+ InternalPackageSet.__init__(self, **kwargs)
self.world_file = os.path.join(settings["ROOT"], portage.WORLD_FILE)
self._lock = None
def _ensure_dirs(self):
portage.util.ensure_dirs(os.path.dirname(self.world_file),
gid=portage.portage_gid, mode=02750, mask=02)
- def load(self):
+ def xload(self):
self.clear()
self.update(portage.util.grabfile_package(self.world_file))
def save(self):
@@ -681,7 +628,7 @@ class RootConfig(object):
self.root = self.settings["ROOT"]
self.sets = {}
world_set = WorldSet(self.settings)
- world_set.load()
+ world_set.xload()
self.sets["world"] = world_set
system_set = SystemSet(self.settings)
self.sets["system"] = system_set
@@ -1144,10 +1091,10 @@ class depgraph(object):
# contains all sets added to the graph
self._sets = {}
# contains atoms given as arguments
- self._sets["args"] = AtomSet()
+ self._sets["args"] = InternalPackageSet()
# contains all atoms from all sets added to the graph, including
# atoms given as arguments
- self._set_atoms = AtomSet()
+ self._set_atoms = InternalPackageSet()
# contains all nodes pulled in by self._set_atoms
self._set_nodes = set()
self.blocker_digraph = digraph()
@@ -2588,8 +2535,7 @@ class depgraph(object):
if verbosity is None:
verbosity = ("--quiet" in self.myopts and 1 or \
"--verbose" in self.myopts and 3 or 2)
- favorites_set = AtomSet()
- favorites_set.update(favorites)
+ favorites_set = InternalPackageSet(favorites)
changelogs=[]
p=[]
blockers = []
@@ -3069,10 +3015,10 @@ class depgraph(object):
pkg_system = False
pkg_world = False
try:
- pkg_system = system_set.findAtomForPackage(pkg_key, metadata)
- pkg_world = world_set.findAtomForPackage(pkg_key, metadata)
+ pkg_system = system_set.containsCPV(pkg_key)
+ pkg_world = world_set.containsCPV(pkg_key)
if not pkg_world and myroot == self.target_root and \
- favorites_set.findAtomForPackage(pkg_key, metadata):
+ favorites_set.containsCPV(pkg_key):
# Maybe it will be added to world now.
if create_world_atom(pkg_key, metadata,
favorites_set, root_config):
@@ -3278,7 +3224,7 @@ class depgraph(object):
root_config = self.roots[self.target_root]
world_set = root_config.sets["world"]
world_set.lock()
- world_set.load()
+ world_set.xload()
args_set = self._sets["args"]
portdb = self.trees[self.target_root]["porttree"].dbapi
added_favorites = set()
@@ -3537,7 +3483,7 @@ class MergeTask(object):
root_config = RootConfig(self.trees[self.target_root])
system_set = root_config.sets["system"]
- args_set = AtomSet(favorites)
+ args_set = InternalPackageSet(favorites)
world_set = root_config.sets["world"]
if "--resume" not in self.myopts:
mymergelist = mylist
@@ -3634,7 +3580,7 @@ class MergeTask(object):
#buildsyspkg: Check if we need to _force_ binary package creation
issyspkg = ("buildsyspkg" in myfeat) \
and x[0] != "blocks" \
- and system_set.findAtomForPackage(pkg_key, metadata) \
+ and system_set.containsCPV(pkg_key) \
and "--buildpkg" not in self.myopts
if x[0] in ["ebuild","blocks"]:
if x[0] == "blocks" and "--fetchonly" not in self.myopts:
@@ -3826,9 +3772,9 @@ class MergeTask(object):
self.trees[x[1]]["vartree"].inject(x[2])
myfavkey = portage.cpv_getkey(x[2])
if not fetchonly and not pretend and \
- args_set.findAtomForPackage(pkg_key, metadata):
+ args_set.containsCPV(pkg_key):
world_set.lock()
- world_set.load()
+ world_set.xload()
myfavkey = create_world_atom(pkg_key, metadata,
args_set, root_config)
if myfavkey:
@@ -5352,7 +5298,7 @@ def action_depclean(settings, trees, ldpath_mtimes,
system_set = SystemSet(settings)
syslist = list(system_set)
world_set = WorldSet(settings)
- world_set.load()
+ world_set.xload()
worldlist = list(world_set)
fakedb = portage.fakedbapi(settings=settings)
myvarlist = vardb.cpv_all()
diff --git a/pym/portage/elog/mod_mail.py b/pym/portage/elog/mod_mail.py
index d0d2b33ac..c9fa5b563 100644
--- a/pym/portage/elog/mod_mail.py
+++ b/pym/portage/elog/mod_mail.py
@@ -16,6 +16,21 @@ def process(mysettings, key, logentries, fulltext):
mysubject = mysubject.replace("${PACKAGE}", key)
mysubject = mysubject.replace("${HOST}", socket.getfqdn())
+ # look at the phases listed in our logentries to figure out what action was performed
+ action = "merged"
+ for phase in logentries.keys():
+ # if we found a *rm phase assume that the package was unmerged
+ if phase in ["postrm", "prerm"]:
+ action = "unmerged"
+ # if we think that the package was unmerged, make sure there was no unexpected
+ # phase recorded to avoid misinformation
+ if action == "unmerged":
+ for phase in logentries.keys():
+ if phase not in ["postrm", "prerm", "other"]:
+ action = "unknown"
+
+ mysubject = mysubject.replace("${ACTION}", action)
+
mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, fulltext)
portage.mail.send_mail(mysettings, mymessage)
diff --git a/pym/portage/sets/__init__.py b/pym/portage/sets/__init__.py
index e2087d816..a7428c092 100644
--- a/pym/portage/sets/__init__.py
+++ b/pym/portage/sets/__init__.py
@@ -6,7 +6,8 @@ import os
from portage.const import PRIVATE_PATH, USER_CONFIG_PATH
from portage.exception import InvalidAtom
-from portage.dep import isvalidatom, match_from_list, dep_getkey
+from portage.dep import isvalidatom, match_from_list, best_match_to_list, dep_getkey, use_reduce, paren_reduce
+from portage import flatten
OPERATIONS = ["merge", "unmerge"]
DEFAULT_SETS = ["world", "system", "everything", "security"] \
@@ -18,13 +19,22 @@ class PackageSet(object):
# package sets, the latter doesn't make sense for some sets like "system"
# or "security" and therefore isn't supported by them.
_operations = ["merge"]
+ _atommap = {}
description = "generic package set"
def __init__(self, name):
- self._name = name
+ self.name = name
self._atoms = set()
+ self._atommap = {}
self._loaded = False
+ def __contains__(self, atom):
+ return atom in self.getAtoms()
+
+ def __iter__(self):
+ for x in self.getAtoms():
+ yield x
+
def supportsOperation(self, op):
if not op in OPERATIONS:
raise ValueError(op)
@@ -44,10 +54,8 @@ class PackageSet(object):
elif not isvalidatom(a):
raise InvalidAtom(a)
self._atoms = atoms
-
- def getName(self):
- return self._name
-
+ self._updateAtomMap()
+
def load(self):
# This method must be overwritten by subclasses
# Editable sets should use the value of self._mtime to determine if they
@@ -56,7 +64,7 @@ class PackageSet(object):
def containsCPV(self, cpv):
for a in self.getAtoms():
- if match_from_list(a, cpv):
+ if match_from_list(a, [cpv]):
return True
return False
@@ -66,30 +74,69 @@ class PackageSet(object):
else:
return ""
+ def _updateAtomMap(self):
+ for a in self.getAtoms():
+ cp = dep_getkey(a)
+ self._atommap.setdefault(cp, set())
+ self._atommap[cp].add(a)
+
+ # Not sure if this one should really be in PackageSet
+ def findAtomForPackage(self, cpv, metadata):
+ """Return the best match for a given package from the arguments, or
+ None if there are no matches. This matches virtual arguments against
+ the PROVIDE metadata. This can raise an InvalidDependString exception
+ if an error occurs while parsing PROVIDE."""
+ cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
+ cp = dep_getkey(cpv)
+ atoms = self._atommap.get(cp)
+ if atoms:
+ best_match = best_match_to_list(cpv_slot, atoms)
+ if best_match:
+ return best_match
+ if not metadata["PROVIDE"]:
+ return None
+ provides = flatten(use_reduce(paren_reduce(metadata["PROVIDE"]),
+ uselist=metadata["USE"].split()))
+ for provide in provides:
+ provided_cp = dep_getkey(provide)
+ atoms = self._atommap.get(provided_cp)
+ if atoms:
+ atoms = list(atoms)
+ transformed_atoms = [atom.replace(provided_cp, cp) for atom in atoms]
+ best_match = best_match_to_list(cpv_slot, transformed_atoms)
+ if best_match:
+ return atoms[transformed_atoms.index(best_match)]
+ return None
class EditablePackageSet(PackageSet):
def getAtoms(self):
self.load()
return self._atoms
- def updateAtoms(self, atoms):
+ def update(self, atoms):
self.load()
self._atoms.update(atoms)
+ self._updateAtomMap()
self.write()
- def addAtom(self, atom):
- self.updateAtoms([atom])
+ def add(self, atom):
+ self.update([atom])
+
+ def replace(self, atoms):
+ self._setAtoms(atoms)
+ self.write()
- def removeAtom(self, atom):
+ def remove(self, atom):
self.load()
self._atoms.discard(atom)
+ self._updateAtomMap()
self.write()
def removePackageAtoms(self, cp):
self.load()
for a in self.getAtoms():
if dep_getkey(a) == cp:
- self._atoms.discard(a)
+ self.remove(a)
self.write()
def write(self):
@@ -98,7 +145,14 @@ class EditablePackageSet(PackageSet):
class InternalPackageSet(EditablePackageSet):
- _operations = ["merge", "unmerge"]
+ def __init__(self, initial_atoms=None):
+ super(InternalPackageSet, self).__init__("")
+ if initial_atoms != None:
+ self.update(initial_atoms)
+
+ def clear(self):
+ self._atoms.clear()
+ self._updateAtomMap()
def load(self):
pass
@@ -172,9 +226,9 @@ if __name__ == "__main__":
elif s != "*":
print "ERROR: could not create set '%s'" % s
if not "*" in sys.argv:
- l = [s for s in l if s.getName() in sys.argv[1:]]
+ l = [s for s in l if s.name in sys.argv[1:]]
for x in l:
- print x.getName()+":"
+ print x.name+":"
print "DESCRIPTION = %s" % x.getMetadata("Description")
for n in sorted(x.getAtoms()):
print "- "+n