mirror of
https://github.com/Hopiu/djLint.git
synced 2026-05-25 13:03:44 +00:00
added option to format linter output messages. closes #153
This commit is contained in:
parent
a10ac08686
commit
1783c3babf
10 changed files with 96 additions and 24 deletions
|
|
@ -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
|
||||
-----
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
1
tests/config_linter_output_format/html-one.html
Normal file
1
tests/config_linter_output_format/html-one.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<h1>asdf</h2>
|
||||
1
tests/config_linter_output_format/html-two.html
Normal file
1
tests/config_linter_output_format/html-two.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<h1>asdf</h2>
|
||||
3
tests/config_linter_output_format/pyproject.toml
Normal file
3
tests/config_linter_output_format/pyproject.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[tool]
|
||||
[tool.djlint]
|
||||
linter_output_format="{filename}:{line}: {code} {message} {match}"
|
||||
32
tests/test_config_linter_output_format.py
Normal file
32
tests/test_config_linter_output_format.py
Normal 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
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue