summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE-NOTES12
-rw-r--r--pym/emerge/__init__.py96
2 files changed, 64 insertions, 44 deletions
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index faa58031..aa126269 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -7,9 +7,6 @@ portage-2.2
* The python namespace for portage has been sanitized, all portage related code
is now contained within the portage namespace. External script should be updated
accordingly, though links exist for backward compability.
-* The "save_summary" and "echo" elog modules are now enabled by default. Setting
- PORTAGE_ELOG_SYSTEM in make.conf will override this, so if you don't want elog
- set PORTAGE_ELOG_SYSTEM="" in make.conf
* -* support in package.keywords was changed as it was inconsistent with
ACCEPT_KEYWORDS behavior (also see http://dev.gentoo.org/~genone/docs/KEYWORDS.stupid).
Previously having -* in package.keywords matched packages with KEYWORDS="-*",
@@ -21,11 +18,20 @@ portage-2.2
portage-2.1.3
==================================
+* The "save_summary" and "echo" elog modules are now enabled by default. Setting
+ PORTAGE_ELOG_SYSTEM in make.conf will override this, so if you don't want elog
+ set PORTAGE_ELOG_SYSTEM="" in make.conf
* The unmerge process will remove any file that is not claimed by another
package in the same slot and is not protected by CONFIG_PROTECT, even if the
modification time or checksum differs from the file that was originally
installed. The old behavior is still available by adding -unmerge-orphans
to FEATURES.
+* The world file now supports slot atoms such as 'sys-devel/gcc:3.4'. In some
+ cases, emerge --depclean may remove slots that it would not have removed
+ in the past. The emerge --noreplace command can be used to add an atom to the
+ world file and prevent matching packages from being removed. A slot atom
+ will be recorded in the world file for any atom that is precise enough to
+ identify a specific slot.
portage-2.1.2
==================================
diff --git a/pym/emerge/__init__.py b/pym/emerge/__init__.py
index ee0494f9..875e5372 100644
--- a/pym/emerge/__init__.py
+++ b/pym/emerge/__init__.py
@@ -674,6 +674,35 @@ class WorldSet(AtomSet):
portage.locks.unlockfile(self._lock)
self._lock = None
+def create_world_atom(pkg_key, metadata, args_set, world_set, portdb):
+ """Create a new atom for the world file if one does not exist. If the
+ argument atom is precise enough to identify a specific slot then a slot
+ atom will be returned. The system set is not used in deciding which
+ atoms to store since system atoms can only match one slot while world
+ atoms can be greedy with respect to slots."""
+ arg_atom = args_set.findAtomForPackage(pkg_key, metadata)
+ cp = portage.dep_getkey(arg_atom)
+ new_world_atom = cp
+ if arg_atom != cp:
+ # If the user gave a specific atom, store it as a
+ # slot atom in the world file.
+ slot_atom = "%s:%s" % (cp, metadata["SLOT"])
+ # First verify the slot is in the portage tree to avoid
+ # adding a bogus slot like that produced by multislot.
+ if portdb.match(slot_atom):
+ # Now verify that the argument is precise enough to identify a
+ # specific slot.
+ matches = portdb.match(arg_atom)
+ matched_slots = set()
+ for cpv in matches:
+ matched_slots.add(portdb.aux_get(cpv, ["SLOT"])[0])
+ if len(matched_slots) == 1:
+ new_world_atom = slot_atom
+ if new_world_atom == world_set.findAtomForPackage(pkg_key, metadata):
+ # Both atoms would be identical, so there's nothing to add.
+ return None
+ return new_world_atom
+
def filter_iuse_defaults(iuse):
for flag in iuse:
if flag.startswith("+") or flag.startswith("-"):
@@ -2420,9 +2449,12 @@ class depgraph(object):
mykey = portage.dep_getkey(atom)
if True:
newlist.append(atom)
- """Make sure all installed slots are updated when possible.
- Do this with --emptytree also, to ensure that all slots are
- remerged."""
+ if mode == "world" and atom not in world_set:
+ # only world is greedy for slots, not system
+ continue
+ # Make sure all installed slots are updated when possible.
+ # Do this with --emptytree also, to ensure that all slots are
+ # remerged.
myslots = set()
for cpv in vardb.match(mykey):
myslots.add(vardb.aux_get(cpv, ["SLOT"])[0])
@@ -3181,10 +3213,11 @@ class depgraph(object):
"--oneshot", "--onlydeps", "--pretend"):
if x in self.myopts:
return
- system_set = SystemSet(self.settings)
world_set = WorldSet(self.settings)
world_set.lock()
world_set.load()
+ args_set = self._args_atoms
+ portdb = self.trees[self.target_root]["porttree"].dbapi
added_favorites = set()
for x in self._args_nodes:
pkg_type, root, pkg_key, pkg_status = x
@@ -3193,9 +3226,9 @@ class depgraph(object):
metadata = dict(izip(self._mydbapi_keys,
self.mydbapi[root].aux_get(pkg_key, self._mydbapi_keys)))
try:
- if not (system_set.findAtomForPackage(pkg_key, metadata) or \
- world_set.findAtomForPackage(pkg_key, metadata)):
- myfavkey = portage.cpv_getkey(pkg_key)
+ myfavkey = create_world_atom(pkg_key, metadata,
+ args_set, world_set, portdb)
+ if myfavkey:
if myfavkey in added_favorites:
continue
added_favorites.add(myfavkey)
@@ -3348,9 +3381,8 @@ class MergeTask(object):
del x, mytype, myroot, mycpv, mystatus, quiet_config
del shown_verifying_msg, quiet_settings
- #buildsyspkg: I need mysysdict also on resume (moved from the else block)
system_set = SystemSet(self.settings)
- favorites_set = AtomSet(favorites)
+ args_set = AtomSet(favorites)
world_set = WorldSet(self.settings)
if "--resume" not in self.myopts:
mymergelist = mylist
@@ -3447,7 +3479,7 @@ class MergeTask(object):
#buildsyspkg: Check if we need to _force_ binary package creation
issyspkg = ("buildsyspkg" in myfeat) \
and x[0] != "blocks" \
- and mysysdict.has_key(portage.cpv_getkey(x[2])) \
+ and system_set.findAtomForPackage(pkg_key, metadata) \
and "--buildpkg" not in self.myopts
if x[0] in ["ebuild","blocks"]:
if x[0] == "blocks" and "--fetchonly" not in self.myopts:
@@ -3637,13 +3669,12 @@ class MergeTask(object):
self.trees[x[1]]["vartree"].inject(x[2])
myfavkey = portage.cpv_getkey(x[2])
if not fetchonly and not pretend and \
- favorites_set.findAtomForPackage(pkg_key, metadata):
+ args_set.findAtomForPackage(pkg_key, metadata):
world_set.lock()
world_set.load()
- #don't record if already in system profile or already recorded
- if not system_set.findAtomForPackage(pkg_key, metadata) and \
- not world_set.findAtomForPackage(pkg_key, metadata):
- #we don't have a favorites entry for this package yet; add one
+ myfavkey = create_world_atom(pkg_key, metadata,
+ args_set, world_set, portdb)
+ if myfavkey:
world_set.add(myfavkey)
print ">>> Recording",myfavkey,"in \"world\" favorites file..."
emergelog(xterm_titles, " === ("+\
@@ -5160,10 +5191,11 @@ def action_depclean(settings, trees, ldpath_mtimes,
vardb = dep_check_trees[myroot]["vartree"].dbapi
# Constrain dependency selection to the installed packages.
dep_check_trees[myroot]["porttree"] = dep_check_trees[myroot]["vartree"]
- syslist = getlist(settings, "system")
- worldlist = getlist(settings, "world")
- system_and_world = AtomSet(syslist)
- system_and_world.update(worldlist)
+ system_set = SystemSet(settings)
+ syslist = list(system_set)
+ world_set = WorldSet(settings)
+ world_set.load()
+ worldlist = list(world_set)
fakedb = portage.fakedbapi(settings=settings)
myvarlist = vardb.cpv_all()
@@ -5201,29 +5233,11 @@ def action_depclean(settings, trees, ldpath_mtimes,
if not atom.startswith("!") and priority == hard:
unresolveable.setdefault(atom, []).append(parent)
continue
- system_or_world = False
- if parent in ('world', 'system'):
- system_or_world = True
- else:
- for pkg in pkgs:
- metadata = dict(izip(metadata_keys,
- vardb.aux_get(pkg, metadata_keys)))
- try:
- if system_and_world.findAtomForPackage(pkg, metadata):
- system_or_world = True
- break
- except portage.exception.InvalidDependString, e:
- writemsg("\n\n!!! '%s' has invalid PROVIDE: %s\n" % \
- (pkg, str(e)), noiselevel=-1)
- writemsg("!!! see '%s'\n\n" % os.path.join(
- myroot, portage.VDB_PATH, pkg, "PROVIDE"),
- noiselevel=-1)
- del e
- if not system_or_world:
+ if len(pkgs) > 1 and parent != "world":
# Prune all but the best matching slot, since that's all that a
- # deep world update would pull in. Don't prune if the cpv is in
- # system or world though, since those sets trigger greedy update
- # of all slots.
+ # deep world update would pull in. Don't prune if this atom comes
+ # directly from world though, since world atoms are greedy when
+ # they don't specify a slot.
pkgs = [portage.best(pkgs)]
for pkg in pkgs:
if fakedb.cpv_exists(pkg):