Skip to content

tools: add tap output to cpplint #3448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 12, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 48 additions & 11 deletions tools/cpplint.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python2.4
#!/usr/bin/env python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I care much, but this wouldn't work on Arch Linux where python is python3.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think python2.4 would work much better :) Just pulled the same convention as what we have in configure and tools/test.py -- would personally have gone with python2 but +1 for consistency.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, right. I have a python2 and a python2.7. python2 would also have been my choice, but whatever is consistent is fine.

#
# Copyright (c) 2009 Google Inc. All rights reserved.
#
Expand Down Expand Up @@ -88,7 +88,8 @@
import string
import sys
import unicodedata

import logging
logger = logging.getLogger('testrunner')

_USAGE = """
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
Expand Down Expand Up @@ -139,6 +140,9 @@
the top-level categories like 'build' and 'whitespace' will
also be printed. If 'detailed' is provided, then a count
is provided for each category like 'build/class'.

logfile=filename
Write TAP output to a logfile.
"""

# We categorize each error message we print. Here are the categories.
Expand Down Expand Up @@ -541,6 +545,11 @@ def SetFilters(self, filters):
raise ValueError('Every filter in --filters must start with + or -'
' (%s does not)' % filt)

def setOutputFile(self, filename):
"""attempts to create a file which we write output to."""
fh = logging.FileHandler(filename, mode='wb')
logger.addHandler(fh)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we set the log level here? By default, it will be printing only the warnings, right?

Edit: NVM. I see that you have done this at line 3124


def ResetErrorCounts(self):
"""Sets the module's error statistic back to zero."""
self.error_count = 0
Expand All @@ -558,10 +567,11 @@ def IncrementErrorCount(self, category):

def PrintErrorCounts(self):
"""Print a summary of errors by category, and the total."""
for category, count in self.errors_by_category.iteritems():
sys.stderr.write('Category \'%s\' errors found: %d\n' %
(category, count))
sys.stderr.write('Total errors found: %d\n' % self.error_count)
if not _cpplint_state.output_format == 'tap':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any specific reason to use this instead of if _cpplint_state.output_format != 'tap':?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope

for category, count in self.errors_by_category.iteritems():
sys.stderr.write('Category \'%s\' errors found: %d\n' %
(category, count))
sys.stderr.write('Total errors found: %d\n' % self.error_count)

_cpplint_state = _CppLintState()

Expand Down Expand Up @@ -608,6 +618,9 @@ def _SetFilters(filters):
"""
_cpplint_state.SetFilters(filters)

def _setOutputFile(filename):
_cpplint_state.setOutputFile(filename)


class _FunctionState(object):
"""Tracks current function name and the number of lines in its body."""
Expand Down Expand Up @@ -786,6 +799,15 @@ def Error(filename, linenum, category, confidence, message):
if _cpplint_state.output_format == 'vs7':
sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
filename, linenum, message, category, confidence))
elif _cpplint_state.output_format == 'tap':
template = ('not ok %s\n'
' ---\n'
' message: %s\n'
' data:\n'
' line: %d\n'
' ruleId: %s\n'
' ...')
logger.info(template % (filename, message, linenum, category))
else:
sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
filename, linenum, message, category, confidence))
Expand Down Expand Up @@ -2069,7 +2091,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, error):
initial_spaces += 1
if line and line[-1].isspace():
error(filename, linenum, 'whitespace/end_of_line', 4,
'Line ends in whitespace. Consider deleting these extra spaces.')
'Line ends in whitespace. Consider deleting these extra spaces.')
# There are certain situations we allow one space, notably for labels
elif ((initial_spaces == 1 or initial_spaces == 3) and
not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
Expand Down Expand Up @@ -3002,7 +3024,8 @@ def ProcessFile(filename, vlevel):
'One or more unexpected \\r (^M) found;'
'better to use only a \\n')

sys.stderr.write('Done processing %s\n' % filename)
if not _cpplint_state.output_format == 'tap':
sys.stderr.write('Done processing %s\n' % filename)


def PrintUsage(message):
Expand Down Expand Up @@ -3041,21 +3064,23 @@ def ParseArguments(args):
try:
(opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
'counting=',
'filter='])
'filter=',
'logfile='])
except getopt.GetoptError:
PrintUsage('Invalid arguments.')

verbosity = _VerboseLevel()
output_format = _OutputFormat()
filters = ''
counting_style = ''
output_filename = ''

for (opt, val) in opts:
if opt == '--help':
PrintUsage(None)
elif opt == '--output':
if not val in ('emacs', 'vs7'):
PrintUsage('The only allowed output formats are emacs and vs7.')
if not val in ('emacs', 'vs7', 'tap'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better way to write this would be if val not in ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

PrintUsage('The only allowed output formats are emacs, vs7 and tap.')
output_format = val
elif opt == '--verbose':
verbosity = int(val)
Expand All @@ -3067,6 +3092,8 @@ def ParseArguments(args):
if val not in ('total', 'toplevel', 'detailed'):
PrintUsage('Valid counting options are total, toplevel, and detailed')
counting_style = val
elif opt == '--logfile':
output_filename = val

if not filenames:
PrintUsage('No files were specified.')
Expand All @@ -3075,6 +3102,8 @@ def ParseArguments(args):
_SetVerboseLevel(verbosity)
_SetFilters(filters)
_SetCountingStyle(counting_style)
if output_filename:
_setOutputFile(output_filename)

return filenames

Expand All @@ -3089,6 +3118,14 @@ def main():
codecs.getwriter('utf8'),
'replace')


ch = logging.StreamHandler(sys.stdout)
logger.addHandler(ch)
logger.setLevel(logging.INFO)

if _cpplint_state.output_format == 'tap':
logger.info('TAP version 13')

_cpplint_state.ResetErrorCounts()
for filename in filenames:
ProcessFile(filename, _cpplint_state.verbose_level)
Expand Down