diff --git a/pyproject.toml b/pyproject.toml index 3d8f7d0..172b5ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ build-backend = "setuptools.build_meta" requires = ["setuptools >= 61"] [tool.setuptools] -packages = ["yamllint", "yamllint.conf", "yamllint.rules"] +packages = ["yamllint", "yamllint.conf", "yamllint.formatters", "yamllint.rules"] [tool.setuptools.package-data] yamllint = ["conf/*.yaml"] diff --git a/yamllint/cli.py b/yamllint/cli.py index 28286eb..ae84ac1 100644 --- a/yamllint/cli.py +++ b/yamllint/cli.py @@ -22,6 +22,7 @@ import sys from yamllint import APP_DESCRIPTION, APP_NAME, APP_VERSION from yamllint import linter from yamllint.config import YamlLintConfig, YamlLintConfigError +from yamllint.formatters import colored, github, parsable, standard from yamllint.linter import PROBLEM_LEVELS @@ -46,62 +47,7 @@ def supports_color(): hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()) -class Format: - @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) * ' ' - line += problem.level - line += max(21 - len(line), 0) * ' ' - line += problem.desc - if problem.rule: - line += ' (%s)' % problem.rule - return line - - @staticmethod - def standard_color(problem, filename): - line = ' \033[2m%d:%d\033[0m' % (problem.line, problem.column) - line += max(20 - len(line), 0) * ' ' - if problem.level == 'warning': - line += '\033[33m%s\033[0m' % problem.level - else: - line += '\033[31m%s\033[0m' % problem.level - line += max(38 - len(line), 0) * ' ' - line += problem.desc - if problem.rule: - line += ' \033[2m(%s)\033[0m' % problem.rule - return line - - @staticmethod - def github(problem, filename): - line = '::' - 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 += problem.desc - return line - - -def show_problems(results, args_format, no_warn): - max_level = 0 - +def show_results(results, args_format, no_warn): if args_format == 'auto': if ('GITHUB_ACTIONS' in os.environ and 'GITHUB_WORKFLOW' in os.environ): @@ -109,39 +55,14 @@ def show_problems(results, args_format, no_warn): elif supports_color(): args_format = 'colored' - for file in results: - first = True - - problems = results[file] - for problem in problems: - max_level = max(max_level, PROBLEM_LEVELS[problem.level]) - 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('') - - return max_level + if args_format == 'parsable': + return parsable.format_results(results, no_warn) + elif args_format == 'github': + return github.format_results(results, no_warn) + elif args_format == 'colored': + return colored.format_results(results, no_warn) + else: + return standard.format_results(results, no_warn) def find_project_config_filepath(path='.'): @@ -248,7 +169,7 @@ def run(argv=None): sys.exit(-1) results['stdin'] = problems - max_level = show_problems(results, args_format=args.format, no_warn=args.no_warnings) + max_level = show_results(results, args_format=args.format, no_warn=args.no_warnings) if max_level == PROBLEM_LEVELS['error']: return_code = 1 diff --git a/yamllint/formatters/colored.py b/yamllint/formatters/colored.py new file mode 100644 index 0000000..e3e5777 --- /dev/null +++ b/yamllint/formatters/colored.py @@ -0,0 +1,48 @@ +# Copyright (C) 2016 Adrien Vergé +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from yamllint.linter import PROBLEM_LEVELS + + +def format_results(results, no_warn): + max_level = 0 + + for file in results: + print('\033[4m%s\033[0m' % file) + + for problem in results[file]: + max_level = max(max_level, PROBLEM_LEVELS[problem.level]) + if no_warn and (problem.level != 'error'): + continue + + print(format_problem(problem)) + + print('') + + return max_level + + +def format_problem(problem): + line = ' \033[2m%d:%d\033[0m' % (problem.line, problem.column) + line += max(20 - len(line), 0) * ' ' + if problem.level == 'warning': + line += '\033[33m%s\033[0m' % problem.level + else: + line += '\033[31m%s\033[0m' % problem.level + line += max(38 - len(line), 0) * ' ' + line += problem.desc + if problem.rule: + line += ' \033[2m(%s)\033[0m' % problem.rule + return line diff --git a/yamllint/formatters/github.py b/yamllint/formatters/github.py new file mode 100644 index 0000000..f2dbe3c --- /dev/null +++ b/yamllint/formatters/github.py @@ -0,0 +1,52 @@ +# Copyright (C) 2016 Adrien Vergé +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from yamllint.linter import PROBLEM_LEVELS + + +def format_results(results, no_warn): + max_level = 0 + + for file in results: + print('::group::%s' % file) + + for problem in results[file]: + max_level = max(max_level, PROBLEM_LEVELS[problem.level]) + if no_warn and (problem.level != 'error'): + continue + + print(format_problem(problem, file)) + + print('::endgroup::') + print('') + + return max_level + + +def format_problem(problem, filename): + line = '::' + 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 += problem.desc + return line diff --git a/yamllint/formatters/parsable.py b/yamllint/formatters/parsable.py new file mode 100644 index 0000000..eb32462 --- /dev/null +++ b/yamllint/formatters/parsable.py @@ -0,0 +1,39 @@ +# Copyright (C) 2016 Adrien Vergé +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from yamllint.linter import PROBLEM_LEVELS + + +def format_results(results, no_warn): + max_level = 0 + + for file in results: + for problem in results[file]: + max_level = max(max_level, PROBLEM_LEVELS[problem.level]) + if no_warn and (problem.level != 'error'): + continue + + print(format_problem(problem, file)) + + return max_level + + +def format_problem(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}) diff --git a/yamllint/formatters/standard.py b/yamllint/formatters/standard.py new file mode 100644 index 0000000..7b256eb --- /dev/null +++ b/yamllint/formatters/standard.py @@ -0,0 +1,45 @@ +# Copyright (C) 2016 Adrien Vergé +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from yamllint.linter import PROBLEM_LEVELS + + +def format_results(results, no_warn): + max_level = 0 + + for file in results: + print(file) + + for problem in results[file]: + max_level = max(max_level, PROBLEM_LEVELS[problem.level]) + if no_warn and (problem.level != 'error'): + continue + + print(format_problem(problem)) + + print('') + + return max_level + + +def format_problem(problem): + line = ' %d:%d' % (problem.line, problem.column) + line += max(12 - len(line), 0) * ' ' + line += problem.level + line += max(21 - len(line), 0) * ' ' + line += problem.desc + if problem.rule: + line += ' (%s)' % problem.rule + return line