From 3651d8a63350d5807df3e7cf8089dc88a3916f68 Mon Sep 17 00:00:00 2001 From: Marius Mauch Date: Tue, 23 Oct 2007 20:33:08 +0000 Subject: move base classes for package sets into a separate module svn path=/main/trunk/; revision=8257 --- pym/_emerge/__init__.py | 3 +- pym/portage/sets/__init__.py | 159 +----------------------------------------- pym/portage/sets/base.py | 160 +++++++++++++++++++++++++++++++++++++++++++ pym/portage/sets/dbapi.py | 3 +- pym/portage/sets/files.py | 3 +- pym/portage/sets/profiles.py | 2 +- pym/portage/sets/security.py | 2 +- pym/portage/sets/shell.py | 2 +- 8 files changed, 170 insertions(+), 164 deletions(-) create mode 100644 pym/portage/sets/base.py (limited to 'pym') diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 6f0f0a744..f337adfeb 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -52,8 +52,9 @@ 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, SetConfig, make_default_config +from portage.sets import SetConfig, make_default_config from portage.sets.profiles import PackagesSystemSet as SystemSet +from portage.sets.base import InternalPackageSet from portage.sets.files import WorldSet from itertools import chain, izip diff --git a/pym/portage/sets/__init__.py b/pym/portage/sets/__init__.py index 1698c20a7..1802e6741 100644 --- a/pym/portage/sets/__init__.py +++ b/pym/portage/sets/__init__.py @@ -4,169 +4,12 @@ import os from ConfigParser import SafeConfigParser, NoOptionError -from portage import flatten, load_mod -from portage.dep import isvalidatom, match_from_list, \ - best_match_to_list, dep_getkey, use_reduce, paren_reduce -from portage.exception import InvalidAtom +from portage import load_mod -OPERATIONS = ["merge", "unmerge"] DEFAULT_SETS = ["world", "system", "everything", "security"] \ +["package_"+x for x in ["mask", "unmask", "use", "keywords"]] del x -__all__ = ["PackageSet", "EditablePackageSet", "InternalPackageSet", \ - "SetConfigError", "SetConfig", "make_default_config"] - -class PackageSet(object): - # Set this to operations that are supported by your subclass. While - # technically there is no difference between "merge" and "unmerge" regarding - # package sets, the latter doesn't make sense for some sets like "system" - # or "security" and therefore isn't supported by them. - _operations = ["merge"] - description = "generic package set" - - def __init__(self): - self._atoms = set() - self._atommap = {} - self._loaded = False - self._loading = False - self.errors = [] - - 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) - return op in self._operations - - def getAtoms(self): - if not (self._loaded or self._loading): - self._loading = True - self.load() - self._loaded = True - self._loading = False - return self._atoms - - def _setAtoms(self, atoms): - atoms = map(str.strip, atoms) - for a in atoms[:]: - if a == "": - atoms.remove(a) - elif not isvalidatom(a): - raise InvalidAtom(a) - self._atoms = set(atoms) - 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 - # need to reload themselves - raise NotImplementedError() - - def containsCPV(self, cpv): - for a in self.getAtoms(): - if match_from_list(a, [cpv]): - return True - return False - - def getMetadata(self, key): - if hasattr(self, key.lower()): - return getattr(self, key.lower()) - else: - return "" - - def _updateAtomMap(self, atoms=None): - """Update self._atommap for specific atoms or all atoms.""" - if not atoms: - self._atommap.clear() - atoms = self._atoms - for a in atoms: - 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) - self.getAtoms() # make sure the atoms are loaded - 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 update(self, atoms): - self.getAtoms() - self._atoms.update(atoms) - self._updateAtomMap(atoms=atoms) - self.write() - - def add(self, atom): - self.update([atom]) - - def replace(self, atoms): - self._setAtoms(atoms) - self.write() - - def remove(self, atom): - self.getAtoms() - self._atoms.discard(atom) - self._updateAtomMap() - self.write() - - def removePackageAtoms(self, cp): - for a in list(self.getAtoms()): - if dep_getkey(a) == cp: - self.remove(a) - self.write() - - def write(self): - # This method must be overwritten in subclasses that should be editable - raise NotImplementedError() - -class InternalPackageSet(EditablePackageSet): - 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 - - def write(self): - pass - - class SetConfigError(Exception): pass diff --git a/pym/portage/sets/base.py b/pym/portage/sets/base.py new file mode 100644 index 000000000..b5ea88928 --- /dev/null +++ b/pym/portage/sets/base.py @@ -0,0 +1,160 @@ +# Copyright 2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +from portage import flatten +from portage.dep import isvalidatom, match_from_list, \ + best_match_to_list, dep_getkey, use_reduce, paren_reduce +from portage.exception import InvalidAtom + +OPERATIONS = ["merge", "unmerge"] + +class PackageSet(object): + # Set this to operations that are supported by your subclass. While + # technically there is no difference between "merge" and "unmerge" regarding + # package sets, the latter doesn't make sense for some sets like "system" + # or "security" and therefore isn't supported by them. + _operations = ["merge"] + description = "generic package set" + + def __init__(self): + self._atoms = set() + self._atommap = {} + self._loaded = False + self._loading = False + self.errors = [] + + 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) + return op in self._operations + + def getAtoms(self): + if not (self._loaded or self._loading): + self._loading = True + self.load() + self._loaded = True + self._loading = False + return self._atoms + + def _setAtoms(self, atoms): + atoms = map(str.strip, atoms) + for a in atoms[:]: + if a == "": + atoms.remove(a) + elif not isvalidatom(a): + raise InvalidAtom(a) + self._atoms = set(atoms) + 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 + # need to reload themselves + raise NotImplementedError() + + def containsCPV(self, cpv): + for a in self.getAtoms(): + if match_from_list(a, [cpv]): + return True + return False + + def getMetadata(self, key): + if hasattr(self, key.lower()): + return getattr(self, key.lower()) + else: + return "" + + def _updateAtomMap(self, atoms=None): + """Update self._atommap for specific atoms or all atoms.""" + if not atoms: + self._atommap.clear() + atoms = self._atoms + for a in atoms: + 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) + self.getAtoms() # make sure the atoms are loaded + 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 update(self, atoms): + self.getAtoms() + self._atoms.update(atoms) + self._updateAtomMap(atoms=atoms) + self.write() + + def add(self, atom): + self.update([atom]) + + def replace(self, atoms): + self._setAtoms(atoms) + self.write() + + def remove(self, atom): + self.getAtoms() + self._atoms.discard(atom) + self._updateAtomMap() + self.write() + + def removePackageAtoms(self, cp): + for a in list(self.getAtoms()): + if dep_getkey(a) == cp: + self.remove(a) + self.write() + + def write(self): + # This method must be overwritten in subclasses that should be editable + raise NotImplementedError() + +class InternalPackageSet(EditablePackageSet): + 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 + + def write(self): + pass + diff --git a/pym/portage/sets/dbapi.py b/pym/portage/sets/dbapi.py index 491a6d4c4..ca481705d 100644 --- a/pym/portage/sets/dbapi.py +++ b/pym/portage/sets/dbapi.py @@ -3,7 +3,8 @@ # $Id$ from portage.versions import catsplit, catpkgsplit -from portage.sets import PackageSet, SetConfigError +from portage.sets.base import PackageSet +from portage.sets import SetConfigError from portage.dbapi.vartree import dblink from portage.util import grabfile diff --git a/pym/portage/sets/files.py b/pym/portage/sets/files.py index 788dead85..55b5714c3 100644 --- a/pym/portage/sets/files.py +++ b/pym/portage/sets/files.py @@ -9,7 +9,8 @@ from portage.util import grabfile, write_atomic, ensure_dirs from portage.const import PRIVATE_PATH, USER_CONFIG_PATH from portage.locks import lockfile, unlockfile from portage import portage_gid -from portage.sets import PackageSet, EditablePackageSet, SetConfigError +from portage.sets.base import PackageSet, EditablePackageSet +from portage.sets import SetConfigError from portage.env.loaders import ItemFileLoader, KeyListFileLoader from portage.env.validators import ValidAtomValidator from portage import dep_getkey, cpv_getkey diff --git a/pym/portage/sets/profiles.py b/pym/portage/sets/profiles.py index 379fb06ec..b7555c7a5 100644 --- a/pym/portage/sets/profiles.py +++ b/pym/portage/sets/profiles.py @@ -4,7 +4,7 @@ import os from portage.util import grabfile_package, stack_lists -from portage.sets import PackageSet +from portage.sets.base import PackageSet __all__ = ["PackagesSystemSet"] diff --git a/pym/portage/sets/security.py b/pym/portage/sets/security.py index e2d595698..ff55ea508 100644 --- a/pym/portage/sets/security.py +++ b/pym/portage/sets/security.py @@ -6,7 +6,7 @@ import os import portage.glsa as glsa from portage.util import grabfile, write_atomic from portage.const import CACHE_PATH -from portage.sets import PackageSet +from portage.sets.base import PackageSet __all__ = ["SecuritySet", "NewGlsaSet", "NewAffectedSet", "AffectedSet"] diff --git a/pym/portage/sets/shell.py b/pym/portage/sets/shell.py index fe4babbab..769673485 100644 --- a/pym/portage/sets/shell.py +++ b/pym/portage/sets/shell.py @@ -5,7 +5,7 @@ import subprocess import os -from portage.sets import PackageSet, SetConfigError +from portage.sets.base import PackageSet, SetConfigError __all__ = ["CommandOutputSet"] -- cgit v1.2.3-1-g7c22