output-format: Add support for Checkstyle format

Checkstyle format is useful to CI toots that support it to display the
linting results in a nice way.
pull/419/head
Hunts Chen 4 years ago
parent f2e2e0c366
commit 9fd4f79b06

@ -22,6 +22,7 @@ import locale
import os import os
import platform import platform
import sys import sys
from xml.sax.saxutils import escape
from yamllint import APP_DESCRIPTION, APP_NAME, APP_VERSION from yamllint import APP_DESCRIPTION, APP_NAME, APP_VERSION
from yamllint import linter from yamllint import linter
@ -98,17 +99,31 @@ class Format(object):
line += problem.desc line += problem.desc
return line return line
@staticmethod
def checkstyle(problem):
line = ' <error line="%d" column="%d" severity="%s"' % (
problem.line, problem.column, problem.level)
if problem.rule:
line += ' source="%s"' % problem.rule
line += ' "message="%s"/>' % escape(problem.desc)
return line
def show_problems(problems, file, args_format, no_warn): def show_problems(problems, file, args_format, no_warn):
max_level = 0 max_level = 0
first = True first = True
if args_format == 'checkstyle':
print(' <file name="%s">' % file)
for problem in problems: for problem in problems:
max_level = max(max_level, PROBLEM_LEVELS[problem.level]) max_level = max(max_level, PROBLEM_LEVELS[problem.level])
if no_warn and (problem.level != 'error'): if no_warn and (problem.level != 'error'):
continue continue
if args_format == 'parsable': if args_format == 'parsable':
print(Format.parsable(problem, file)) print(Format.parsable(problem, file))
elif args_format == 'checkstyle':
print(Format.checkstyle(problem))
elif args_format == 'github' or (args_format == 'auto' and elif args_format == 'github' or (args_format == 'auto' and
'GITHUB_ACTIONS' in os.environ and 'GITHUB_ACTIONS' in os.environ and
'GITHUB_WORKFLOW' in os.environ): 'GITHUB_WORKFLOW' in os.environ):
@ -128,6 +143,9 @@ def show_problems(problems, file, args_format, no_warn):
if not first and args_format != 'parsable': if not first and args_format != 'parsable':
print('') print('')
if args_format == 'checkstyle':
print(' </file>')
return max_level return max_level
@ -149,7 +167,7 @@ def run(argv=None):
help='custom configuration (as YAML source)') help='custom configuration (as YAML source)')
parser.add_argument('-f', '--format', parser.add_argument('-f', '--format',
choices=('parsable', 'standard', 'colored', 'github', choices=('parsable', 'standard', 'colored', 'github',
'auto'), 'checkstyle', 'auto'),
default='auto', help='format for parsing output') default='auto', help='format for parsing output')
parser.add_argument('-s', '--strict', parser.add_argument('-s', '--strict',
action='store_true', action='store_true',
@ -199,6 +217,10 @@ def run(argv=None):
max_level = 0 max_level = 0
if args.format == 'checkstyle':
print('<?xml version="1.0" encoding="UTF-8"?>')
print('<checkstyle version="5.0">')
for file in find_files_recursively(args.files, conf): for file in find_files_recursively(args.files, conf):
filepath = file[2:] if file.startswith('./') else file filepath = file[2:] if file.startswith('./') else file
try: try:
@ -222,6 +244,9 @@ def run(argv=None):
no_warn=args.no_warnings) no_warn=args.no_warnings)
max_level = max(max_level, prob_level) max_level = max(max_level, prob_level)
if args.format == 'checkstyle':
print('</checkstyle>')
if max_level == PROBLEM_LEVELS['error']: if max_level == PROBLEM_LEVELS['error']:
return_code = 1 return_code = 1
elif max_level == PROBLEM_LEVELS['warning']: elif max_level == PROBLEM_LEVELS['warning']:

Loading…
Cancel
Save