From 82f4e2a922429111e3abfb6bb2849fcc1b4ec134 Mon Sep 17 00:00:00 2001 From: Alec Warner Date: Mon, 1 Oct 2007 10:20:32 +0000 Subject: [PATCH] Add Donnie's quote check, refactor other ebuild-content checks into classes and get them out of repoman in an attempt to start moving other checks out as well. Again wonder at the price of StringIO and N passes, is the readability worth it? svn path=/main/trunk/; revision=7895 --- bin/repoman | 99 ++++++++++++++++++----------------------------------- 1 file changed, 34 insertions(+), 65 deletions(-) diff --git a/bin/repoman b/bin/repoman index 9e78a964f..28b68dab8 100755 --- a/bin/repoman +++ b/bin/repoman @@ -20,6 +20,11 @@ try: except ImportError: import pickle +try: + import cStringIO as StringIO +except ImportError: + import StringIO + if not hasattr(__builtins__, "set"): from sets import Set as set @@ -38,10 +43,19 @@ try: import portage except ImportError: from os import path as osp - sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")) + sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 'pym')) import portage del os.environ["PORTAGE_LEGACY_GLOBALS"] +try: + from repoman.checks import EbuildWhitespaceCheck, EbuildHeaderCheck, EbuildQuoteCheck, \ + EbuildAssignmentCheck +except ImportError: + from os import path as osp + sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 'pym')) + from repoman.checks import EbuildWhitespaceCheck, EbuildHeaderCheck, EbuildQuoteCheck, \ + EbuildAssignmentCheck + import portage.checksum import portage.const import portage.dep @@ -1322,71 +1336,26 @@ for x in scanlist: stats["RESTRICT.invalid"] += len(mybadrestrict) for mybad in mybadrestrict: fails["RESTRICT.invalid"].append(x+"/"+y+".ebuild: %s" % mybad) + # Syntax Checks + path = checkdir + '/' + y + '.ebuild' + myear = time.gmtime(os.stat(path)[ST_MTIME])[0] + file_contents = open(path, 'rb').readlines() + contents = StringIO.StringIO(''.join(file_contents)) + for check in (EbuildWhitespaceCheck, EbuildQuoteCheck, EbuildAssignmentCheck): + c = check(contents) + errors = c.Run() + for e in errors: + stats[c.repoman_check_name] += 1 + fails[c.repoman_check_name].append(x + '/' + y + '.ebuild: %s' % e[1] % e[0]) + contents.seek(0) # move fp to the beginning of the StringIO Object + del check + check = EbuildHeaderCheck(contents, str(myear)) + errors = check.Run() + for e in errors: + stats[check.repoman_check_name] += 1 + fails[check.repoman_check_name].append(x + '/' + y + '.ebuild: %s' % e[1] % e[0]) + del check, errors - #syntax checks - myear = time.gmtime(os.stat(checkdir+"/"+y+".ebuild")[ST_MTIME])[0] - gentoo_copyright = re.compile(r'^# Copyright ((1999|200\d)-)?' + str(myear) + r' Gentoo Foundation') - gentoo_license = re.compile(r'^# Distributed under the terms of the GNU General Public License v2$') - cvs_header = re.compile(r'^#\s*\$Header.*\$$') - ignore_line = re.compile(r'(^$)|(^(\t)*#)') - leading_spaces = re.compile(r'^[\S\t]') - trailing_whitespace = re.compile(r'.*([\S]$)') - readonly_assignment = re.compile(r'^\s*(export\s+)?(A|CATEGORY|P|PV|PN|PR|PVR|PF|D|WORKDIR|FILESDIR|FEATURES|USE)=') - line_continuation = re.compile(r'([^#]*\S)(\s+|\t)\\$') - linenum=0 - previous_line = None - for line in input(checkdir+"/"+y+".ebuild"): - linenum += 1 - # Gentoo copyright check - if linenum == 1: - match = gentoo_copyright.match(line) - if not match: - myerrormsg = "Copyright header Error. Possibly date related." - stats["ebuild.badheader"] +=1 - fails["ebuild.badheader"].append(x+"/"+y+".ebuild: %s" % myerrormsg) - # Gentoo license check - elif linenum == 2: - match = gentoo_license.match(line) - if not match: - myerrormsg = "Gentoo License Error." - stats["ebuild.badheader"] +=1 - fails["ebuild.badheader"].append(x+"/"+y+".ebuild: %s" % myerrormsg) - # CVS Header check - elif linenum == 3: - match = cvs_header.match(line) - if not match: - myerrormsg = "CVS Header Error." - stats["ebuild.badheader"] +=1 - fails["ebuild.badheader"].append(x+"/"+y+".ebuild: %s" % myerrormsg) - else: - match = ignore_line.match(line) - if not match: - # Excluded Blank lines and full line comments. Good! - # Leading Spaces Check - match = leading_spaces.match(line) - if not match: - #Line has got leading spaces. Bad! - myerrormsg = "Leading Space Syntax Error. Line %d" % linenum - stats["ebuild.minorsyn"] +=1 - fails["ebuild.minorsyn"].append(x+"/"+y+".ebuild: %s" % myerrormsg) - # Trailing whitespace check - match = trailing_whitespace.match(line) - if not match: - #Line has got trailing whitespace. Bad! - myerrormsg = "Trailing whitespace Syntax Error. Line %d" % linenum - stats["ebuild.minorsyn"] +=1 - fails["ebuild.minorsyn"].append(x+"/"+y+".ebuild: %s" % myerrormsg) - # Readonly variable assignment check - match = readonly_assignment.match(line) - # The regex can give a false positive for continued lines, - # so we check the previous line to see if it was continued. - if match and (not previous_line or not line_continuation.match(previous_line)): - # invalid assignment, very bad! - myerrormsg = "Readonly variable assignment to %s on line %d" % (match.group(2), linenum) - stats["variable.readonly"] += 1 - fails["variable.readonly"].append(x+"/"+y+".ebuild: %s" % myerrormsg) - previous_line = line - del previous_line if "--force" in myoptions: # The dep_check() calls are the most expensive QA test. If --force -- 2.26.2