added option to format linter output messages. closes #153

This commit is contained in:
Christopher Pickering 2021-11-29 13:05:58 +01:00
parent a10ac08686
commit 1783c3babf
No known key found for this signature in database
GPG key ID: E14DB3B0A0FACF84
10 changed files with 96 additions and 24 deletions

View file

@ -4,6 +4,7 @@ Changelog
next release
------------
- Added config option ``format_attribute_template_tags`` as opt-in for template tag formatting inside of attributes
- Added config option ``linter_output_format`` to customize linter message variable order
0.6.6
-----

View file

@ -181,3 +181,22 @@ For example, with this option enabled, the following html will be acceptable:
{% else %}
that is long stuff asdf and more even
{% endif %}"/>
linter_output_format
--------------------
Customize order of output message. Default="{code} {line} {message} {match}". If ``{filename}`` is not include in message, then the output will be grouped by file and a header will automatically be added to each group.
Usage:
.. code:: ini
# optional variables:
# {filename}
# {line}
# {code}
# {message}
# {match}
linter_output_format="{filename}:{line}: {code} {message} {match}"

View file

@ -44,8 +44,8 @@ def get_line(start: int, line_ends: List) -> str:
def lint_file(config: Config, this_file: Path) -> Dict:
"""Check file for formatting errors."""
file_name = str(this_file)
errors: dict = {file_name: []}
filename = str(this_file)
errors: dict = {filename: []}
html = this_file.read_text(encoding="utf8")
# build list of line ends for file
@ -92,7 +92,7 @@ def lint_file(config: Config, this_file: Path) -> Dict:
for match in open_tags:
if inside_ignored_block(config, html, match) is False:
errors[file_name].append(
errors[filename].append(
{
"code": rule["name"],
"line": get_line(match.start(), line_ends),
@ -109,7 +109,7 @@ def lint_file(config: Config, this_file: Path) -> Dict:
html,
):
if inside_ignored_block(config, html, match) is False:
errors[file_name].append(
errors[filename].append(
{
"code": rule["name"],
"line": get_line(match.start(), line_ends),
@ -119,10 +119,10 @@ def lint_file(config: Config, this_file: Path) -> Dict:
)
# remove duplicate matches
for file_name, error_dict in errors.items():
for filename, error_dict in errors.items():
unique_errors = []
for dict_ in error_dict:
if dict_ not in unique_errors:
unique_errors.append(dict_)
errors[file_name] = unique_errors
errors[filename] = unique_errors
return errors

View file

@ -85,28 +85,37 @@ def build_output(error: dict, config: Config) -> int:
if len(errors) == 0:
return 0
echo(
f"{Fore.GREEN}{Style.BRIGHT}\n{build_relative_path(list(error.keys())[0],config.project_root.resolve())}\n{Style.DIM}"
+ "".join(["" for x in range(1, width)])
+ Style.RESET_ALL
)
filename = build_relative_path(list(error.keys())[0], config.project_root.resolve())
for message in errors:
if "{filename}" not in config.linter_output_format:
echo(
(Fore.RED if bool(message["code"][:1] == "E") else Fore.YELLOW)
+ message["code"]
f"{Fore.GREEN}{Style.BRIGHT}\n{filename}\n{Style.DIM}"
+ "".join(["" for x in range(1, width)])
+ Style.RESET_ALL
+ Fore.BLUE
+ " "
+ message["line"]
)
for message_dict in errors:
line = Fore.BLUE + message_dict["line"] + Style.RESET_ALL
code = (
(Fore.RED if bool(message_dict["code"][:1] == "E") else Fore.YELLOW)
+ message_dict["code"]
+ Style.RESET_ALL
+ " "
+ message["message"]
+ Fore.BLUE
+ " "
+ re.sub(r"\s{2,}", " ", message["match"]),
)
message = message_dict["message"]
match = (
Fore.BLUE
+ re.sub(r"\s{2,}|\n", " ", message_dict["match"])
+ Style.RESET_ALL
)
echo(
config.linter_output_format.format(
filename=filename, line=line, code=code, message=message, match=match
),
err=False,
)
return len(errors)

View file

@ -180,7 +180,7 @@ class Config:
build_custom_blocks(djlint_settings.get("custom_blocks")) or ""
)
self.format_attribute_template_tags = djlint_settings.get(
self.format_attribute_template_tags: bool = djlint_settings.get(
"format_attribute_template_tags", False
)
@ -203,6 +203,10 @@ class Config:
profile or djlint_settings.get("profile", "all")
).lower()
self.linter_output_format: str = djlint_settings.get(
"linter_output_format", "{code} {line} {message} {match}"
)
# load linter rules
rule_set = validate_rules(
yaml.load(

View file

@ -0,0 +1 @@
<h1>asdf</h2>

View file

@ -0,0 +1 @@
<h1>asdf</h2>

View file

@ -0,0 +1,3 @@
[tool]
[tool.djlint]
linter_output_format="{filename}:{line}: {code} {message} {match}"

View file

@ -0,0 +1,32 @@
"""Djlint tests specific to linter output format.
run::
pytest tests/test_config_linter_output_format.py --cov=src/djlint --cov-branch \
--cov-report xml:coverage.xml --cov-report term-missing
for a single test, run::
pytest tests/test_config_linter_output_format.py::test_with_config --cov=src/djlint \
--cov-branch --cov-report xml:coverage.xml --cov-report term-missing
"""
# pylint: disable=C0116
from click.testing import CliRunner
from src.djlint import main as djlint
def test_with_config(runner: CliRunner) -> None:
result = runner.invoke(djlint, ["tests/config_linter_output_format", "--lint"])
assert result.exit_code == 1
print(result.output)
assert (
"""html-one.html:1:0: H025 Tag seems to be an orphan. <h1>
html-one.html:1:8: H025 Tag seems to be an orphan. </h2>
html-two.html:1:0: H025 Tag seems to be an orphan. <h1>
html-two.html:1:8: H025 Tag seems to be an orphan. </h2>"""
in result.output
)

View file

@ -7,7 +7,7 @@ run::
# for a single test
pytest tests/test_linter.py::test_T028 --cov=src/djlint --cov-branch \
pytest tests/test_linter.py::test_output_for_no_linebreaks --cov=src/djlint --cov-branch \
--cov-report xml:coverage.xml --cov-report term-missing
"""
@ -576,6 +576,7 @@ def test_output_for_no_linebreaks(runner: CliRunner, tmp_file: TextIO) -> None:
write_to_file(tmp_file.name, b"<h1>asdf</h1>\n <h2>asdf</h2>")
result = runner.invoke(djlint, [tmp_file.name])
assert result.exit_code == 1
assert "</h1>\n" not in result.output
@ -583,6 +584,7 @@ def test_output_order(runner: CliRunner, tmp_file: TextIO) -> None:
write_to_file(tmp_file.name, b"<h1>asdf</h2>\n <h3>asdf</h4>")
result = runner.invoke(djlint, [tmp_file.name])
assert result.exit_code == 1
assert (
"""H025 1:0 Tag seems to be an orphan. <h1>
H015 1:8 Follow h tags with a line break. </h2> <h3