From: Fabian Groffen Date: Wed, 11 Nov 2009 20:21:08 +0000 (-0000) Subject: Merged from trunk -r14771:14781 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=8c20073e153ef9c3229c899fbd7609554e86753f;p=portage.git Merged from trunk -r14771:14781 | 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 --- diff --git a/bin/ebuild.sh b/bin/ebuild.sh index e839c54e8..899f98e81 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -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} diff --git a/pym/_emerge/BlockerDB.py b/pym/_emerge/BlockerDB.py index 8367ec651..f4ff9cc2c 100644 --- a/pym/_emerge/BlockerDB.py +++ b/pym/_emerge/BlockerDB.py @@ -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): diff --git a/pym/_emerge/FakeVartree.py b/pym/_emerge/FakeVartree.py index 96d13bd28..e1b819809 100644 --- a/pym/_emerge/FakeVartree.py +++ b/pym/_emerge/FakeVartree.py @@ -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 diff --git a/pym/_emerge/PackageVirtualDbapi.py b/pym/_emerge/PackageVirtualDbapi.py index adf269116..e557f0489 100644 --- a/pym/_emerge/PackageVirtualDbapi.py +++ b/pym/_emerge/PackageVirtualDbapi.py @@ -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()) diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 26085fead..bbca25007 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -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 diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 654120b57..ef8233684 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -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: diff --git a/pym/portage/mail.py b/pym/portage/mail.py index 040cd1136..9a69f9604 100644 --- a/pym/portage/mail.py +++ b/pym/portage/mail.py @@ -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)) diff --git a/pym/portage/proxy/objectproxy.py b/pym/portage/proxy/objectproxy.py index a064d7056..d392beb60 100644 --- a/pym/portage/proxy/objectproxy.py +++ b/pym/portage/proxy/objectproxy.py @@ -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')())