Merged from trunk -r12277:12282
authorFabian Groffen <grobian@gentoo.org>
Tue, 23 Dec 2008 18:37:53 +0000 (18:37 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 23 Dec 2008 18:37:53 +0000 (18:37 -0000)
   | 12278   | Bug #252167 - If the ebuild no longer exists or it's         |
   | zmedico | keywords have been dropped, reject built instances           |
   |         | (installed or binary). If --usepkgonly is enabled, assume    |
   |         | that the ebuild status should be ignored.                    |

   | 12279   | Simplify the code from bug #218854. Also, ensure that the    |
   | zmedico | set of visible packages thats used by                        |
   |         | depgraph._iter_atoms_for_pkg() is consistent with the        |
   |         | packages that have been selected by                          |
   |         | depgraph._select_pkg_highest_available(). This should        |
   |         | correct potential inconstencies introduced by the package    |
   |         | selection changes from bug #252167.                          |

   | 12280   | Bug #252243 - Fix binarytree.prevent_collision() so that it  |
   | zmedico | won't create a circular symlink if there happens to be a     |
   |         | symlink in $PKGDIR/All for some reason.                      |

   | 12281   | Fix typo.                                                    |
   | zmedico |                                                              |

   | 12282   | When removing entries with duplicate paths inside            |
   | zmedico | binarytree.inject(), handle path collisions in $PKGDIR/All   |
   |         | when CPV is not identical.                                   |

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

pym/_emerge/__init__.py
pym/portage/dbapi/bintree.py

index e1d5a7010920f1d9d05dadbb7a6d12a63195815e..ad4f9342b6e372c48ae2b4ff2e89c1590cfe0fbf 100644 (file)
@@ -4334,7 +4334,7 @@ class depgraph(object):
                # to the graph.
                self._graph_trees = {}
                # All Package instances
-               self._pkg_cache = self._package_cache(self)
+               self._pkg_cache = {}
                for myroot in trees:
                        self.trees[myroot] = {}
                        # Create a RootConfig instance that references
@@ -5737,6 +5737,12 @@ class depgraph(object):
                        return ret
                ret = self._select_pkg_highest_available_imp(root, atom, onlydeps=onlydeps)
                self._highest_pkg_cache[cache_key] = ret
+               pkg, existing = ret
+               if pkg is not None:
+                       settings = pkg.root_config.settings
+                       if visible(settings, pkg) and not (pkg.installed and \
+                               settings._getMissingKeywords(pkg.cpv, pkg.metadata)):
+                               pkg.root_config.visible_pkgs.cpv_inject(pkg)
                return ret
 
        def _select_pkg_highest_available_imp(self, root, atom, onlydeps=False):
@@ -5860,7 +5866,7 @@ class depgraph(object):
                                                        calculated_use = True
                                                self._pkg_cache[pkg] = pkg
 
-                                       if not installed or (installed and matched_packages):
+                                       if not installed or (built and matched_packages):
                                                # Only enforce visibility on installed packages
                                                # if there is at least one other visible package
                                                # available. By filtering installed masked packages
@@ -5879,9 +5885,8 @@ class depgraph(object):
                                                # version is masked by KEYWORDS, but never
                                                # reinstall the same exact version only due
                                                # to a KEYWORDS mask.
-                                               if installed and matched_packages and \
-                                                       pkgsettings._getMissingKeywords(
-                                                       pkg.cpv, pkg.metadata):
+                                               if built and matched_packages:
+
                                                        different_version = None
                                                        for avail_pkg in matched_packages:
                                                                if not portage.dep.cpvequal(
@@ -5889,9 +5894,26 @@ class depgraph(object):
                                                                        different_version = avail_pkg
                                                                        break
                                                        if different_version is not None:
-                                                               # Only reinstall for KEYWORDS if
-                                                               # it's not the same version.
-                                                               continue
+
+                                                               if installed and \
+                                                                       pkgsettings._getMissingKeywords(
+                                                                       pkg.cpv, pkg.metadata):
+                                                                       continue
+
+                                                               # If the ebuild no longer exists or it's
+                                                               # keywords have been dropped, reject built
+                                                               # instances (installed or binary).
+                                                               # If --usepkgonly is enabled, assume that
+                                                               # the ebuild status should be ignored.
+                                                               if not usepkgonly:
+                                                                       try:
+                                                                               pkg_eb = self._pkg(
+                                                                                       pkg.cpv, "ebuild", root_config)
+                                                                       except portage.exception.PackageNotFound:
+                                                                               continue
+                                                                       else:
+                                                                               if not visible(pkgsettings, pkg_eb):
+                                                                                       continue
 
                                        if not pkg.built and not calculated_use:
                                                # This is avoided whenever possible because
@@ -6028,22 +6050,6 @@ class depgraph(object):
                                        if pkg.cp == cp]
                                break
 
-               # If the installed version is in a different slot and it is higher than
-               # the highest available visible package, _iter_atoms_for_pkg() may fail
-               # to properly match the available package with a corresponding argument
-               # atom. Detect this case and correct it here.
-               if not selective and len(matched_packages) > 1 and \
-                       matched_packages[-1].installed and \
-                       matched_packages[-1].slot_atom != \
-                       matched_packages[-2].slot_atom and \
-                       matched_packages[-1] > matched_packages[-2]:
-                       pkg = matched_packages[-2]
-                       if pkg.root == self.target_root and \
-                               self._set_atoms.findAtomForPackage(pkg):
-                               # Select the available package instead
-                               # of the installed package.
-                               matched_packages.pop()
-
                if len(matched_packages) > 1:
                        bestmatch = portage.best(
                                [pkg.cpv for pkg in matched_packages])
@@ -6180,7 +6186,10 @@ class depgraph(object):
                        db = root_config.trees[tree_type].dbapi
                        db_keys = list(self._trees_orig[root_config.root][
                                tree_type].dbapi._aux_cache_keys)
-                       metadata = izip(db_keys, db.aux_get(cpv, db_keys))
+                       try:
+                               metadata = izip(db_keys, db.aux_get(cpv, db_keys))
+                       except KeyError:
+                               raise portage.exception.PackageNotFound(cpv)
                        pkg = Package(cpv=cpv, metadata=metadata,
                                root_config=root_config, installed=installed)
                        if type_name == "ebuild":
@@ -8489,22 +8498,6 @@ class depgraph(object):
                        metadata = self._cpv_pkg_map[cpv].metadata
                        return [metadata.get(x, "") for x in wants]
 
-       class _package_cache(dict):
-               def __init__(self, depgraph):
-                       dict.__init__(self)
-                       self._depgraph = depgraph
-
-               def __setitem__(self, k, v):
-                       dict.__setitem__(self, k, v)
-                       root_config = self._depgraph.roots[v.root]
-                       try:
-                               if visible(root_config.settings, v) and \
-                                       not (v.installed and \
-                                       v.root_config.settings._getMissingKeywords(v.cpv, v.metadata)):
-                                       root_config.visible_pkgs.cpv_inject(v)
-                       except portage.exception.InvalidDependString:
-                               pass
-
 class RepoDisplay(object):
        def __init__(self, roots):
                self._shown_repos = {}
index 51012fb3eae657f77abc869f624d3a58335293f5..f8485f340450eefa2482a085bd7c6d524b1a7c73 100644 (file)
@@ -329,7 +329,21 @@ class binarytree(object):
                myfile = mypkg + ".tbz2"
                mypath = os.path.join("All", myfile)
                dest_path = os.path.join(self.pkgdir, mypath)
-               if os.path.exists(dest_path):
+
+               try:
+                       st = os.lstat(dest_path)
+               except OSError:
+                       st = None
+               else:
+                       if stat.S_ISLNK(st.st_mode):
+                               st = None
+                               try:
+                                       os.unlink(dest_path)
+                               except OSError:
+                                       if os.path.exists(dest_path):
+                                               raise
+
+               if st is not None:
                        # For invalid packages, other_cat could be None.
                        other_cat = portage.xpak.tbz2(dest_path).getfile("CATEGORY")
                        if other_cat:
@@ -337,11 +351,7 @@ class binarytree(object):
                                other_cpv = other_cat + "/" + mypkg
                                self._move_from_all(other_cpv)
                                self.inject(other_cpv)
-               """The file may or may not exist. Move it if necessary and update
-               internal state for future calls to getname()."""
                self._move_to_all(cpv)
-               if os.path.exists(full_path):
-                       self.inject(cpv)
 
        def _ensure_dir(self, path):
                """
@@ -368,6 +378,7 @@ class binarytree(object):
                for future getname() calls."""
                mycat, mypkg = catsplit(cpv)
                myfile = mypkg + ".tbz2"
+               self._pkg_paths[cpv] = os.path.join("All", myfile)
                src_path = os.path.join(self.pkgdir, mycat, myfile)
                try:
                        mystat = os.lstat(src_path)
@@ -378,7 +389,7 @@ class binarytree(object):
                        dest_path = os.path.join(self.pkgdir, "All", myfile)
                        _movefile(src_path, dest_path, mysettings=self.settings)
                        self._create_symlink(cpv)
-               self._pkg_paths[cpv] = os.path.join("All", myfile)
+                       self.inject(cpv)
 
        def _move_from_all(self, cpv):
                """Move a package from ${PKGDIR}/All/${PF}.tbz2 to
@@ -860,11 +871,14 @@ class binarytree(object):
                                return
 
                        # If found, remove package(s) with duplicate path.
+                       path = d.get("PATH")
                        for i in xrange(len(pkgindex.packages) - 1, -1, -1):
                                d2 = pkgindex.packages[i]
-                               if d2["CPV"] != cpv:
-                                       continue
-                               if d2.get("PATH", "") == d.get("PATH", ""):
+                               if path is not None and path == d2.get("PATH"):
+                                       # Handle path collisions in $PKGDIR/All
+                                       # when CPV is not identical.
+                                       del pkgindex.packages[i]
+                               elif cpv == d2.get("CPV") and path == d2.get("PATH"):
                                        del pkgindex.packages[i]
                        pkgindex.packages.append(d)