Merged from trunk -r14771:14781
authorFabian Groffen <grobian@gentoo.org>
Wed, 11 Nov 2009 20:21:08 +0000 (20:21 -0000)
committerFabian Groffen <grobian@gentoo.org>
Wed, 11 Nov 2009 20:21:08 +0000 (20:21 -0000)
   | 14772    | Eliminate duplicate code from the FakeVartree constructor   |
   | zmedico  | which does the same thing as FakeVartree.sync().            |

   | 14773    | Move FakeVartree population out of the constructor by       |
   | zmedico  | calling the sync() method explicitly. This allows the       |
   |          | depgraph constructor avoid populating the FakeVartree, and  |
   |          | delay it until depgraph._load_vdb() is called.              |

   | 14774    | Don't call FakeVartree.sync() redundantly when              |
   | zmedico  | backtracking.                                               |

   | 14775    | Inside depgraph._complete_graph(), only pull in deps for    |
   | zmedico  | the relevant root during remove operations. Thanks to       |
   |          | acevery for reporting.                                      |

   | 14776    | Bug #291331 - Make send_mail() encode the unicode message   |
   | zmedico  | as bytes before passing it to smtplib.SMTP.sendmail(), in   |
   |          | order to avoid a UnicodeEncodeError which SMTP.send() tries |
   |          | to encode the message a plain ascii.                        |

   | 14777    | Decode git output in _emerge.actions.git_sync_timestamps()  |
   | arfrever | for bug #291790.                                            |

   | 14778    | Define portage.proxy.objectproxy.ObjectProxy.__add__() to   |
   | arfrever | fix problem with string concatenation reported by dol-sen.  |

   | 14779    | Use writemsg instead of print, to send debug messages to    |
   | zmedico  | stderr.                                                     |

   | 14780    | Bug #291142 - Fix some cases when a 'missed update' message |
   | zmedico  | might not be displayed.                                     |

   | 14781    | For --debug mode, enable bash tracing when sourcing the     |
   | zmedico  | ebuild.                                                     |

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

bin/ebuild.sh
pym/_emerge/BlockerDB.py
pym/_emerge/FakeVartree.py
pym/_emerge/PackageVirtualDbapi.py
pym/_emerge/actions.py
pym/_emerge/depgraph.py
pym/portage/mail.py
pym/portage/proxy/objectproxy.py

index e839c54e8ccf82671afa3f356b97608000b984c5..899f98e814a2a668aeb6e74aaf0b77b07e507eca 100755 (executable)
@@ -1827,7 +1827,14 @@ if ! hasq "$EBUILD_PHASE" clean cleanrm ; then
                # eclasses, they need to be unset before this process of
                # interaction begins.
                unset DEPEND RDEPEND PDEPEND IUSE
-               source "${EBUILD}" || die "error sourcing ebuild"
+
+               if [[ $PORTAGE_DEBUG != 1 ]] || [[ ${-/x/} != $- ]] ; then
+                       source "$EBUILD" || die "error sourcing ebuild"
+               else
+                       set -x
+                       source "$EBUILD" || die "error sourcing ebuild"
+                       set +x
+               fi
 
                if [[ "${EBUILD_PHASE}" != "depend" ]] ; then
                        RESTRICT=${PORTAGE_RESTRICT}
index 8367ec6513a09e8f61b05f645f31d03006b4bca1..f4ff9cc2c71c37742b45f46f41e2487d51884c95 100644 (file)
@@ -29,15 +29,13 @@ class BlockerDB(object):
        def _get_fake_vartree(self, acquire_lock=0):
                fake_vartree = self._fake_vartree
                if fake_vartree is None:
-                       fake_vartree = FakeVartree(self._root_config,
-                               acquire_lock=acquire_lock)
+                       fake_vartree = FakeVartree(self._root_config)
                        self._fake_vartree = fake_vartree
                        self._dep_check_trees = { self._vartree.root : {
                                "porttree"    :  fake_vartree,
                                "vartree"     :  fake_vartree,
                        }}
-               else:
-                       fake_vartree.sync(acquire_lock=acquire_lock)
+               fake_vartree.sync(acquire_lock=acquire_lock)
                return fake_vartree
 
        def findInstalledBlockers(self, new_pkg, acquire_lock=0):
index 96d13bd28bb527fa6b10c6d4adaadf35c729ab1e..e1b81980959f8435ec7801e29a1bfd301c91d44a 100644 (file)
@@ -21,8 +21,9 @@ class FakeVartree(portage.vartree):
        allows things like vardb global updates to be done in memory so that the
        user doesn't necessarily need write access to the vardb in cases where
        global updates are necessary (updates are performed when necessary if there
-       is not a matching ebuild in the tree)."""
-       def __init__(self, root_config, pkg_cache=None, acquire_lock=1):
+       is not a matching ebuild in the tree). Instances of this class are not
+       populated until the sync() method is called."""
+       def __init__(self, root_config, pkg_cache=None):
                self._root_config = root_config
                if pkg_cache is None:
                        pkg_cache = {}
@@ -36,51 +37,6 @@ class FakeVartree(portage.vartree):
                self._db_keys = mykeys
                self._pkg_cache = pkg_cache
                self.dbapi = PackageVirtualDbapi(real_vartree.settings)
-               vdb_path = os.path.join(self.root, portage.VDB_PATH)
-               try:
-                       # At least the parent needs to exist for the lock file.
-                       portage.util.ensure_dirs(vdb_path)
-               except portage.exception.PortageException:
-                       pass
-               vdb_lock = None
-               try:
-                       if acquire_lock and os.access(vdb_path, os.W_OK):
-                               vdb_lock = portage.locks.lockdir(vdb_path)
-                       real_dbapi = real_vartree.dbapi
-                       slot_counters = {}
-                       for cpv in real_dbapi.cpv_all():
-                               cache_key = ("installed", self.root, cpv, "nomerge")
-                               pkg = self._pkg_cache.get(cache_key)
-                               if pkg is not None:
-                                       metadata = pkg.metadata
-                               else:
-                                       metadata = dict(zip(mykeys, real_dbapi.aux_get(cpv, mykeys)))
-                               myslot = metadata["SLOT"]
-                               mycp = portage.cpv_getkey(cpv)
-                               myslot_atom = "%s:%s" % (mycp, myslot)
-                               try:
-                                       mycounter = long(metadata["COUNTER"])
-                               except ValueError:
-                                       mycounter = 0
-                                       metadata["COUNTER"] = str(mycounter)
-                               other_counter = slot_counters.get(myslot_atom, None)
-                               if other_counter is not None:
-                                       if other_counter > mycounter:
-                                               continue
-                               slot_counters[myslot_atom] = mycounter
-                               if pkg is None:
-                                       pkg = Package(built=True, cpv=cpv,
-                                               installed=True, metadata=metadata,
-                                               root_config=root_config, type_name="installed")
-                               self._pkg_cache[pkg] = pkg
-                               self.dbapi.cpv_inject(pkg)
-                       real_dbapi.flush_cache()
-               finally:
-                       if vdb_lock:
-                               portage.locks.unlockdir(vdb_lock)
-               # Populate the old-style virtuals using the cached values.
-               if not self.settings.treeVirtuals:
-                       self.settings._populate_treeVirtuals(self)
 
                # Intialize variables needed for lazy cache pulls of the live ebuild
                # metadata.  This ensures that the vardb lock is released ASAP, without
@@ -148,6 +104,10 @@ class FakeVartree(portage.vartree):
                        if vdb_lock:
                                portage.locks.unlockdir(vdb_lock)
 
+               # Populate the old-style virtuals using the cached values.
+               if not self.settings.treeVirtuals:
+                       self.settings._populate_treeVirtuals(self)
+
        def _sync(self):
 
                real_vardb = self._root_config.trees["vartree"].dbapi
index adf269116728cd9244ecf2f78611b51e7560041e..e557f0489830e9e373ff4fdbc9e1b2542fc1aa1d 100644 (file)
@@ -2,6 +2,7 @@
 # Distributed under the terms of the GNU General Public License v2
 # $Id$
 
+import sys
 import portage
 
 class PackageVirtualDbapi(portage.dbapi):
@@ -37,6 +38,12 @@ class PackageVirtualDbapi(portage.dbapi):
                obj._cpv_map = self._cpv_map.copy()
                return obj
 
+       def __bool__(self):
+               return bool(self._cpv_map)
+
+       if sys.hexversion < 0x3000000:
+               __nonzero__ = __bool__
+
        def __iter__(self):
                return iter(self._cpv_map.values())
 
index 26085fead769c82d18e2aa8e18bf3b72d501a8d4..bbca25007707fd82ff5cd06e637366dd8d022e3e 100644 (file)
@@ -24,6 +24,7 @@ from itertools import chain
 import portage
 from portage import os
 from portage import digraph
+from portage import _unicode_decode
 from portage.cache.cache_errors import CacheError
 from portage.const import NEWS_LIB_PATH, EPREFIX
 from portage.output import blue, bold, colorize, create_color_func, darkgreen, \
@@ -2513,7 +2514,7 @@ def git_sync_timestamps(settings, portdir):
                portage._shell_quote(portdir)]
        import subprocess
        proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-       modified_files = set(l.rstrip("\n") for l in proc.stdout)
+       modified_files = set(_unicode_decode(l).rstrip("\n") for l in proc.stdout)
        rval = proc.wait()
        if rval != os.EX_OK:
                return rval
index 654120b5701edd8a470c804a80b6511eec74d666..ef8233684754452b1620ff86bb372fdbc26aba62 100644 (file)
@@ -269,10 +269,17 @@ class depgraph(object):
                                "--nodeps" not in self._frozen_config.myopts and \
                                "--buildpkgonly" not in self._frozen_config.myopts
 
+                       fake_vartree = self._frozen_config.trees[myroot]["vartree"]
+                       if not fake_vartree.dbapi:
+                               # This needs to be called for the first depgraph, but not for
+                               # backtracking depgraphs that share the same frozen_config.
+                               fake_vartree.sync()
+
                        if preload_installed_pkgs:
+                               vardb = fake_vartree.dbapi
                                fakedb = self._dynamic_config._graph_trees[
                                        myroot]["vartree"].dbapi
-                               vardb = self._frozen_config.trees[myroot]["vartree"].dbapi
+
                                for pkg in vardb:
                                        self._spinner_update()
                                        # This triggers metadata updates via FakeVartree.
@@ -933,7 +940,9 @@ class depgraph(object):
                                                parent_atoms = \
                                                        self._dynamic_config._parent_atoms.get(pkg, set())
                                                if parent_atoms:
-                                                       parent_atoms = self._dynamic_config._slot_conflict_parent_atoms.intersection(parent_atoms)
+                                                       conflict_atoms = self._dynamic_config._slot_conflict_parent_atoms.intersection(parent_atoms)
+                                                       if conflict_atoms:
+                                                               parent_atoms = conflict_atoms
                                                if pkg >= existing_node:
                                                        # We only care about the parent atoms
                                                        # when they trigger a downgrade.
@@ -1186,10 +1195,12 @@ class depgraph(object):
                strict = pkg.type_name != "installed"
 
                if debug:
-                       print()
-                       print("Parent:   ", pkg)
-                       print("Depstring:", dep_string)
-                       print("Priority:", dep_priority)
+                       writemsg_level("\nParent:    %s\n" % (pkg,),
+                               noiselevel=-1, level=logging.DEBUG)
+                       writemsg_level("Depstring: %s\n" % (dep_string,),
+                               noiselevel=-1, level=logging.DEBUG)
+                       writemsg_level("Priority:  %s\n" % (dep_priority,),
+                               noiselevel=-1, level=logging.DEBUG)
 
                try:
                        selected_atoms = self._select_atoms(dep_root,
@@ -1203,7 +1214,9 @@ class depgraph(object):
                        return 0
 
                if debug:
-                       print("Candidates:", [str(x) for x in selected_atoms[pkg]])
+                       writemsg_level("Candidates: %s\n" % \
+                               ([str(x) for x in selected_atoms[pkg]],),
+                               noiselevel=-1, level=logging.DEBUG)
 
                root_config = self._frozen_config.roots[dep_root]
                vardb = root_config.trees["vartree"].dbapi
@@ -1231,8 +1244,9 @@ class depgraph(object):
                for virt_pkg, atoms in selected_atoms.items():
 
                        if debug:
-                               print("Candidates: %s: %s" % \
-                                       (virt_pkg.cpv, [str(x) for x in atoms]))
+                               writemsg_level("Candidates: %s: %s\n" % \
+                                       (virt_pkg.cpv, [str(x) for x in atoms]),
+                                       noiselevel=-1, level=logging.DEBUG)
 
                        # Just assume depth + 1 here for now, though it's not entirely
                        # accurate since multilple levels of indirect virtual deps may
@@ -1325,7 +1339,18 @@ class depgraph(object):
                                if eliminate_pkg:
                                        atom_pkg_graph.remove(pkg)
 
+                       # Yield < and <= atoms first, since those are more likely to
+                       # cause a slot conflicts, and we want those atoms to be displayed
+                       # in the resulting slot conflict message (see bug #291142).
+                       less_than = []
+                       not_less_than = []
                        for atom in cp_atoms:
+                               if atom.operator in ('<', '<='):
+                                       less_than.append(atom)
+                               else:
+                                       not_less_than.append(atom)
+
+                       for atom in chain(less_than, not_less_than):
                                child_pkgs = atom_pkg_graph.child_nodes(atom)
                                yield (atom, child_pkgs[0])
 
@@ -2626,6 +2651,10 @@ class depgraph(object):
                        self._dynamic_config.myparams["deep"] = True
 
                for root in self._frozen_config.roots:
+                       if root != self._frozen_config.target_root and \
+                               "remove" in self._dynamic_config.myparams:
+                               # Only pull in deps for the relevant root.
+                               continue
                        if required_sets is None or root not in required_sets:
                                required_set_names = self._frozen_config._required_set_names.copy()
                        else:
index 040cd1136955c09384c6bafbe165bc4a175417f2..9a69f9604717daf9c95768e531ef49377aad862d 100644 (file)
@@ -127,7 +127,9 @@ def send_mail(mysettings, message):
                                myconn = smtplib.SMTP(mymailhost, mymailport)
                        if mymailuser != "" and mymailpasswd != "":
                                myconn.login(mymailuser, mymailpasswd)
-                       myconn.sendmail(myfrom, myrecipient, message.as_string())
+                       msg = _unicode_encode(message.as_string(),
+                               encoding=_encodings['content'], errors='backslashreplace')
+                       myconn.sendmail(myfrom, myrecipient, msg)
                        myconn.quit()
                except smtplib.SMTPException as e:
                        raise portage.exception.PortageException(_("!!! An error occured while trying to send logmail:\n")+str(e))
index a064d705668739482fa25325a45f92e6c07eedc0..d392beb6032e22370ffad7ee2bb927c2116ca16c 100644 (file)
@@ -55,6 +55,9 @@ class ObjectProxy(object):
        def __str__(self):
                return str(object.__getattribute__(self, '_get_target')())
 
+       def __add__(self, other):
+               return self.__str__() + other
+
        def __hash__(self):
                return hash(object.__getattribute__(self, '_get_target')())