refactor: use object inheritance for the formaters

pull/442/head
QuentinN42 3 years ago
parent c4463c706f
commit 6217241fec
No known key found for this signature in database
GPG Key ID: 2CD7D563712B3A50

@ -118,7 +118,7 @@ def run(argv=None):
except EnvironmentError as e:
print(e, file=sys.stderr)
sys.exit(-1)
all_problems[file] = problems
all_problems[file] = [pb for pb in problems if pb]
if args.stdin:
# read yaml from stdin
@ -127,7 +127,7 @@ def run(argv=None):
except EnvironmentError as e:
print(e, file=sys.stderr)
sys.exit(-1)
all_problems['stdin'] = problems
all_problems['stdin'] = [pb for pb in problems if pb]
max_level = show_all_problems(
all_problems,

@ -17,29 +17,149 @@ def supports_color():
hasattr(sys.stdout, 'isatty') and sys.stdout.isatty())
class Format(object):
@staticmethod
def parsable(problem, filename):
return ('%(file)s:%(line)s:%(column)s: [%(level)s] %(message)s' %
{'file': filename,
'line': problem.line,
'column': problem.column,
'level': problem.level,
'message': problem.message})
@staticmethod
def standard(problem, filename):
line = ' %d:%d' % (problem.line, problem.column)
line += max(12 - len(line), 0) * ' '
def run_on_gh():
"""Return if the currnet job is on github."""
return 'GITHUB_ACTIONS' in os.environ and 'GITHUB_WORKFLOW' in os.environ
class Formater(object):
"""Any formater."""
# the formater name
name = ''
@classmethod
def get_formater(cls, name, no_warn):
"""Return a formater instance."""
if name == 'auto':
if run_on_gh():
name = 'github'
elif supports_color():
name = 'colored'
else:
name = 'standard'
for formater in cls.__subclasses__():
if name == formater.name:
return formater(no_warn)
raise ValueError('unknown formater: %s' % name)
def __init__(self, no_warn):
"""Setup the formater."""
self.no_warn = no_warn
def show_problems_for_all_files(self, all_problems):
"""Show all problems of all files."""
raise NotImplementedError()
def show_problems_for_file(self, problems, file):
"""Show all problems of a specific file."""
raise NotImplementedError()
def show_problem(self, problem, file):
"""Show all problems of a specific file."""
raise NotImplementedError()
class ParsableFormater(Formater):
"""The parsable formater."""
name = 'parsable'
def show_problems_for_all_files(self, all_problems):
"""Show all problems of all files."""
string = ''
for file, problems in all_problems.items():
string += self.show_problems_for_file(problems, file)
return string
def show_problems_for_file(self, problems, file):
"""Show all problems of a specific file."""
string = ''
for problem in problems:
string += self.show_problem(problem, file)
return string
def show_problem(self, problem, file):
"""Show all problems of a specific file."""
if self.no_warn and (problem.level != 'error'):
return ''
return (
'%(file)s:%(line)s:%(column)s: [%(level)s] %(message)s\n' %
{
'file': file,
'line': problem.line,
'column': problem.column,
'level': problem.level,
'message': problem.message
}
)
class GithubFormater(Formater):
"""The parsable formater."""
name = 'github'
def show_problems_for_all_files(self, all_problems):
"""Show all problems of all files."""
string = ''
for file, problems in all_problems.items():
string += self.show_problems_for_file(problems, file)
return string
def show_problems_for_file(self, problems, file):
"""Show all problems of a specific file."""
string = '::group::%s\n' % file
for problem in problems:
string += self.show_problem(problem, file)
if string == '::group::%s\n' % file:
return ''
return string + '::endgroup::\n\n'
def show_problem(self, problem, file):
"""Show all problems of a specific file."""
if self.no_warn and (problem.level != 'error'):
return ''
line = '::'
line += problem.level
line += max(21 - len(line), 0) * ' '
line += problem.desc
line += ' file=' + file + ','
line += 'line=' + format(problem.line) + ','
line += 'col=' + format(problem.column)
line += '::'
line += format(problem.line)
line += ':'
line += format(problem.column)
line += ' '
if problem.rule:
line += ' (%s)' % problem.rule
line += '[' + problem.rule + '] '
line += problem.desc
line += '\n'
return line
@staticmethod
def standard_color(problem, filename):
class ColoredFormater(Formater):
"""The parsable formater."""
name = 'colored'
def show_problems_for_all_files(self, all_problems):
"""Show all problems of all files."""
string = ''
for file, problems in all_problems.items():
string += self.show_problems_for_file(problems, file)
return string
def show_problems_for_file(self, problems, file):
"""Show all problems of a specific file."""
string = '\033[4m%s\033[0m\n' % file
for problem in problems:
string += self.show_problem(problem, file)
if string == '\033[4m%s\033[0m\n' % file:
return ''
return string + '\n'
def show_problem(self, problem, file):
"""Show all problems of a specific file."""
if self.no_warn and (problem.level != 'error'):
return ''
line = ' \033[2m%d:%d\033[0m' % (problem.line, problem.column)
line += max(20 - len(line), 0) * ' '
if problem.level == 'warning':
@ -50,73 +170,58 @@ class Format(object):
line += problem.desc
if problem.rule:
line += ' \033[2m(%s)\033[0m' % problem.rule
line += '\n'
return line
@staticmethod
def github(problem, filename):
line = '::'
class StandardFormater(Formater):
"""The parsable formater."""
name = 'standard'
def show_problems_for_all_files(self, all_problems):
"""Show all problems of all files."""
string = ''
for file, problems in all_problems.items():
string += self.show_problems_for_file(problems, file)
return string
def show_problems_for_file(self, problems, file):
"""Show all problems of a specific file."""
string = file + '\n'
for problem in problems:
string += self.show_problem(problem, file)
if string == file + '\n':
return ''
return string + '\n'
def show_problem(self, problem, file):
"""Show all problems of a specific file."""
if self.no_warn and (problem.level != 'error'):
return ''
line = ' %d:%d' % (problem.line, problem.column)
line += max(12 - len(line), 0) * ' '
line += problem.level
line += ' file=' + filename + ','
line += 'line=' + format(problem.line) + ','
line += 'col=' + format(problem.column)
line += '::'
line += format(problem.line)
line += ':'
line += format(problem.column)
line += ' '
if problem.rule:
line += '[' + problem.rule + '] '
line += max(21 - len(line), 0) * ' '
line += problem.desc
if problem.rule:
line += ' (%s)' % problem.rule
line += '\n'
return line
def show_problems(problems, file, args_format, no_warn):
first = True
if args_format == 'auto':
if ('GITHUB_ACTIONS' in os.environ and
'GITHUB_WORKFLOW' in os.environ):
args_format = 'github'
elif supports_color():
args_format = 'colored'
for problem in problems:
if no_warn and (problem.level != 'error'):
continue
if args_format == 'parsable':
print(Format.parsable(problem, file))
elif args_format == 'github':
if first:
print('::group::%s' % file)
first = False
print(Format.github(problem, file))
elif args_format == 'colored':
if first:
print('\033[4m%s\033[0m' % file)
first = False
print(Format.standard_color(problem, file))
else:
if first:
print(file)
first = False
print(Format.standard(problem, file))
if not first and args_format == 'github':
print('::endgroup::')
if not first and args_format != 'parsable':
print('')
def max_level(problems):
def max_level(all_problems):
"""Return the max level of all problems."""
return max(PROBLEM_LEVELS[problem.level] for problem in problems)
all_levels = [problem.level for problems in all_problems.values() for problem in problems]
if all_levels:
return max(map(lambda x: PROBLEM_LEVELS[x], all_levels))
return 0
def show_all_problems(all_problems, args_format, no_warn):
"""Print all problems, return the max level."""
for file, problem in all_problems.items():
show_problems(problem, file, args_format, no_warn)
fmt = Formater.get_formater(args_format, no_warn)
print(fmt.show_problems_for_all_files(all_problems), end='')
return max_level(all_problems)

Loading…
Cancel
Save