From ba1b5f5e4948c71d6ac233c0f445a500e285e9fa Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Fri, 5 Oct 2007 18:58:31 +0000 Subject: [PATCH] Merged from trunk 7913:7918 | 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 | 8 ++++ bin/repoman | 71 +++++++++++++++++++++++++---------- man/repoman.1 | 3 ++ pym/portage/__init__.py | 1 - pym/portage/dbapi/porttree.py | 14 ++++++- 5 files changed, 75 insertions(+), 22 deletions(-) diff --git a/bin/ebuild b/bin/ebuild index 2dd02fe7c..14902dd6e 100755 --- a/bin/ebuild +++ b/bin/ebuild @@ -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 diff --git a/bin/repoman b/bin/repoman index 94699f1bd..d7dcd075b 100755 --- a/bin/repoman +++ b/bin/repoman @@ -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) diff --git a/man/repoman.1 b/man/repoman.1 index edbc7afd0..81d9e6a08 100644 --- a/man/repoman.1 +++ b/man/repoman.1 @@ -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 diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 8481620bc..6d5a91a0d 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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"])) diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 83c568fa0..824d1afc4 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -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] -- 2.26.2