Merged from trunk -r14605:14615
authorFabian Groffen <grobian@gentoo.org>
Sun, 18 Oct 2009 13:23:01 +0000 (13:23 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sun, 18 Oct 2009 13:23:01 +0000 (13:23 -0000)
|14606  |Only call _test_pty_eof() on Linux, since it seems to hang on most other kernels. |
|zmedico|This should fix the hang reported on FreeBSD here:                                |
|       |http://archives.gentoo.org/gentoo-alt/msg_d81c5e8c6dd6849312ecb048feb41c5b.xml    |

|14607  |Add the "test" flag to implicit IUSE, so handling of FEATURES=test is consistent  |
|zmedico|regardless of explicit IUSE. Users may use use.mask and package.use.mask to       |
|       |control FEATURES=test for all ebuilds, regardless of explicit IUSE.               |

|14609  |Add back info_vars docs accidentally removed in r14587. Thanks to Arfrever for    |
|zmedico|reporting.                                                                        |

|14610  |Bug #289068 - Avoid KeyError: USE when depgraph calls _getMissingLicenses.        |
|zmedico|                                                                                  |

|14611  |TODO: Make resume_depgraph() return reasons for dropped_tasks, for                |
|zmedico|display/logging.                                                                  |

|14612  |Ensure that /dev/std* streams have appropriate sandbox permission for bug #288863.|
|zmedico|This can be removed after sandbox is fixed and portage depends on the fixed       |
|       |version.                                                                          |

|14613  |Remove soname_cache inside calc_depclean() since LinkageMap caches that already.  |
|zmedico|                                                                                  |

|14614  |Bug #266454 - Make @world an all-inclusive set once again, like it was prior to   |
|zmedico|portage-2.2_rc* releases. In addition to @system, @world now includes a @selected |
|       |set which represents user-selected "world" packages and sets that saved in        |
|       |/var/lib/portage/world{,sets}.                                                    |

|14615  |Bug #287869 - Add a --selective[=n] option (inverse of --oneshot). This is useful |
|zmedico|if you want to use EMERGE_DEFAULT_OPTS to make --oneshot behavior default.        |

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

16 files changed:
RELEASE-NOTES
bin/ebuild.sh
cnf/sets.conf
doc/config/sets.docbook
man/emerge.1
man/portage.5
pym/_emerge/Scheduler.py
pym/_emerge/actions.py
pym/_emerge/create_world_atom.py
pym/_emerge/depgraph.py
pym/_emerge/help.py
pym/_emerge/main.py
pym/_emerge/unmerge.py
pym/portage/__init__.py
pym/portage/sets/files.py
pym/portage/tests/ebuild/test_pty_eof.py

index 81ac86682ac4b6f99060c9ae1bec372bba3fd98c..b4908beb521ecc07936151a7fa8751df6629c1f7 100644 (file)
@@ -18,8 +18,9 @@ portage-2.2
   - packages won't be unmerged if they are referenced by an installed package
     set (with the exception of the world set, and installed being determined
     by the world_sets file).
-* "world" no longer includes "system" unconditionally, but you can add
-  "@system" to the world_sets file to restore the old state.
+* "world" now includes separate "selected" and "system" sets, where the
+  "selected" set includes packages listed in /var/lib/portage/world and nested
+  sets that may be listed /var/lib/portage/world_sets.
 
 portage-2.1.7
 ==================================
index 75ff5cfd63e163e065b9303f26c1f4099a59df70..35da07f2c0beb6742b07454e2faedb2b6dac69ad 100755 (executable)
@@ -6,6 +6,12 @@
 PORTAGE_BIN_PATH="${PORTAGE_BIN_PATH:-@PORTAGE_BASE@/bin}"
 PORTAGE_PYM_PATH="${PORTAGE_PYM_PATH:-@PORTAGE_BASE@/pym}"
 
+# Ensure that /dev/std* streams have appropriate sandbox permission for
+# bug #288863. This can be removed after sandbox is fixed and portage
+# depends on the fixed version.
+export SANDBOX_WRITE="${SANDBOX_WRITE:+${SANDBOX_WRITE}:}/dev/stdout:/dev/stderr"
+export SANDBOX_READ="${SANDBOX_READ:+${SANDBOX_READ}:}/dev/stdin"
+
 # Don't use sandbox's BASH_ENV for new shells because it does
 # 'source /etc/profile' which can interfere with the build
 # environment by modifying our PATH.
index 66c132e8b4f15e9dcfb76d8fdd2bb2316c63fdd7..311d4a38f83f624f772cb6ae0bd58e917a6233b8 100644 (file)
@@ -6,7 +6,13 @@
 
 # Not much that could be changed for world, so better leave it alone
 [world]
-class = portage.sets.files.WorldSet
+class = portage.sets.base.DummyPackageSet
+world-candidate = False
+packages = @selected @system
+
+# Not much that could be changed for world, so better leave it alone
+[selected]
+class = portage.sets.files.WorldSelectedSet
 world-candidate = False
 
 # Same as for world, though later portage versions might use a different class
index e50c85cc9b4a1514efa0a877eba21fcf69fbcd75..8f93b1df2d33641564cf059c69c778f254c999da 100644 (file)
                        <programlisting>
                        # The classic world set
                        [world]
-                       class = portage.sets.files.WorldSet
+                       class = portage.sets.base.DummyPackageSet
                        world-candidate = False
-                       
+                       packages = @selected @system
+
+                       # The selected set
+                       [selected]
+                       class = portage.sets.files.WorldSelectedSet
+                       world-candidate = False
+
                        # The classic system set
                        [system]
                        class = portage.sets.profiles.PackagesSystemSet
                        </sect3>
                </sect2>
                
-               <sect2 id='config-set-classes-WorldSet'>
-               <title>portage.sets.files.WorldSet</title>
+               <sect2 id='config-set-classes-WorldSelectedSet'>
+               <title>portage.sets.files.WorldSelectedSet</title>
                <para>
                A minor variation of <classname>StaticFileSet</classname>, mainly for implementation 
                reasons. It should never be used in user configurations as it's already configured
        The default sets are:
        </para>
        <itemizedlist>
+       <listitem><para><varname>world</varname>: uses <classname>DummySet</classname></para></listitem>
+       <listitem><para><varname>selected</varname>: uses <classname>WorldSelectedSet</classname></para></listitem>
        <listitem><para><varname>system</varname>: uses <classname>PackagesSystemSet</classname></para></listitem>
-       <listitem><para><varname>world</varname>: uses <classname>WorldSet</classname></para></listitem>
        <listitem><para><varname>security</varname>: uses <classname>NewAffectedSet</classname> with default options</para></listitem>
        <listitem><para><varname>installed</varname>: uses <classname>EverythingSet</classname></para></listitem>
        <listitem><para><varname>preserved-rebuild</varname>: uses <classname>PreservedLibraryConsumerSet</classname></para></listitem>
index 7edd905fc741748765bc0a3fa9f29f6903178e51..934f6905a87eb5b095f3468ee1e283dc28003710 100644 (file)
@@ -58,10 +58,13 @@ would like to query the owners of one or more files or directories.
 .TP
 .BR set
 A \fIset\fR is a convenient shorthand for a large group of
-packages.  Two sets are currently always available: \fBsystem\fR
-and \fBworld\fR.  \fBsystem\fR refers to a set of packages
-deemed necessary for your system to run properly. \fBworld\fR
-contains all the packages listed in \fB/var/lib/portage/world\fR.  [See
+packages. Three sets are currently always available: \fBselected\fR,
+\fBsystem\fR and \fBworld\fR. \fBselected\fR contains the user-selected
+"world" packages that are listed in \fB/var/lib/portage/world\fR,
+and nested sets that may be listed
+in \fB/var/lib/portage/world_sets\fR. \fBsystem\fR refers to a set of
+packages deemed necessary for your system to run properly. \fBworld\fR
+encompasses both the \fBselected\fR and \fBsystem\fR sets. [See
 \fBFILES\fR below for more information.] Other sets can exist depending
 on the current configuration. The default set configuration is located
 in \fB/usr/share/portage/config/sets.conf\fR. Note that a \fIset\fR
@@ -105,7 +108,7 @@ setups that the user may wish to run.
 .BR \-\-depclean
 Cleans the system by removing packages that are not associated
 with explicitly merged packages. Depclean works by creating the
-full dependency tree from the @system and @world sets,
+full dependency tree from the @world set,
 then comparing it to installed packages. Packages installed, but
 not part of the dependency tree, will be uninstalled by depclean.
 See \fB\-\-with\-bdeps\fR for behavior with respect to build time dependencies
@@ -114,7 +117,7 @@ always be kept. They can be manually added to this set with \fIemerge
 \-\-noreplace <atom>\fR. As a safety measure, depclean will not remove any
 packages unless *all* required dependencies have been resolved. As a
 consequence, it is often necessary to run \fIemerge \-\-update \-\-newuse
-\-\-deep @system @world\fR prior to depclean. 
+\-\-deep @world\fR prior to depclean. 
 
 \fBWARNING:\fR
 Inexperienced users are advised to use \fB\-\-pretend\fR with this
@@ -300,7 +303,7 @@ and old version to be displayed in an aligned format for easy cut\-n\-paste.
 .TP
 .BR "\-\-complete\-graph[=n]"
 This causes \fBemerge\fR to consider the deep dependencies of all
-packages from the system and world sets. With this option enabled,
+packages from the world set. With this option enabled,
 \fBemerge\fR will bail out if it determines that the given operation will
 break any dependencies of the packages that have been added to the
 graph. Like the \fB\-\-deep\fR option, the \fB\-\-complete\-graph\fR
@@ -473,6 +476,12 @@ be enabled under normal circumstances. For currently supported
 \fBDEPEND\fR variable. However, behavior may change for new
 \fBEAPI\fRs when related extensions are added in the future.
 .TP
+.BR "\-\-select"[=n]
+Add specified packages to the world set (inverse of
+\fB\-\-oneshot\fR). This is useful if you want to
+use \fBEMERGE_DEFAULT_OPTS\fR to make
+\fB\-\-oneshot\fR behavior default.
+.TP
 .BR "\-\-selective"[=n]
 This is similar to the \fB\-\-noreplace\fR option, except that it
 does not take precedence over options such as \fB\-\-newuse\fR.
index 963a9d4f9adceca36913121588072f57d792bb65..d81232f1c42cf3be0cb997b08edab5182e786f68 100644 (file)
@@ -683,6 +683,9 @@ sys\-kernel
 .BR info_pkgs
 A list of all the packages which will be displayed when you run `emerge info`.
 .TP
+.BR info_vars
+A list of all the variables which will be displayed when you run `emerge info`.
+.TP
 .BR license_groups
 This contains groups of licenses that may be specifed in the
 \fBACCEPT_LICENSE\fR variable (see \fBmake.conf\fR(5)). Refer
@@ -891,7 +894,7 @@ packages sets which always begin with the @ character.
 
 .I Example:
 .nf
-@system
+@kde
 .fi
 .RE
 .SH "REPORTING BUGS"
index eb2f894973069c77adc394b3516ba4527e162bfd..c95003dd76579bea42a2a2fa7e9154984b54ceae 100644 (file)
@@ -1629,7 +1629,7 @@ class Scheduler(PollScheduler):
                logger = self._logger
                pkg_count = self._pkg_count
                root_config = pkg.root_config
-               world_set = root_config.sets["world"]
+               world_set = root_config.sets["selected"]
                world_locked = False
                if hasattr(world_set, "lock"):
                        world_set.lock()
index d9117be9e2232eda7c1761f531438ded504ccf1f..c94ca3c5d80b52c41a8f7ae98e39c1f6afcaae13 100644 (file)
@@ -566,7 +566,7 @@ def action_depclean(settings, trees, ldpath_mtimes,
        msg.append("unless *all* required dependencies have been resolved.  As a\n")
        msg.append("consequence, it is often necessary to run %s\n" % \
                good("`emerge --update"))
-       msg.append(good("--newuse --deep @system @world`") + \
+       msg.append(good("--newuse --deep @world`") + \
                " prior to depclean.\n")
 
        if action == "depclean" and "--quiet" not in myopts and not myfiles:
@@ -614,7 +614,7 @@ def action_depclean(settings, trees, ldpath_mtimes,
 
        print("Packages installed:   " + str(len(vardb.cpv_all())))
        print("Packages in world:    " + \
-               str(len(root_config.sets["world"].getAtoms())))
+               str(len(root_config.sets["selected"].getAtoms())))
        print("Packages in system:   " + \
                str(len(root_config.sets["system"].getAtoms())))
        print("Required packages:    "+str(req_pkg_count))
@@ -634,7 +634,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
        vardb = trees[myroot]["vartree"].dbapi
        deselect = myopts.get('--deselect') != 'n'
 
-       required_set_names = ("system", "world")
+       required_set_names = ("world",)
        required_sets = {}
        set_args = []
 
@@ -647,7 +647,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
        # which excludes packages that are intended to be eligible for
        # removal.
        world_temp_set = required_sets["world"]
-       system_set = required_sets["system"]
+       system_set = root_config.sets["system"]
 
        if not system_set or not world_temp_set:
 
@@ -787,7 +787,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
                                msg.append("    %s" % (parent,))
                                msg.append("")
                        msg.append("Have you forgotten to run " + \
-                               good("`emerge --update --newuse --deep @system @world`") + " prior")
+                               good("`emerge --update --newuse --deep @world`") + " prior")
                        msg.append(("to %s? It may be necessary to manually " + \
                                "uninstall packages that no longer") % action)
                        msg.append("exist in the portage tree since " + \
@@ -905,7 +905,6 @@ def calc_depclean(settings, trees, ldpath_mtimes,
                linkmap = real_vardb.linkmap
                consumer_cache = {}
                provider_cache = {}
-               soname_cache = {}
                consumer_map = {}
 
                writemsg_level(">>> Checking for lib consumers...\n")
@@ -942,10 +941,7 @@ def calc_depclean(settings, trees, ldpath_mtimes,
 
                        for lib, lib_consumers in consumers.items():
 
-                               soname = soname_cache.get(lib)
-                               if soname is None:
-                                       soname = linkmap.getSoname(lib)
-                                       soname_cache[lib] = soname
+                               soname = linkmap.getSoname(lib)
 
                                consumer_providers = []
                                for lib_consumer in lib_consumers:
@@ -1180,9 +1176,9 @@ def calc_depclean(settings, trees, ldpath_mtimes,
 
 def action_deselect(settings, trees, opts, atoms):
        root_config = trees[settings['ROOT']]['root_config']
-       world_set = root_config.sets['world']
+       world_set = root_config.sets['selected']
        if not hasattr(world_set, 'update'):
-               writemsg_level("World set does not appear to be mutable.\n",
+               writemsg_level("World @selected set does not appear to be mutable.\n",
                        level=logging.ERROR, noiselevel=-1)
                return 1
 
index 30ade0acf4413fc11494b8e8b23b4613296359cd..7ded8af13af93295d5e0d34b862e633bc2bce4ed 100644 (file)
@@ -68,7 +68,7 @@ def create_world_atom(pkg, args_set, root_config):
                        if len(matched_slots) == 1:
                                new_world_atom = slot_atom
 
-       if new_world_atom == sets["world"].findAtomForPackage(pkg):
+       if new_world_atom == sets["selected"].findAtomForPackage(pkg):
                # Both atoms would be identical, so there's nothing to add.
                return None
        if not slotted:
index 1d75f1809850f40f637ee84938f6bc836c3de15e..e6a60a6ca06983c3ba83860df4ad4438de83b107 100644 (file)
@@ -90,7 +90,7 @@ class _frozen_depgraph_config(object):
                        self.pkgsettings[myroot] = portage.config(
                                clone=self.trees[myroot]["vartree"].settings)
 
-               self._required_set_names = set(["system", "world"])
+               self._required_set_names = set(["world"])
 
 class _dynamic_depgraph_config(object):
 
@@ -1756,7 +1756,7 @@ class depgraph(object):
                                                        continue
 
                                                if not (isinstance(arg, SetArg) and \
-                                                       arg.name in ("system", "world")):
+                                                       arg.name in ("selected", "system", "world")):
                                                        self._dynamic_config._unsatisfied_deps_for_display.append(
                                                                ((myroot, atom), {}))
                                                        return 0, myfavorites
@@ -1783,7 +1783,7 @@ class depgraph(object):
                                                # out here if the atom is not from either the system or
                                                # world set.
                                                if not (isinstance(arg, SetArg) and \
-                                                       arg.name in ("system", "world")):
+                                                       arg.name in ("selected", "system", "world")):
                                                        return 0, myfavorites
 
                                        # Add the selected package to the graph as soon as possible
@@ -2071,6 +2071,9 @@ class depgraph(object):
                                if metadata is not None:
                                        pkg = self._pkg(cpv, pkg_type, root_config,
                                                installed=installed)
+                                       # pkg.metadata contains calculated USE for ebuilds,
+                                       # required later for getMissingLicenses.
+                                       metadata = pkg.metadata
                                        if pkg.cp != atom.cp:
                                                # A cpv can be returned from dbapi.match() as an
                                                # old-style virtual match even in cases when the
@@ -3483,7 +3486,7 @@ class depgraph(object):
                                                skip = False
                                                try:
                                                        for atom in root_config.sets[
-                                                               "world"].iterAtomsForPackage(task):
+                                                               "selected"].iterAtomsForPackage(task):
                                                                satisfied = False
                                                                for pkg in graph_db.match_pkgs(atom):
                                                                        if pkg == inst_pkg:
@@ -3772,7 +3775,7 @@ class depgraph(object):
                                if not parent_atoms:
                                        atom = self._dynamic_config._blocked_world_pkgs.get(pkg)
                                        if atom is not None:
-                                               parent_atoms = set([("@world", atom)])
+                                               parent_atoms = set([("@selected", atom)])
                                if parent_atoms:
                                        conflict_pkgs[pkg] = parent_atoms
 
@@ -4425,7 +4428,7 @@ class depgraph(object):
                                pkg_cp = xs[0]
                                root_config = self._frozen_config.roots[myroot]
                                system_set = root_config.sets["system"]
-                               world_set  = root_config.sets["world"]
+                               world_set  = root_config.sets["selected"]
 
                                pkg_system = False
                                pkg_world = False
@@ -4644,9 +4647,9 @@ class depgraph(object):
                        if "world" in self._dynamic_config._sets:
                                # Filter out indirect members of world (from nested sets)
                                # since only direct members of world are desired here.
-                               world_set = self._frozen_config.roots[self._frozen_config.target_root].sets["world"]
+                               world_set = self._frozen_config.roots[self._frozen_config.target_root].sets["selected"]
                                for arg, atom in self._dynamic_config._missing_args:
-                                       if arg.name == "world" and atom in world_set:
+                                       if arg.name in ("selected", "world") and atom in world_set:
                                                world_problems = True
                                                break
 
@@ -4695,7 +4698,7 @@ class depgraph(object):
                                        ref_string = " pulled in by " + ref_string
                                msg.append("  %s%s\n" % (colorize("INFORM", str(arg)), ref_string))
                        msg.append("\n")
-                       if "world" in problems_sets:
+                       if "selected" in problems_sets or "world" in problems_sets:
                                msg.append("This problem can be solved in one of the following ways:\n\n")
                                msg.append("  A) Use emaint to clean offending packages from world (if not installed).\n")
                                msg.append("  B) Uninstall offending packages (cleans them from world).\n")
@@ -4726,7 +4729,7 @@ class depgraph(object):
                        if x in self._frozen_config.myopts:
                                return
                root_config = self._frozen_config.roots[self._frozen_config.target_root]
-               world_set = root_config.sets["world"]
+               world_set = root_config.sets["selected"]
 
                world_locked = False
                if hasattr(world_set, "lock"):
@@ -4758,7 +4761,8 @@ class depgraph(object):
                                del e
                all_added = []
                for k in self._dynamic_config._sets:
-                       if k in ("args", "world") or not root_config.sets[k].world_candidate:
+                       if k in ("args", "selected", "world") or \
+                               not root_config.sets[k].world_candidate:
                                continue
                        s = SETPREFIX + k
                        if s in world_set:
@@ -5222,6 +5226,7 @@ def resume_depgraph(settings, trees, mtimedb, myopts, myparams, spinner):
        """
        Construct a depgraph for the given resume list. This will raise
        PackageNotFound or depgraph.UnsatisfiedResumeDep when necessary.
+       TODO: Return reasons for dropped_tasks, for display/logging.
        @rtype: tuple
        @returns: (success, depgraph, dropped_tasks)
        """
index e2c7a80ea8b8fd090375302457d6f80c88ef8f79..bbeb2fb365dffe584a950984e51b245de0adba02 100644 (file)
@@ -70,8 +70,8 @@ def help(myopts, havecolor=1):
 
                paragraph = "Cleans the system by removing packages that are " + \
                "not associated with explicitly merged packages. Depclean works " + \
-               "by creating the full dependency tree from the @system and " + \
-               "@world sets, then comparing it to installed packages. Packages " + \
+               "by creating the full dependency tree from the " + \
+               "@world set, then comparing it to installed packages. Packages " + \
                "installed, but not part of the dependency tree, will be " + \
                "uninstalled by depclean. See --with-bdeps for behavior with " + \
                "respect to build time dependencies that are not strictly " + \
@@ -80,7 +80,7 @@ def help(myopts, havecolor=1):
                "emerge --noreplace <atom>. As a safety measure, depclean " + \
                "will not remove any packages unless *all* required dependencies " + \
                "have been resolved. As a consequence, it is often necessary to " + \
-               "run emerge --update --newuse --deep @system @world " + \
+               "run emerge --update --newuse --deep @world " + \
                "prior to depclean."
 
                for line in wrap(paragraph, desc_width):
@@ -312,7 +312,7 @@ def help(myopts, havecolor=1):
                print()
                print("       "+green("--complete-graph") + "[=%s]" % turquoise("n"))
                desc = "This causes emerge to consider the deep dependencies of all" + \
-                       " packages from the system and world sets. With this option enabled," + \
+                       " packages from the world set. With this option enabled," + \
                        " emerge will bail out if it determines that the given operation will" + \
                        " break any dependencies of the packages that have been added to the" + \
                        " graph. Like the --deep option, the --complete-graph" + \
@@ -502,6 +502,14 @@ def help(myopts, havecolor=1):
                for line in wrap(desc, desc_width):
                        print(desc_indent + line)
                print()
+               print("       " + green("--select") + "[=%s]" % turquoise("n"))
+               desc = "Add specified packages to the world set (inverse of " + \
+                       "--oneshot). This is useful if you want to " + \
+                       "use EMERGE_DEFAULT_OPTS to make " + \
+                       "--oneshot behavior default."
+               for line in wrap(desc, desc_width):
+                       print(desc_indent + line)
+               print()
                print("       " + green("--selective") + "[=%s]" % turquoise("n"))
                desc = "This is similar to the --noreplace option, except that it " + \
                        "does not take precedence over options such as --newuse. " + \
index 41c4c02a06435814305bdf92a911848c2c093b8a..e9afd255f8d553010ac1cf56e858cf072afa5540 100644 (file)
@@ -390,6 +390,7 @@ def insert_optional_args(args):
                '--jobs'       : valid_integers,
                '--keep-going'           : ('n',),
                '--root-deps'  : ('rdeps',),
+               '--select'               : ('n',),
                '--selective'            : ('n',),
                '--usepkg'               : ('n',),
                '--usepkgonly'           : ('n',),
@@ -614,6 +615,13 @@ def parse_opts(tmpcmdline, silent=False):
                        "choices" :("True", "rdeps")
                },
 
+               "--select": {
+                       "help"    : "add specified packages to the world set " + \
+                                   "(inverse of --oneshot)",
+                       "type"    : "choice",
+                       "choices" : ("True", "n")
+               },
+
                "--selective": {
                        "help"    : "similar to the --noreplace but does not take " + \
                                    "precedence over options such as --newuse",
@@ -705,6 +713,11 @@ def parse_opts(tmpcmdline, silent=False):
        if myoptions.root_deps == "True":
                myoptions.root_deps = True
 
+       if myoptions.select == "True":
+               myoptions.oneshot = False
+       elif myoptions.select == "n":
+               myoptions.oneshot = True
+
        if myoptions.selective == "True":
                myoptions.selective = True
 
@@ -905,8 +918,8 @@ def expand_set_arguments(myfiles, myaction, root_config):
        for e in setconfig.errors:
                print(colorize("BAD", "Error during set creation: %s" % e))
 
-       # emerge relies on the existance of sets with names "world" and "system"
-       required_sets = ("world", "system")
+       # emerge requires existence of "world", "selected", and "system"
+       required_sets = ("selected", "system", "world",)
        missing_sets = []
 
        for s in required_sets:
index 4d2a546c5b2915bb8a3d8ace3916d6d2ab73280b..967d72478b40f809894748f31fffcf3d802b504e 100644 (file)
@@ -283,9 +283,9 @@ def unmerge(root_config, myopts, unmerge_action,
        
        from portage.sets.base import EditablePackageSet
        
-       # generate a list of package sets that are directly or indirectly listed in "world",
+       # generate a list of package sets that are directly or indirectly listed in "selected",
        # as there is no persistent list of "installed" sets
-       installed_sets = ["world"]
+       installed_sets = ["selected"]
        stop = False
        pos = 0
        while not stop:
@@ -333,7 +333,8 @@ def unmerge(root_config, myopts, unmerge_action,
                                # skip sets that the user requested to unmerge, and skip world 
                                # unless we're unmerging a package set (as the package would be 
                                # removed from "world" later on)
-                               if s in root_config.setconfig.active or (s == "world" and not root_config.setconfig.active):
+                               if s in root_config.setconfig.active or \
+                                       (s == "selected" and not root_config.setconfig.active):
                                        continue
 
                                if s not in sets:
@@ -510,22 +511,22 @@ def unmerge(root_config, myopts, unmerge_action,
                                        raise UninstallFailure(retval)
                                sys.exit(retval)
                        else:
-                               if clean_world and hasattr(sets["world"], "cleanPackage")\
-                                               and hasattr(sets["world"], "lock"):
-                                       sets["world"].lock()
-                                       if hasattr(sets["world"], "load"):
-                                               sets["world"].load()
-                                       sets["world"].cleanPackage(vartree.dbapi, y)
-                                       sets["world"].unlock()
+                               if clean_world and hasattr(sets["selected"], "cleanPackage")\
+                                               and hasattr(sets["selected"], "lock"):
+                                       sets["selected"].lock()
+                                       if hasattr(sets["selected"], "load"):
+                                               sets["selected"].load()
+                                       sets["selected"].cleanPackage(vartree.dbapi, y)
+                                       sets["selected"].unlock()
                                emergelog(xterm_titles, " >>> unmerge success: "+y)
 
-       if clean_world and hasattr(sets["world"], "remove")\
-                       and hasattr(sets["world"], "lock"):
-               sets["world"].lock()
+       if clean_world and hasattr(sets["selected"], "remove")\
+                       and hasattr(sets["selected"], "lock"):
+               sets["selected"].lock()
                # load is called inside remove()
                for s in root_config.setconfig.active:
-                       sets["world"].remove(SETPREFIX+s)
-               sets["world"].unlock()
+                       sets["selected"].remove(SETPREFIX + s)
+               sets["selected"].unlock()
 
        return 1
 
index 32656dd58ee86847e89380d41a3bc1bc00a9099f..255ba32cd43c257cecb2eb43d0709dfc649a9008 100644 (file)
@@ -2740,7 +2740,7 @@ class config(object):
                        not hasattr(self, "_ebuild_force_test_msg_shown"):
                                self._ebuild_force_test_msg_shown = True
                                writemsg(_("Forcing test.\n"), noiselevel=-1)
-               if "test" in self.features and "test" in iuse_implicit:
+               if "test" in self.features:
                        if "test" in self.usemask and not ebuild_force_test:
                                # "test" is in IUSE and USE=test is masked, so execution
                                # of src_test() probably is not reliable. Therefore,
@@ -2830,6 +2830,12 @@ class config(object):
                iuse_implicit.add("build")
                iuse_implicit.add("bootstrap")
 
+               # Controlled by FEATURES=test. Make this implicit, so handling
+               # of FEATURES=test is consistent regardless of explicit IUSE.
+               # Users may use use.mask/package.use.mask to control
+               # FEATURES=test for all ebuilds, regardless of explicit IUSE.
+               iuse_implicit.add("test")
+
                return iuse_implicit
 
        def _getUseMask(self, pkg):
@@ -3793,6 +3799,15 @@ class config(object):
                keys = __iter__
                items = iteritems
 
+def _can_test_pty_eof():
+       """
+       The _test_pty_eof() function seems to hang on most
+       kernels other than Linux.
+       @rtype: bool
+       @returns: True if _test_pty_eof() won't hang, False otherwise.
+       """
+       return platform.system() in ("Linux",)
+
 def _test_pty_eof():
        """
        Returns True if this issues is fixed for the currently
@@ -3877,9 +3892,13 @@ def _test_pty_eof():
 
        return test_string == ''.join(data)
 
-# In some cases, openpty can be slow when it fails. Therefore,
-# stop trying to use it after the first failure.
-if platform.system() not in ["FreeBSD", "Linux"]:
+# If _test_pty_eof() can't be used for runtime detection of
+# http://bugs.python.org/issue5380, openpty can't safely be used
+# unless we can guarantee that the current version of python has
+# been fixed (affects all current versions of python3). When
+# this issue is fixed in python3, we can add another sys.hexversion
+# conditional to enable openpty support in the fixed versions.
+if sys.hexversion >= 0x3000000 and not _can_test_pty_eof():
        # Disable the use of openpty on Solaris as it seems Python's openpty
        # implementation doesn't play nice on Solaris with Portage's
        # behaviour causing hangs/deadlocks.
@@ -3896,6 +3915,10 @@ else:
        _disable_openpty = False
 _tested_pty = False
 
+if not _can_test_pty_eof():
+       # Skip _test_pty_eof() on systems where it hangs.
+       _tested_pty = True
+
 def _create_pty_or_pipe(copy_term_size=None):
        """
        Try to create a pty and if then fails then create a normal
index ba56e7b0f0482de4e2d497dc0ed6737a70e64fff..eac98d6ae50e77dafdc9a85a85d561732f1edc77 100644 (file)
@@ -20,7 +20,7 @@ from portage.env.loaders import ItemFileLoader, KeyListFileLoader
 from portage.env.validators import ValidAtomValidator
 from portage import dep_getkey, cpv_getkey
 
-__all__ = ["StaticFileSet", "ConfigFileSet", "WorldSet"]
+__all__ = ["StaticFileSet", "ConfigFileSet", "WorldSelectedSet"]
 
 class StaticFileSet(EditablePackageSet):
        _operations = ["merge", "unmerge"]
@@ -204,11 +204,11 @@ class ConfigFileSet(PackageSet):
                return rValue
        multiBuilder = classmethod(multiBuilder)
 
-class WorldSet(EditablePackageSet):
+class WorldSelectedSet(EditablePackageSet):
        description = "Set of packages that were directly installed by the user"
        
        def __init__(self, root):
-               super(WorldSet, self).__init__()
+               super(WorldSelectedSet, self).__init__()
                # most attributes exist twice as atoms and non-atoms are stored in 
                # separate files
                self._lock = None
@@ -323,5 +323,5 @@ class WorldSet(EditablePackageSet):
                self.replace(newworldlist)
 
        def singleBuilder(self, options, settings, trees):
-               return WorldSet(settings["ROOT"])
+               return WorldSelectedSet(settings["ROOT"])
        singleBuilder = classmethod(singleBuilder)
index 0dd1e85069800a343d8164c52f09b15b475807ea..31a5df4aaa3b77184b2d273f9728bd0ba9b0654f 100644 (file)
@@ -13,7 +13,8 @@ class PtyEofTestCase(TestCase):
                # Since it might not be fixed, mark as todo.
                self.todo = True
                # The result is only valid if openpty does not raise EnvironmentError.
-               try:
-                       self.assertEqual(portage._test_pty_eof(), True)
-               except EnvironmentError:
-                       pass
+               if portage._can_test_pty_eof():
+                       try:
+                               self.assertEqual(portage._test_pty_eof(), True)
+                       except EnvironmentError:
+                               pass