lintro 0.6.2__py3-none-any.whl → 0.17.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lintro/__init__.py +1 -1
- lintro/cli.py +230 -14
- lintro/cli_utils/commands/__init__.py +8 -1
- lintro/cli_utils/commands/check.py +1 -0
- lintro/cli_utils/commands/config.py +325 -0
- lintro/cli_utils/commands/format.py +2 -2
- lintro/cli_utils/commands/init.py +361 -0
- lintro/cli_utils/commands/list_tools.py +180 -42
- lintro/cli_utils/commands/test.py +316 -0
- lintro/cli_utils/commands/versions.py +81 -0
- lintro/config/__init__.py +62 -0
- lintro/config/config_loader.py +420 -0
- lintro/config/lintro_config.py +189 -0
- lintro/config/tool_config_generator.py +403 -0
- lintro/enums/__init__.py +1 -0
- lintro/enums/darglint_strictness.py +10 -0
- lintro/enums/hadolint_enums.py +22 -0
- lintro/enums/tool_name.py +2 -0
- lintro/enums/tool_type.py +2 -0
- lintro/enums/yamllint_format.py +11 -0
- lintro/exceptions/__init__.py +1 -0
- lintro/formatters/__init__.py +1 -0
- lintro/formatters/core/__init__.py +1 -0
- lintro/formatters/core/output_style.py +11 -0
- lintro/formatters/core/table_descriptor.py +8 -0
- lintro/formatters/styles/csv.py +2 -0
- lintro/formatters/styles/grid.py +2 -0
- lintro/formatters/styles/html.py +2 -0
- lintro/formatters/styles/json.py +2 -0
- lintro/formatters/styles/markdown.py +2 -0
- lintro/formatters/styles/plain.py +2 -0
- lintro/formatters/tools/__init__.py +12 -0
- lintro/formatters/tools/black_formatter.py +27 -5
- lintro/formatters/tools/darglint_formatter.py +16 -1
- lintro/formatters/tools/eslint_formatter.py +108 -0
- lintro/formatters/tools/hadolint_formatter.py +13 -0
- lintro/formatters/tools/markdownlint_formatter.py +88 -0
- lintro/formatters/tools/prettier_formatter.py +15 -0
- lintro/formatters/tools/pytest_formatter.py +201 -0
- lintro/formatters/tools/ruff_formatter.py +26 -5
- lintro/formatters/tools/yamllint_formatter.py +14 -1
- lintro/models/__init__.py +1 -0
- lintro/models/core/__init__.py +1 -0
- lintro/models/core/tool_config.py +11 -7
- lintro/parsers/__init__.py +69 -9
- lintro/parsers/actionlint/actionlint_parser.py +1 -1
- lintro/parsers/bandit/__init__.py +6 -0
- lintro/parsers/bandit/bandit_issue.py +49 -0
- lintro/parsers/bandit/bandit_parser.py +99 -0
- lintro/parsers/black/black_issue.py +4 -0
- lintro/parsers/darglint/__init__.py +1 -0
- lintro/parsers/darglint/darglint_issue.py +11 -0
- lintro/parsers/eslint/__init__.py +6 -0
- lintro/parsers/eslint/eslint_issue.py +26 -0
- lintro/parsers/eslint/eslint_parser.py +63 -0
- lintro/parsers/markdownlint/__init__.py +6 -0
- lintro/parsers/markdownlint/markdownlint_issue.py +22 -0
- lintro/parsers/markdownlint/markdownlint_parser.py +113 -0
- lintro/parsers/prettier/__init__.py +1 -0
- lintro/parsers/prettier/prettier_issue.py +12 -0
- lintro/parsers/prettier/prettier_parser.py +1 -1
- lintro/parsers/pytest/__init__.py +21 -0
- lintro/parsers/pytest/pytest_issue.py +28 -0
- lintro/parsers/pytest/pytest_parser.py +483 -0
- lintro/parsers/ruff/ruff_parser.py +6 -2
- lintro/parsers/yamllint/__init__.py +1 -0
- lintro/tools/__init__.py +3 -1
- lintro/tools/core/__init__.py +1 -0
- lintro/tools/core/timeout_utils.py +112 -0
- lintro/tools/core/tool_base.py +286 -50
- lintro/tools/core/tool_manager.py +77 -24
- lintro/tools/core/version_requirements.py +482 -0
- lintro/tools/implementations/__init__.py +1 -0
- lintro/tools/implementations/pytest/pytest_command_builder.py +311 -0
- lintro/tools/implementations/pytest/pytest_config.py +200 -0
- lintro/tools/implementations/pytest/pytest_error_handler.py +128 -0
- lintro/tools/implementations/pytest/pytest_executor.py +122 -0
- lintro/tools/implementations/pytest/pytest_handlers.py +375 -0
- lintro/tools/implementations/pytest/pytest_option_validators.py +212 -0
- lintro/tools/implementations/pytest/pytest_output_processor.py +408 -0
- lintro/tools/implementations/pytest/pytest_result_processor.py +113 -0
- lintro/tools/implementations/pytest/pytest_utils.py +697 -0
- lintro/tools/implementations/tool_actionlint.py +106 -16
- lintro/tools/implementations/tool_bandit.py +34 -29
- lintro/tools/implementations/tool_black.py +236 -29
- lintro/tools/implementations/tool_darglint.py +183 -22
- lintro/tools/implementations/tool_eslint.py +374 -0
- lintro/tools/implementations/tool_hadolint.py +94 -25
- lintro/tools/implementations/tool_markdownlint.py +354 -0
- lintro/tools/implementations/tool_prettier.py +317 -24
- lintro/tools/implementations/tool_pytest.py +327 -0
- lintro/tools/implementations/tool_ruff.py +278 -84
- lintro/tools/implementations/tool_yamllint.py +448 -34
- lintro/tools/tool_enum.py +8 -0
- lintro/utils/__init__.py +1 -0
- lintro/utils/ascii_normalize_cli.py +5 -0
- lintro/utils/config.py +41 -18
- lintro/utils/console_logger.py +211 -25
- lintro/utils/path_utils.py +42 -0
- lintro/utils/tool_executor.py +339 -45
- lintro/utils/tool_utils.py +51 -24
- lintro/utils/unified_config.py +926 -0
- {lintro-0.6.2.dist-info → lintro-0.17.2.dist-info}/METADATA +172 -30
- lintro-0.17.2.dist-info/RECORD +134 -0
- lintro-0.6.2.dist-info/RECORD +0 -96
- {lintro-0.6.2.dist-info → lintro-0.17.2.dist-info}/WHEEL +0 -0
- {lintro-0.6.2.dist-info → lintro-0.17.2.dist-info}/entry_points.txt +0 -0
- {lintro-0.6.2.dist-info → lintro-0.17.2.dist-info}/licenses/LICENSE +0 -0
- {lintro-0.6.2.dist-info → lintro-0.17.2.dist-info}/top_level.txt +0 -0
lintro/utils/tool_utils.py
CHANGED
|
@@ -27,14 +27,26 @@ from lintro.formatters.tools.darglint_formatter import (
|
|
|
27
27
|
DarglintTableDescriptor,
|
|
28
28
|
format_darglint_issues,
|
|
29
29
|
)
|
|
30
|
+
from lintro.formatters.tools.eslint_formatter import (
|
|
31
|
+
EslintTableDescriptor,
|
|
32
|
+
format_eslint_issues,
|
|
33
|
+
)
|
|
30
34
|
from lintro.formatters.tools.hadolint_formatter import (
|
|
31
35
|
HadolintTableDescriptor,
|
|
32
36
|
format_hadolint_issues,
|
|
33
37
|
)
|
|
38
|
+
from lintro.formatters.tools.markdownlint_formatter import (
|
|
39
|
+
MarkdownlintTableDescriptor,
|
|
40
|
+
format_markdownlint_issues,
|
|
41
|
+
)
|
|
34
42
|
from lintro.formatters.tools.prettier_formatter import (
|
|
35
43
|
PrettierTableDescriptor,
|
|
36
44
|
format_prettier_issues,
|
|
37
45
|
)
|
|
46
|
+
from lintro.formatters.tools.pytest_formatter import (
|
|
47
|
+
PytestFailuresTableDescriptor,
|
|
48
|
+
format_pytest_issues,
|
|
49
|
+
)
|
|
38
50
|
from lintro.formatters.tools.ruff_formatter import (
|
|
39
51
|
RuffTableDescriptor,
|
|
40
52
|
format_ruff_issues,
|
|
@@ -47,9 +59,13 @@ from lintro.parsers.bandit.bandit_parser import parse_bandit_output
|
|
|
47
59
|
from lintro.parsers.black.black_issue import BlackIssue
|
|
48
60
|
from lintro.parsers.black.black_parser import parse_black_output
|
|
49
61
|
from lintro.parsers.darglint.darglint_parser import parse_darglint_output
|
|
62
|
+
from lintro.parsers.eslint.eslint_issue import EslintIssue
|
|
63
|
+
from lintro.parsers.eslint.eslint_parser import parse_eslint_output
|
|
50
64
|
from lintro.parsers.hadolint.hadolint_parser import parse_hadolint_output
|
|
65
|
+
from lintro.parsers.markdownlint.markdownlint_parser import parse_markdownlint_output
|
|
51
66
|
from lintro.parsers.prettier.prettier_issue import PrettierIssue
|
|
52
67
|
from lintro.parsers.prettier.prettier_parser import parse_prettier_output
|
|
68
|
+
from lintro.parsers.pytest.pytest_parser import parse_pytest_text_output
|
|
53
69
|
from lintro.parsers.ruff.ruff_issue import RuffFormatIssue, RuffIssue
|
|
54
70
|
from lintro.parsers.ruff.ruff_parser import parse_ruff_output
|
|
55
71
|
from lintro.parsers.yamllint.yamllint_parser import parse_yamllint_output
|
|
@@ -57,13 +73,16 @@ from lintro.parsers.yamllint.yamllint_parser import parse_yamllint_output
|
|
|
57
73
|
# Constants
|
|
58
74
|
TOOL_TABLE_FORMATTERS: dict[str, tuple] = {
|
|
59
75
|
"darglint": (DarglintTableDescriptor(), format_darglint_issues),
|
|
76
|
+
"eslint": (EslintTableDescriptor(), format_eslint_issues),
|
|
60
77
|
"hadolint": (HadolintTableDescriptor(), format_hadolint_issues),
|
|
61
78
|
"black": (BlackTableDescriptor(), format_black_issues),
|
|
62
79
|
"prettier": (PrettierTableDescriptor(), format_prettier_issues),
|
|
80
|
+
"pytest": (PytestFailuresTableDescriptor(), format_pytest_issues),
|
|
63
81
|
"ruff": (RuffTableDescriptor(), format_ruff_issues),
|
|
64
82
|
"yamllint": (YamllintTableDescriptor(), format_yamllint_issues),
|
|
65
83
|
"actionlint": (ActionlintTableDescriptor(), format_actionlint_issues),
|
|
66
84
|
"bandit": (BanditTableDescriptor(), format_bandit_issues),
|
|
85
|
+
"markdownlint": (MarkdownlintTableDescriptor(), format_markdownlint_issues),
|
|
67
86
|
}
|
|
68
87
|
VENV_PATTERNS: list[str] = [
|
|
69
88
|
"venv",
|
|
@@ -104,7 +123,7 @@ def parse_tool_list(tools_str: str | None) -> list[str]:
|
|
|
104
123
|
try:
|
|
105
124
|
result.append(ToolEnum[t.upper()])
|
|
106
125
|
except KeyError:
|
|
107
|
-
raise ValueError(f"Unknown core: {t}")
|
|
126
|
+
raise ValueError(f"Unknown core: {t}") from None
|
|
108
127
|
return result
|
|
109
128
|
|
|
110
129
|
|
|
@@ -200,10 +219,7 @@ def get_table_columns(
|
|
|
200
219
|
columns = expected_columns
|
|
201
220
|
else:
|
|
202
221
|
# Fallback: use all unique keys from the first issue
|
|
203
|
-
if issues
|
|
204
|
-
columns = list(issues[0].keys())
|
|
205
|
-
else:
|
|
206
|
-
columns = []
|
|
222
|
+
columns = list(issues[0].keys()) if issues else []
|
|
207
223
|
|
|
208
224
|
# Convert issues to rows
|
|
209
225
|
rows: list[list[str]] = []
|
|
@@ -307,9 +323,19 @@ def format_tool_output(
|
|
|
307
323
|
isinstance(i, RuffIssue) and getattr(i, "fixable", False)
|
|
308
324
|
)
|
|
309
325
|
if tool == "prettier":
|
|
310
|
-
return lambda i: isinstance(i, PrettierIssue)
|
|
326
|
+
return lambda i: isinstance(i, PrettierIssue)
|
|
311
327
|
if tool == "black":
|
|
312
|
-
return lambda i: isinstance(i, BlackIssue)
|
|
328
|
+
return lambda i: isinstance(i, BlackIssue) and getattr(
|
|
329
|
+
i,
|
|
330
|
+
"fixable",
|
|
331
|
+
True,
|
|
332
|
+
)
|
|
333
|
+
if tool == "eslint":
|
|
334
|
+
return lambda i: isinstance(i, EslintIssue) and getattr(
|
|
335
|
+
i,
|
|
336
|
+
"fixable",
|
|
337
|
+
False,
|
|
338
|
+
)
|
|
313
339
|
return None
|
|
314
340
|
|
|
315
341
|
is_fixable = _is_fixable_predicate(tool_name)
|
|
@@ -367,10 +393,14 @@ def format_tool_output(
|
|
|
367
393
|
parsed_issues = parse_black_output(output=output)
|
|
368
394
|
elif tool_name == "darglint":
|
|
369
395
|
parsed_issues = parse_darglint_output(output=output)
|
|
396
|
+
elif tool_name == "eslint":
|
|
397
|
+
parsed_issues = parse_eslint_output(output=output)
|
|
370
398
|
elif tool_name == "hadolint":
|
|
371
399
|
parsed_issues = parse_hadolint_output(output=output)
|
|
372
400
|
elif tool_name == "yamllint":
|
|
373
401
|
parsed_issues = parse_yamllint_output(output=output)
|
|
402
|
+
elif tool_name == "markdownlint":
|
|
403
|
+
parsed_issues = parse_markdownlint_output(output=output)
|
|
374
404
|
elif tool_name == "bandit":
|
|
375
405
|
# Bandit emits JSON; try parsing when raw output is provided
|
|
376
406
|
try:
|
|
@@ -379,6 +409,9 @@ def format_tool_output(
|
|
|
379
409
|
)
|
|
380
410
|
except Exception:
|
|
381
411
|
parsed_issues = []
|
|
412
|
+
elif tool_name == "pytest":
|
|
413
|
+
# Pytest emits text output; parse it
|
|
414
|
+
parsed_issues = parse_pytest_text_output(output=output)
|
|
382
415
|
|
|
383
416
|
if parsed_issues and tool_name in TOOL_TABLE_FORMATTERS:
|
|
384
417
|
_, formatter_func = TOOL_TABLE_FORMATTERS[tool_name]
|
|
@@ -394,21 +427,17 @@ def walk_files_with_excludes(
|
|
|
394
427
|
exclude_patterns: list[str],
|
|
395
428
|
include_venv: bool = False,
|
|
396
429
|
) -> list[str]:
|
|
397
|
-
"""
|
|
398
|
-
specified patterns.
|
|
430
|
+
"""Return files under ``paths`` matching patterns and not excluded.
|
|
399
431
|
|
|
400
432
|
Args:
|
|
401
|
-
paths: list[str]:
|
|
402
|
-
file_patterns: list[str]:
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
["__pycache__", "*.pyc"]).
|
|
406
|
-
include_venv: bool: Whether to include virtual environment directories.
|
|
433
|
+
paths: list[str]: Files or directories to search.
|
|
434
|
+
file_patterns: list[str]: Glob patterns to include.
|
|
435
|
+
exclude_patterns: list[str]: Glob patterns to exclude.
|
|
436
|
+
include_venv: bool: Include virtual environment directories when True.
|
|
407
437
|
|
|
408
438
|
Returns:
|
|
409
|
-
list[str]:
|
|
439
|
+
list[str]: Sorted file paths matching include filters and not excluded.
|
|
410
440
|
"""
|
|
411
|
-
|
|
412
441
|
all_files: list[str] = []
|
|
413
442
|
|
|
414
443
|
for path in paths:
|
|
@@ -438,13 +467,11 @@ def walk_files_with_excludes(
|
|
|
438
467
|
matches_pattern = True
|
|
439
468
|
break
|
|
440
469
|
|
|
441
|
-
if matches_pattern
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
):
|
|
447
|
-
all_files.append(file_path)
|
|
470
|
+
if matches_pattern and not should_exclude_path(
|
|
471
|
+
path=rel_path,
|
|
472
|
+
exclude_patterns=exclude_patterns,
|
|
473
|
+
):
|
|
474
|
+
all_files.append(file_path)
|
|
448
475
|
|
|
449
476
|
return sorted(all_files)
|
|
450
477
|
|