diff --git a/panc/src/main/scripts/panlint/panlint.py b/panc/src/main/scripts/panlint/panlint.py index 29a242df..81e75029 100755 --- a/panc/src/main/scripts/panlint/panlint.py +++ b/panc/src/main/scripts/panlint/panlint.py @@ -93,6 +93,7 @@ def __str__(self): RE_COMMENT = re.compile(RS_COMMENT) RE_COMMENT_LINE = re.compile(r'^\s*' + RS_COMMENT + '.*$') RE_ANNOTATION = re.compile(r'@\w*\s*{.*?}', re.S) +RE_MAGIC_LINE = re.compile(r'^\s*#\s+panlint\s+disable=(?P(?:[A-Z]{2}[0-9]{3},?)+)$') # Deal with heredoc as fake operator incl tag (so no bitshift). Will ignore it in the code. # The order here is important: the < at the end must remain at the end or linting heredocs will fail. RE_OPERATOR = re.compile(r'([>=+*=/-]|<<\w+(?!;)|<)') @@ -588,21 +589,41 @@ def lint_file(filename, allow_mvn_templates=False, ignore_components=None, suppr # If so, regard the component config as being included components_included.union(get_components_from_filename(filename)) + # Start out with no check suppression + suppressors = set() + for line_number, line_text in enumerate(raw_text.splitlines(), start=1): line = Line(filename, line_number, line_text.rstrip('\n')) - if line.text and line.number not in ignore_lines and not RE_COMMENT_LINE.match(line.text): - line, first_line = lint_line( - line, - components_included, - first_line, - allow_mvn_templates, - suppress, - ) - - if line.problems: - problem_lines.append(line) - file_problem_count += len(line.problems) + if line.text and line.number not in ignore_lines: + magic = RE_MAGIC_LINE.match(line_text) + comment = RE_COMMENT_LINE.match(line_text) + + if magic: + debug_line(line) + debug_range(magic.start('id'), magic.end('id'), 'Magic String', line) + # Currently the only supported magic is to suppress certain checks for the next line of real Pan + suppressors = set(magic.group('id').split(',')) + + elif not comment: + # Not magic, not a comment, so must be real code... lint it! + line, first_line = lint_line( + line, + components_included, + first_line, + allow_mvn_templates, + suppress, + ) + + # Filter out any suppressed problems + line.problems = [p for p in line.problems if p.message.id not in suppressors] + + if line.problems: + problem_lines.append(line) + file_problem_count += len(line.problems) + + # We've just processed a real line, so wipe out any suppression + suppressors = set() else: debug_ignored_line(line) diff --git a/panc/src/main/scripts/panlint/test_files/test_good_suppression.pan b/panc/src/main/scripts/panlint/test_files/test_good_suppression.pan new file mode 100644 index 00000000..bb1f6402 --- /dev/null +++ b/panc/src/main/scripts/panlint/test_files/test_good_suppression.pan @@ -0,0 +1,22 @@ +template bob.org; + +variable WHYYY = -102; + +# panlint disable=LP011,LC001 +# we think we know better than panlint +variable x= bob[-4]; + +# this is a comment explaining that bob is a great host +# panlint disable=PP001 +'/system/hostname/' = 'bob.foo.org'; + +# panlint disable=CU001, +'/software/components/chkconfig/service/rdma' = dict(); + +# panlint disable=CU001 + +prefix '/software/components/metaconfig/services/{/etc/sysconfig/fetch-crl}'; + +# panlint disable=LP006 +# We know this line is long, but it's unavoidable +variable SUPER_DUPER_LONG_LINE = 'sdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff892342342342943 234902342934 90234 90234 234 44444444444444444444444444444444444444444444';