From cf1d139137a6fa898384665515f4992c5934801f Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Tue, 2 Oct 2007 04:03:12 +0000 Subject: [PATCH] Filter some false positives out of the EbuildQuote check. It might work well enough now so that we don't have to degrade it to a warning. svn path=/main/trunk/; revision=7901 --- pym/repoman/checks.py | 61 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py index 7ec670804..de7ceee23 100644 --- a/pym/repoman/checks.py +++ b/pym/repoman/checks.py @@ -118,10 +118,15 @@ class EbuildQuote(ContentCheck): """Ensure ebuilds have valid quoting around things like D,FILESDIR, etc...""" repoman_check_name = 'ebuild.minorsyn' - - missing_quotes = re.compile(r'[^"]\${?(D|S|T|ROOT|FILESDIR|WORKDIR)}?\W') - missing_quotes_exclude = re.compile(r'\[\[.*[^"]\${?(D|S|T|ROOT|FILESDIR|WORKDIR)}?\W.*\]\]') - ignore_line = re.compile(r'(^$)|(^(\t)*#)') + ignore_line = re.compile(r'(^$)|(^\s*#.*)') + var_names = r'(D|S|T|ROOT|FILESDIR|WORKDIR)' + var_reference = re.compile(r'\$({'+var_names+'}|' + \ + r'\$' + var_names + '\W)') + missing_quotes = re.compile(r'(\s|^)[^"\s]*\${?' + var_names + \ + r'}?[^"\s]*(\s|$)') + var_assignment = re.compile(r'^\s*\w*=.*') + cond_begin = re.compile(r'(^|\s+)\[\[($|\\$|\s+)') + cond_end = re.compile(r'(^|\s+)\]\]($|\\$|\s+)') def __init__(self, contents): ContentCheck.__init__(self, contents) @@ -133,16 +138,46 @@ class EbuildQuote(ContentCheck): errors = [] for num, line in enumerate(self.contents): - match = self.ignore_line.match(line) - if match: + if self.ignore_line.match(line) is not None: + continue + if self.var_reference.search(line) is None: continue - missing_quotes_line = self.missing_quotes.search(line) - if missing_quotes_line: - for group in missing_quotes_line.group(): - match = self.missing_quotes_exclude.search(group) - if not match: - errors.append((num + 1, MISSING_QUOTES_ERROR)) - break + # There can be multiple matches / violations on a single line. We + # have to make sure none of the matches are violators. Once we've + # found one violator, any remaining matches on the same line can + # be ignored. + pos = 0 + while pos <= len(line) - 1: + missing_quotes = self.missing_quotes.search(line, pos) + if not missing_quotes: + break + # If the last character of the previous match is a whitespace + # character, that character may be needed for the next + # missing_quotes match, so search overlaps by 1 character. + group = missing_quotes.group() + pos = missing_quotes.end() - 1 + + # Filter out some false positives that can + # get through the missing_quotes regex. + if self.var_reference.search(group) is None: + continue + if self.var_assignment.search(group) is not None: + continue + + # This is an attempt to avoid false positives without getting + # too complex, while possibly allowing some (hopefully + # unlikely) violations to slip through. We just assume + # everything is correct if the there is a ' [[ ' or a ' ]] ' + # anywhere in the whole line (possibly continued over one + # line). + if self.cond_begin.search(line) is not None: + continue + if self.cond_end.search(line) is not None: + continue + + errors.append((num + 1, MISSING_QUOTES_ERROR)) + # Any remaining matches on the same line can be ignored. + break return errors -- 2.26.2