Allow running pkg_info on non-installed packages
authorSebastian Luther <SebastianLuther@gmx.de>
Tue, 30 Mar 2010 18:21:09 +0000 (20:21 +0200)
committerZac Medico <zmedico@gentoo.org>
Wed, 31 Mar 2010 21:36:20 +0000 (14:36 -0700)
pym/_emerge/actions.py
pym/_emerge/main.py

index 4fb08e3adecfe4e68177f700dfc45977faf49ee5..78f564c9511bfa892741b6bcecae59af50939541 100644 (file)
@@ -12,10 +12,12 @@ import logging
 import platform
 import pwd
 import re
+import shutil
 import signal
 import socket
 import stat
 import sys
+import tempfile
 import textwrap
 import time
 from itertools import chain
@@ -1324,8 +1326,33 @@ def action_info(settings, trees, myopts, myfiles):
        mypkgs = []
        vardb = trees[settings["ROOT"]]["vartree"].dbapi
        portdb = trees[settings["ROOT"]]["porttree"].dbapi
+       bindb = trees[settings["ROOT"]]["bintree"].dbapi
        for x in myfiles:
-               mypkgs.extend(vardb.match(x))
+               match_found = False
+               installed_match = vardb.match(x)
+               for installed in installed_match:
+                       mypkgs.append((installed, "installed"))
+                       match_found = True
+
+               if match_found:
+                       continue
+
+               for db, pkg_type in ((portdb, "ebuild"), (bindb, "binary")):
+                       if pkg_type == "binary" and "--usepkg" not in myopts:
+                               continue
+
+                       matches = db.match(x)
+                       matches.reverse()
+                       for match in matches:
+                               if pkg_type == "binary":
+                                       if db.bintree.isremote(match):
+                                               continue
+                               auxkeys = ["EAPI", "DEFINED_PHASES"]
+                               metadata = dict(zip(auxkeys, db.aux_get(match, auxkeys)))
+                               if metadata["EAPI"] not in ("0", "1", "2", "3") and \
+                                       "info" in metadata["DEFINED_PHASES"].split():
+                                       mypkgs.append((match, pkg_type))
+                                       break
 
        # If some packages were found...
        if mypkgs:
@@ -1345,16 +1372,31 @@ def action_info(settings, trees, myopts, myfiles):
                print(header_width * "=")
                from portage.output import EOutput
                out = EOutput()
-               for cpv in mypkgs:
+               for mypkg in mypkgs:
+                       cpv = mypkg[0]
+                       pkg_type = mypkg[1]
                        # Get all package specific variables
-                       metadata = dict(zip(auxkeys, vardb.aux_get(cpv, auxkeys)))
-                       pkg = Package(built=True, cpv=cpv,
-                               installed=True, metadata=zip(Package.metadata_keys,
+                       if pkg_type == "installed":
+                               metadata = dict(zip(auxkeys, vardb.aux_get(cpv, auxkeys)))
+                       elif pkg_type == "ebuild":
+                               metadata = dict(zip(auxkeys, portdb.aux_get(cpv, auxkeys)))
+                       elif pkg_type == "binary":
+                               metadata = dict(zip(auxkeys, bindb.aux_get(cpv, auxkeys)))
+
+                       pkg = Package(built=(pkg_type!="ebuild"), cpv=cpv,
+                               installed=(pkg_type=="installed"), metadata=zip(Package.metadata_keys,
                                (metadata.get(x, '') for x in Package.metadata_keys)),
-                               root_config=root_config, type_name='installed')
-
-                       print("\n%s was built with the following:" % \
-                               colorize("INFORM", str(pkg.cpv)))
+                               root_config=root_config, type_name=pkg_type)
+
+                       if pkg_type == "installed":
+                               print("\n%s was built with the following:" % \
+                                       colorize("INFORM", str(pkg.cpv)))
+                       elif pkg_type == "ebuild":
+                               print("\n%s would be build with the following:" % \
+                                       colorize("INFORM", str(pkg.cpv)))
+                       elif pkg_type == "binary":
+                               print("\n%s (non-installed binary) was built with the following:" % \
+                                       colorize("INFORM", str(pkg.cpv)))
 
                        pkgsettings.setcpv(pkg)
                        forced_flags = set(chain(pkgsettings.useforce,
@@ -1406,10 +1448,10 @@ def action_info(settings, trees, myopts, myfiles):
                                        flags.sort(key=UseFlagDisplay.sort_separated)
                                print('%s="%s"' % (varname, ' '.join(str(f) for f in flags)), end=' ')
                        print()
-
-                       for myvar in mydesiredvars:
-                               if metadata[myvar].split() != settings.get(myvar, '').split():
-                                       print("%s=\"%s\"" % (myvar, metadata[myvar]))
+                       if pkg_type == "installed":
+                               for myvar in mydesiredvars:
+                                       if metadata[myvar].split() != settings.get(myvar, '').split():
+                                               print("%s=\"%s\"" % (myvar, metadata[myvar]))
                        print()
 
                        if metadata['DEFINED_PHASES']:
@@ -1417,14 +1459,41 @@ def action_info(settings, trees, myopts, myfiles):
                                        continue
 
                        print(">>> Attempting to run pkg_info() for '%s'" % pkg.cpv)
-                       ebuildpath = vardb.findname(pkg.cpv)
+
+                       if pkg_type == "installed":
+                               ebuildpath = vardb.findname(pkg.cpv)
+                       elif pkg_type == "ebuild":
+                               ebuildpath = portdb.findname(pkg.cpv)
+                       elif pkg_type == "binary":
+                               tbz2_file = bindb.bintree.getname(pkg.cpv)
+                               ebuild_file_name = pkg.cpv.split("/")[1] + ".ebuild"
+                               ebuild_file_contents = portage.xpak.tbz2(tbz2_file).getfile(ebuild_file_name)
+                               tmpdir = tempfile.mkdtemp()
+                               ebuildpath = os.path.join(tmpdir, ebuild_file_name)
+                               file = open(ebuildpath, 'w')
+                               file.write(ebuild_file_contents)
+                               file.close()
+
                        if not ebuildpath or not os.path.exists(ebuildpath):
                                out.ewarn("No ebuild found for '%s'" % pkg.cpv)
                                continue
-                       portage.doebuild(ebuildpath, "info", pkgsettings["ROOT"],
-                               pkgsettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1),
-                               mydbapi=trees[settings["ROOT"]]["vartree"].dbapi,
-                               tree="vartree")
+
+                       if pkg_type == "installed":
+                               portage.doebuild(ebuildpath, "info", pkgsettings["ROOT"],
+                                       pkgsettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1),
+                                       mydbapi=trees[settings["ROOT"]]["vartree"].dbapi,
+                                       tree="vartree")
+                       elif pkg_type == "ebuild":
+                               portage.doebuild(ebuildpath, "info", pkgsettings["ROOT"],
+                                       pkgsettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1),
+                                       mydbapi=trees[settings["ROOT"]]["porttree"].dbapi,
+                                       tree="porttree")
+                       elif pkg_type == "binary":
+                               portage.doebuild(ebuildpath, "info", pkgsettings["ROOT"],
+                                       pkgsettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1),
+                                       mydbapi=trees[settings["ROOT"]]["bintree"].dbapi,
+                                       tree="bintree")
+                               shutil.rmtree(tmpdir)
 
 def action_metadata(settings, portdb, myopts, porttrees=None):
        if porttrees is None:
index 3e89e2905565c550a3ec3db5003653da3ffec555..21888f590ca8a2fc3d0d0f6c55e14f69f60cc31f 100644 (file)
@@ -1498,12 +1498,21 @@ def emerge_main():
 
                # Ensure atoms are valid before calling unmerge().
                vardb = trees[settings["ROOT"]]["vartree"].dbapi
+               portdb = trees[settings["ROOT"]]["porttree"].dbapi
+               bindb = trees[settings["ROOT"]]["bintree"].dbapi
                valid_atoms = []
                for x in myfiles:
                        if is_valid_package_atom(x):
                                try:
-                                       valid_atoms.append(
-                                               dep_expand(x, mydb=vardb, settings=settings))
+                                       #look at the installed files first, if there is no match
+                                       #look at the ebuilds, since EAPI 4 allows running pkg_info
+                                       #on non-installed packages
+                                       valid_atom = dep_expand(x, mydb=vardb, settings=settings)
+                                       if valid_atom.cp.split("/")[0] == "null":
+                                               valid_atom = dep_expand(x, mydb=portdb, settings=settings)
+                                       if valid_atom.cp.split("/")[0] == "null" and "--usepkg" in myopts:
+                                               valid_atom = dep_expand(x, mydb=bindb, settings=settings)
+                                       valid_atoms.append(valid_atom)
                                except portage.exception.AmbiguousPackageName as e:
                                        msg = "The short ebuild name \"" + x + \
                                                "\" is ambiguous.  Please specify " + \