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