Merged from trunk 7913:7918
authorFabian Groffen <grobian@gentoo.org>
Fri, 5 Oct 2007 18:58:31 +0000 (18:58 -0000)
committerFabian Groffen <grobian@gentoo.org>
Fri, 5 Oct 2007 18:58:31 +0000 (18:58 -0000)
   | 7914    | Make repoman bail out if it is unable to properly access     |
   | zmedico | ebuild metadata for some reason. In this case it's           |
   |         | impossible to generate a Manifest and therefore the --force  |
   |         | option has to be disabled.                                   |

   | 7915    | Fix logic for the message that's show when --force is        |
   | zmedico | disabled.                                                    |

   | 7916    | Make portdbapi.getfetchlist() bail out if the EAPI is        |
   | zmedico | unsupported. This makes it impossible for an unsupported     |
   |         | EAPI to result in invalid Manifest generation.               |

   | 7917    | Include the package name in all exceptions raised from       |
   | zmedico | portdbapi.getfetchlist() so that a redundant and sometimes   |
   |         | inaccurate message doesn't have to be shown when the error   |
   |         | is caught in digestgen().                                    |

   | 7918    | Handle UnsupportedAPIException when running the ebuild(1)    |
   | zmedico | command.                                                     |

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

bin/ebuild
bin/repoman
man/repoman.1
pym/portage/__init__.py
pym/portage/dbapi/porttree.py

index 2dd02fe7cda0c92886e03d40061325aef011972f..14902dd6e6a8397f90d3bc3f52d90dcead0102c1 100755 (executable)
@@ -158,6 +158,7 @@ def stale_env_warning():
                        for x in msg:
                                portage.writemsg(">>> %s\n" % x)
 
+from portage.exception import UnsupportedAPIException
 checked_for_stale_env = False
 
 for arg in pargs:
@@ -178,6 +179,13 @@ for arg in pargs:
        except KeyError:
                # aux_get error
                a = 1
+       except UnsupportedAPIException, e:
+               from textwrap import wrap
+               msg = wrap(str(e), 70)
+               del e
+               for x in msg:
+                       portage.writemsg("!!! %s\n" % x, noiselevel=-1)
+               a = 1
        if a == None:
                print "Could not run the required binary?"
                a = 127
index 94699f1bdab4d679c28ae491c84c3aefef8dee27..d7dcd075b9fb888a4c4d6c0e28f31ba0f10c623a 100755 (executable)
@@ -8,10 +8,12 @@
 # that last one is tricky because multiple profiles need to be checked.
 
 import errno
+from itertools import izip
 import os
 import shutil
 import sys
 import signal
+import stat
 import re
 import tempfile
 
@@ -70,7 +72,10 @@ from portage.manifest import Manifest
 from portage.exception import ParseError
 from portage.process import find_binary, spawn
 
-from portage.output import bold, darkgreen, darkred, green, nocolor, red, turquoise, yellow
+from portage.output import bold, create_color_func, darkgreen, \
+       green, nocolor, red, turquoise, yellow
+
+bad = create_color_func("BAD")
 
 from commands import getstatusoutput
 from fileinput import input
@@ -169,6 +174,7 @@ qahelp={
        "KEYWORDS.stupid":"Ebuilds that use KEYWORDS=-* instead of package.mask", 
        "LICENSE.missing":"Ebuilds that have a missing or empty LICENSE variable",
        "DESCRIPTION.missing":"Ebuilds that have a missing or empty DESCRIPTION variable",
+       "EAPI.unsupported":"Ebuilds that have an unsupported EAPI version (you must upgrade portage)",
        "SLOT.missing":"Ebuilds that have a missing or empty SLOT variable",
        "HOMEPAGE.missing":"Ebuilds that have a missing or empty HOMEPAGE variable",
        "DEPEND.bad":"User-visible ebuilds with bad DEPEND settings (matched against *visible* ebuilds)",
@@ -258,6 +264,9 @@ for x in missingvars:
 valid_restrict = frozenset(["binchecks", "bindist", "fetch", "mirror",
        "primaryuri", "strip", "test", "userpriv"])
 
+# file.executable
+no_exec = frozenset(["Manifest","ChangeLog","metadata.xml"])
+
 verbose=0
 quiet=0
 
@@ -407,6 +416,11 @@ if mymode=="last" or (mymode=="lfull"):
 if mymode == "commit":
        myoptions.pop("--ignore-masked", None)
 
+# Set this to False when an extraordinary issue (generally
+# something other than a QA issue) makes it impossible to
+# commit (like if Manifest generation fails).
+can_force = True
+
 from portage import normalize_path
 isCvs=False
 if os.path.isdir("CVS"):
@@ -841,14 +855,40 @@ for x in scanlist:
 
        checkdirlist=os.listdir(checkdir)
        ebuildlist=[]
+       ebuild_metadata = {}
        for y in checkdirlist:
-               if y[-7:]==".ebuild":
-                       ebuildlist.append(y[:-7])
-               if y in ["Manifest","ChangeLog","metadata.xml"]:
-                       if os.stat(checkdir+"/"+y)[0] & 0x0248:
+               if y in no_exec and \
+                       stat.S_IMODE(os.stat(os.path.join(checkdir, y)).st_mode) & 0111:
                                stats["file.executable"] += 1
-                               fails["file.executable"].append(checkdir+"/"+y)
-       digestlist=[]
+                               fails["file.executable"].append(os.path.join(checkdir, y))
+               if y.endswith(".ebuild"):
+                       pf = y[:-7]
+                       ebuildlist.append(pf)
+                       cpv = "%s/%s" % (catdir, pf)
+                       try:
+                               myaux = dict(izip(allvars, portdb.aux_get(cpv, allvars)))
+                       except KeyError:
+                               stats["ebuild.syntax"] += 1
+                               fails["ebuild.syntax"].append(os.path.join(x, y))
+                               continue
+                       except IOError:
+                               stats["ebuild.output"] += 1
+                               fails["ebuild.output"].append(os.path.join(x, y))
+                               continue
+                       if not portage.eapi_is_supported(myaux["EAPI"]):
+                               stats["EAPI.unsupported"] += 1
+                               fails["EAPI.unsupported"].append(os.path.join(x, y))
+                               continue
+                       ebuild_metadata[pf] = myaux
+
+       if len(ebuild_metadata) != len(ebuildlist):
+               # If we can't access all the metadata then it's totally unsafe to
+               # commit since there's no way to generate a correct Manifest.
+               # Do not try to do any more QA checks on this package since missing
+               # metadata leads to false positives for several checks, and false
+               # positives confuse users.
+               can_force = False
+               continue
 
        for y in checkdirlist:
                for c in y.strip(os.path.sep):
@@ -1161,17 +1201,8 @@ for x in scanlist:
                        stats["ebuild.namenomatch"]=stats["ebuild.namenomatch"]+1
                        fails["ebuild.namenomatch"].append(x+"/"+y+".ebuild")
                        continue
-               try:
-                       myaux = dict(
-                               zip(allvars, portdb.aux_get(os.path.join(catdir, y), allvars)))
-               except KeyError:
-                       stats["ebuild.syntax"]=stats["ebuild.syntax"]+1
-                       fails["ebuild.syntax"].append(x+"/"+y+".ebuild")
-                       continue
-               except IOError:
-                       stats["ebuild.output"]=stats["ebuild.output"]+1
-                       fails["ebuild.output"].append(x+"/"+y+".ebuild")
-                       continue
+
+               myaux = ebuild_metadata[y]
 
                # Test for negative logic and bad words in the RESTRICT var.
                #for x in myaux[allvars.index("RESTRICT")].split():
@@ -1637,11 +1668,13 @@ if mymode!="commit":
        if quiet < 1:
                print
 elif "--pretend" not in myoptions:
-       if dofail and "--force" in myoptions and "--pretend" not in myoptions:
+       if dofail and can_force and "--force" in myoptions and "--pretend" not in myoptions:
                print green("RepoMan sez:") + \
                        " \"You want to commit even with these QA issues?\n" + \
                        "              I'll take it this time, but I'm not happy.\"\n"
        elif dofail:
+               if "--force" in myoptions and not can_force:
+                       print bad("The --force option has been disabled due to extraordinary issues.")
                print turquoise("Please fix these important QA issues first.")
                print green("RepoMan sez:"),"\"Make your QA payment on time and you'll never see the likes of me.\"\n"
                sys.exit(1)
index edbc7afd038b859536c6c5c0a8d97057144a491c..81d9e6a0884b94c34733d009fbed0f728d464e0e 100644 (file)
@@ -93,6 +93,9 @@ Syntax error in DEPEND (usually an extra/missing space/parenthesis)
 .B DESCRIPTION.missing
 Ebuilds that have a missing or empty DESCRIPTION variable
 .TP
+.B EAPI.unsupported
+Ebuilds that have an unsupported EAPI version (you must upgrade portage)
+.TP
 .B HOMEPAGE.missing
 Ebuilds that have a missing or empty HOMEPAGE variable
 .TP
index 8481620bc823681e203be915223c632859c13d7f..6d5a91a0d0209736d2be064d83e34fa5b12fda1d 100644 (file)
@@ -3074,7 +3074,6 @@ def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None
                                        distfiles_map.setdefault(myfile, []).append(cpv)
                        except portage.exception.InvalidDependString, e:
                                writemsg("!!! %s\n" % str(e), noiselevel=-1)
-                               writemsg("!!! Invalid SRC_URI for '%s'.\n" % cpv, noiselevel=-1)
                                del e
                                return 0
                mytree = os.path.dirname(os.path.dirname(mysettings["O"]))
index 83c568fa061969ca19d7aada6a77cb7c60ecd4e3..824d1afc437f5201071e741223b18409074c9320 100644 (file)
@@ -371,13 +371,21 @@ class portdbapi(dbapi):
                if mysettings is None:
                        mysettings = self.mysettings
                try:
-                       myuris = self.aux_get(mypkg, ["SRC_URI"], mytree=mytree)[0]
+                       eapi, myuris = self.aux_get(mypkg,
+                               ["EAPI", "SRC_URI"], mytree=mytree)
                except KeyError:
                        # Convert this to an InvalidDependString exception since callers
                        # already handle it.
                        raise portage.exception.InvalidDependString(
                                "getfetchlist(): aux_get() error reading "+mypkg+"; aborting.")
 
+               if not eapi_is_supported(eapi):
+                       # Convert this to an InvalidDependString exception
+                       # since callers already handle it.
+                       raise portage.exception.InvalidDependString(
+                               "getfetchlist(): '%s' has unsupported EAPI: '%s'" % \
+                               (mypkg, eapi.lstrip("-")))
+
                if useflags is None:
                        useflags = mysettings["USE"].split()
 
@@ -389,7 +397,9 @@ class portdbapi(dbapi):
                for x in newuris:
                        mya = os.path.basename(x)
                        if not mya:
-                               raise portage.exception.InvalidDependString("URI has no basename: '%s'" % x)
+                               raise portage.exception.InvalidDependString(
+                                       "getfetchlist(): '%s' SRC_URI has no file name: '%s'" % \
+                                       (mypkg, x))
                        if not mya in myfiles:
                                myfiles.append(mya)
                return [newuris, myfiles]