Merged from trunk 8251:8259
authorFabian Groffen <grobian@gentoo.org>
Wed, 24 Oct 2007 14:00:06 +0000 (14:00 -0000)
committerFabian Groffen <grobian@gentoo.org>
Wed, 24 Oct 2007 14:00:06 +0000 (14:00 -0000)
   | 8252    | protect variables specified in PROFILE_ONLY_VARIABLES from   |
   | genone  | being set by the user                                        |

   | 8253    | make PROFILE_ONLY_VARIABLES incremental                      |
   | genone  |                                                              |

   | 8254    | make 'world' and 'system' behave like their sets/            |
   | genone  | counterparts                                                 |

   | 8255    | Optimize PROFILE_ONLY_VARIABLES handling.                    |
   | zmedico |                                                              |

   | 8256    | just pass the SetConfig instance instead of only the         |
   | genone  | settings and trees attributes                                |

   | 8257    | move base classes for package sets into a separate module    |
   | genone  |                                                              |

   | 8258    | revert r8256 (plans changed)                                 |
   | genone  |                                                              |

   | 8259    | document PROFILE_ONLY_VARIABLES                              |
   | genone  |                                                              |

svn path=/main/branches/prefix/; revision=8273

man/portage.5
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/const.py
pym/portage/sets/__init__.py
pym/portage/sets/base.py [new file with mode: 0644]
pym/portage/sets/dbapi.py
pym/portage/sets/files.py
pym/portage/sets/profiles.py
pym/portage/sets/security.py
pym/portage/sets/shell.py

index b94b2fdbd79fd23df96ba7ac618a1c762d6c87ac..0599c5e09301d4fc28b48c9daf5bc3a5c946fb45 100644 (file)
@@ -163,9 +163,13 @@ Architecture type (x86/ppc/hppa/etc...).
 .B USERLAND = \fI"GNU"\fR
 Support BSD/cygwin/etc...
 .TP
-.B PORTAGE_LIBC = \fI"glibc"\fR
+.B ELIBC = \fI"glibc"\fR
 Support uClibc/BSD libc/etc...
 .TP
+.B PROFILE_ONLY_VARIABLES = \fI"ARCH"\fR
+Prevent critical variables from being changed by the user in make.conf 
+or the env.
+.TP
 .BR PROFILE_ARCH
 Distinguish machines classes that have the same \fBARCH\fR.  All sparc 
 machines have ARCH=sparc but set this to either 'sparc32' or 'sparc64'.
index b39a5edb6733cdd6e72402f13c84c6c0d46c105c..3dfc3960691654705e183481ba998a9f9a8af823 100644 (file)
@@ -53,8 +53,9 @@ from portage.const import EPREFIX, BPREFIX
 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
@@ -350,8 +351,7 @@ def create_depgraph_params(myopts, myaction):
        if "--update" in myopts or \
                "--newuse" in myopts or \
                "--reinstall" in myopts or \
-               "--noreplace" in myopts or \
-               myaction in ("system", "world"):
+               "--noreplace" in myopts:
                myparams.add("selective")
        if "--emptytree" in myopts:
                myparams.add("empty")
index 1568d2618c685c9342cc57ec3137442ed05171ad..e29c14f4331a32e13eedb6f253a6ece182f3c79f 100644 (file)
@@ -1194,6 +1194,13 @@ class config(object):
                                                "this. Do not use them.\n", noiselevel=-1)
                                sys.exit(1)
 
+
+                       # Don't allow the user to override certain variables in make.conf
+                       profile_only_variables = self.configdict["defaults"].get(
+                               "PROFILE_ONLY_VARIABLES", "").split()
+                       for k in profile_only_variables:
+                               self.mygcfg.pop(k, None)
+                       
                        # Allow ROOT setting to come from make.conf if it's not overridden
                        # by the constructor argument (from the calling environment).  As a
                        # special exception for a very common use case, config_root == "/"
@@ -1217,7 +1224,12 @@ class config(object):
                        self.configlist.append(self.backupenv) # XXX Why though?
                        self.configdict["backupenv"]=self.configlist[-1]
 
-                       self.configlist.append(os.environ.copy())
+                       myenv = os.environ.copy()               
+                       # Don't allow the user to override certain variables in the env
+                       for k in profile_only_variables:
+                               myenv.pop(k, None)
+
+                       self.configlist.append(myenv)
                        self.configdict["env"]=self.configlist[-1]
 
                        # make lookuplist for loading package.*
index 53232f1611149ab1ff3b775851584cdfe3c886aa..708eb71773d9eb740e6830c0b88491417130866e 100644 (file)
@@ -63,7 +63,7 @@ REPO_NAME_LOC          = "profiles" + "/" + REPO_NAME_FILE
 INCREMENTALS = ["USE", "USE_EXPAND", "USE_EXPAND_HIDDEN", "FEATURES",
        "ACCEPT_KEYWORDS", "ACCEPT_LICENSE",
        "CONFIG_PROTECT_MASK", "CONFIG_PROTECT",
-       "PRELINK_PATH", "PRELINK_PATH_MASK"]
+       "PRELINK_PATH", "PRELINK_PATH_MASK", "PROFILE_ONLY_VARIABLES"]
 EBUILD_PHASES           = ["setup", "unpack", "compile", "test", "install",
                           "preinst", "postinst", "prerm", "postrm", "other"]
 
index ac3f4b0cbfe70e4c0ad2a48d140525f6848f44a1..b757c43c47c5972d66f29f1ff27aa7e3ca033021 100644 (file)
 
 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 (file)
index 0000000..b5ea889
--- /dev/null
@@ -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
+
index bc842ae2c3feb7510ebb9e3e74179fdb41f99268..a1b902fdcc4db9abf2072032ab237907ea23f656 100644 (file)
@@ -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
 
index 71a2ecd85361cfbdbac9e98579535334373532de..9cbb018da042e43c132d9a0144b2fbd6a6767fb1 100644 (file)
@@ -8,7 +8,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
index fcefaff887ddbff0020676dc5bd410f106a6ad35..35cf4d87db2fb4dc114cc91ab0a90381d2895824 100644 (file)
@@ -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"]
 
index f58e725f9d4799101832102aa007d2b29a9651aa..b5332699078e21a1db1b78d096ef2112a9d230d7 100644 (file)
@@ -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"]
 
index 56b8ef5efd1ea2ba2434c29d125ec9b9f5e9b9b8..cae28fa4622a9a54329df135d1c6b4591e4b1ebe 100644 (file)
@@ -5,7 +5,7 @@
 import subprocess
 import os
 
-from portage.sets import PackageSet, SetConfigError
+from portage.sets.base import PackageSet, SetConfigError
 
 __all__ = ["CommandOutputSet"]