lintro 0.5.3__tar.gz → 0.6.1__tar.gz
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.
Potentially problematic release.
This version of lintro might be problematic. Click here for more details.
- {lintro-0.5.3/lintro.egg-info → lintro-0.6.1}/PKG-INFO +9 -7
- {lintro-0.5.3 → lintro-0.6.1}/README.md +7 -5
- {lintro-0.5.3 → lintro-0.6.1}/docs/README.md +10 -9
- {lintro-0.5.3 → lintro-0.6.1}/docs/configuration.md +88 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/getting-started.md +7 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/github-integration.md +2 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/README.md +8 -0
- lintro-0.6.1/docs/tool-analysis/black-analysis.md +111 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/ruff-analysis.md +21 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/__init__.py +1 -1
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/actionlint_formatter.py +1 -1
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/bandit_formatter.py +1 -1
- lintro-0.6.1/lintro/formatters/tools/black_formatter.py +48 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/darglint_formatter.py +3 -1
- lintro-0.6.1/lintro/parsers/black/black_issue.py +22 -0
- lintro-0.6.1/lintro/parsers/black/black_parser.py +90 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/darglint/darglint_parser.py +1 -1
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/hadolint/hadolint_parser.py +2 -2
- lintro-0.6.1/lintro/parsers/ruff/ruff_parser.py +140 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/yamllint/yamllint_parser.py +2 -2
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/__init__.py +2 -2
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/core/tool_base.py +41 -11
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/tool_bandit.py +4 -2
- lintro-0.6.1/lintro/tools/implementations/tool_black.py +261 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/tool_prettier.py +1 -1
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/tool_ruff.py +47 -25
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/tool_enum.py +2 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/ascii_normalize_cli.py +3 -1
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/config.py +16 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/console_logger.py +59 -11
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/output_manager.py +2 -2
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/tool_executor.py +214 -7
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/tool_utils.py +12 -1
- {lintro-0.5.3 → lintro-0.6.1/lintro.egg-info}/PKG-INFO +9 -7
- {lintro-0.5.3 → lintro-0.6.1}/lintro.egg-info/SOURCES.txt +18 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro.egg-info/requires.txt +1 -1
- {lintro-0.5.3 → lintro-0.6.1}/pyproject.toml +14 -4
- lintro-0.6.1/test_samples/ruff_black_e501_wrappable.py +8 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/conftest.py +1 -1
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/conftest.py +2 -2
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/test_actionlint_integration.py +3 -1
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/test_darglint_integration.py +18 -18
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/test_hadolint_integration.py +38 -29
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/test_prettier_integration.py +18 -16
- lintro-0.6.1/tests/integration/test_ruff_black_policy.py +82 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/test_ruff_integration.py +5 -5
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/test_yamllint_integration.py +35 -24
- {lintro-0.5.3 → lintro-0.6.1}/tests/scripts/test_delete_previous_lintro_comments.py +3 -1
- {lintro-0.5.3 → lintro-0.6.1}/tests/scripts/test_ghcr_prune_untagged.py +41 -9
- {lintro-0.5.3 → lintro-0.6.1}/tests/scripts/test_script_environment.py +22 -13
- {lintro-0.5.3 → lintro-0.6.1}/tests/scripts/test_semantic_release_compute_next.py +16 -6
- {lintro-0.5.3 → lintro-0.6.1}/tests/scripts/test_shell_scripts.py +38 -28
- {lintro-0.5.3 → lintro-0.6.1}/tests/test_documentation.py +6 -6
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_ascii_normalize.py +5 -1
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_bandit_formatter_mapping.py +4 -1
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_bandit_parsing.py +4 -4
- lintro-0.6.1/tests/unit/test_black_formatter.py +38 -0
- lintro-0.6.1/tests/unit/test_black_parser.py +29 -0
- lintro-0.6.1/tests/unit/test_black_tool.py +228 -0
- lintro-0.6.1/tests/unit/test_black_tool_more.py +41 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_cli_programmatic.py +10 -4
- lintro-0.6.1/tests/unit/test_compatibility_ruff_black.py +129 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_config_loader.py +24 -1
- lintro-0.6.1/tests/unit/test_config_loader_more.py +26 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_console_logger.py +14 -4
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_console_logger_more.py +12 -2
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_enums_and_normalizers.py +7 -7
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_formatters_tables.py +6 -6
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_output_manager_reports.py +4 -1
- lintro-0.6.1/tests/unit/test_ruff_parser_additional.py +30 -0
- lintro-0.6.1/tests/unit/test_ruff_parser_more.py +57 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_tool_executor.py +11 -7
- lintro-0.6.1/tests/unit/test_tool_executor_more.py +389 -0
- lintro-0.6.1/tests/unit/test_tool_executor_post_checks.py +210 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_tool_manager.py +4 -5
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_tool_utils.py +5 -1
- lintro-0.6.1/tests/unit/test_tool_utils_fallbacks.py +30 -0
- lintro-0.5.3/lintro/parsers/ruff/ruff_parser.py +0 -89
- {lintro-0.5.3 → lintro-0.6.1}/LICENSE +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/MANIFEST.in +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/assets/images/coverage-badge.svg +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/assets/images/lintro.png +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/contributing.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/coverage-setup.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/docker.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/lintro-self-use.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/style-guide.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/actionlint-analysis.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/bandit-analysis.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/darglint-analysis.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/hadolint-analysis.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/prettier-analysis.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/docs/tool-analysis/yamllint-analysis.md +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/__main__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/ascii-art/fail.txt +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/ascii-art/success.txt +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/cli.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/cli_utils/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/cli_utils/commands/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/cli_utils/commands/check.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/cli_utils/commands/format.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/cli_utils/commands/list_tools.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/action.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/darglint_strictness.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/group_by.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/hadolint_enums.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/output_format.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/tool_name.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/tool_type.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/enums/yamllint_format.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/exceptions/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/exceptions/errors.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/core/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/core/output_style.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/core/table_descriptor.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/styles/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/styles/csv.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/styles/grid.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/styles/html.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/styles/json.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/styles/markdown.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/styles/plain.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/hadolint_formatter.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/prettier_formatter.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/ruff_formatter.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/formatters/tools/yamllint_formatter.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/models/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/models/core/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/models/core/tool.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/models/core/tool_config.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/models/core/tool_result.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/actionlint/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/darglint/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/darglint/darglint_issue.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/hadolint/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/prettier/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/prettier/prettier_issue.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/prettier/prettier_parser.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/ruff/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/ruff/ruff_issue.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/yamllint/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/core/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/core/tool_manager.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/tool_actionlint.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/tool_darglint.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/tool_hadolint.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/tools/implementations/tool_yamllint.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/formatting.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro/utils/path_utils.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro.egg-info/dependency_links.txt +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro.egg-info/entry_points.txt +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/lintro.egg-info/top_level.txt +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/setup.cfg +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/Dockerfile.violations +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/actionlint_violations.yml +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/bandit_violations.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/darglint_violations.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/prettier_violations.js +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/ruff_clean.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/ruff_violations.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/test_samples/yaml_violations.yml +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/cli/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/cli/conftest.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/cli/test_cli.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/formatters/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/formatters/conftest.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/formatters/test_formatters.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/integration/test_bandit_integration.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/scripts/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/scripts/test_extract_version.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_bandit_command_building.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_bandit_config_hydration.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_cli_commands.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_cli_commands_more.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_exceptions.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_parsers_actionlint.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_tool_executor_fmt_exclusion.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/unit/test_tool_utils_more.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/utils/__init__.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/utils/conftest.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/utils/test_formatting.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/utils/test_output_manager.py +0 -0
- {lintro-0.5.3 → lintro-0.6.1}/tests/utils/test_path_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lintro
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: A unified CLI tool for code formatting, linting, and quality assurance
|
|
5
5
|
Author-email: TurboCoder13 <turbocoder13@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -58,7 +58,7 @@ Requires-Dist: allure-pytest==2.15.0; extra == "dev"
|
|
|
58
58
|
Requires-Dist: ruff; extra == "dev"
|
|
59
59
|
Requires-Dist: mypy; extra == "dev"
|
|
60
60
|
Requires-Dist: coverage-badge==1.1.2; extra == "dev"
|
|
61
|
-
Requires-Dist: python-semantic-release==10.3.
|
|
61
|
+
Requires-Dist: python-semantic-release==10.3.2; extra == "dev"
|
|
62
62
|
Requires-Dist: assertpy==1.1; extra == "dev"
|
|
63
63
|
Requires-Dist: httpx==0.28.1; extra == "dev"
|
|
64
64
|
Provides-Extra: test
|
|
@@ -121,6 +121,7 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
121
121
|
| [](https://github.com/terrencepreilly/darglint) | 🐍 Python | - |
|
|
122
122
|
| [](https://github.com/hadolint/hadolint) | 🐳 Dockerfile | - |
|
|
123
123
|
| [](https://prettier.io/) | 🟨 JS/TS · 🧾 JSON | ✅ |
|
|
124
|
+
| [](https://github.com/psf/black) | 🐍 Python | ✅ |
|
|
124
125
|
| [](https://github.com/astral-sh/ruff) | 🐍 Python | ✅ |
|
|
125
126
|
| [](https://github.com/adrienverge/yamllint) | 🧾 YAML | - |
|
|
126
127
|
|
|
@@ -216,11 +217,12 @@ lintro check --exclude "migrations,node_modules,dist"
|
|
|
216
217
|
# Tool-specific options use key=value (lists with |)
|
|
217
218
|
lintro check --tool-options "ruff:line_length=88,prettier:print_width=80"
|
|
218
219
|
|
|
219
|
-
# Ruff
|
|
220
|
-
#
|
|
221
|
-
#
|
|
222
|
-
|
|
223
|
-
lintro format --tool-options ruff:format=
|
|
220
|
+
# Ruff + Black cooperation:
|
|
221
|
+
# Lintro prefers Ruff for linting and Black for formatting.
|
|
222
|
+
# When Black is configured as a post-check, Lintro disables Ruff formatting by
|
|
223
|
+
# default to avoid double-formatting. Override if needed:
|
|
224
|
+
lintro format --tool-options ruff:format=True # force Ruff to format
|
|
225
|
+
lintro check --tool-options ruff:format_check=True # force Ruff format check
|
|
224
226
|
```
|
|
225
227
|
|
|
226
228
|
### CI/CD Integration
|
|
@@ -47,6 +47,7 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
47
47
|
| [](https://github.com/terrencepreilly/darglint) | 🐍 Python | - |
|
|
48
48
|
| [](https://github.com/hadolint/hadolint) | 🐳 Dockerfile | - |
|
|
49
49
|
| [](https://prettier.io/) | 🟨 JS/TS · 🧾 JSON | ✅ |
|
|
50
|
+
| [](https://github.com/psf/black) | 🐍 Python | ✅ |
|
|
50
51
|
| [](https://github.com/astral-sh/ruff) | 🐍 Python | ✅ |
|
|
51
52
|
| [](https://github.com/adrienverge/yamllint) | 🧾 YAML | - |
|
|
52
53
|
|
|
@@ -142,11 +143,12 @@ lintro check --exclude "migrations,node_modules,dist"
|
|
|
142
143
|
# Tool-specific options use key=value (lists with |)
|
|
143
144
|
lintro check --tool-options "ruff:line_length=88,prettier:print_width=80"
|
|
144
145
|
|
|
145
|
-
# Ruff
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
|
|
149
|
-
lintro format --tool-options ruff:format=
|
|
146
|
+
# Ruff + Black cooperation:
|
|
147
|
+
# Lintro prefers Ruff for linting and Black for formatting.
|
|
148
|
+
# When Black is configured as a post-check, Lintro disables Ruff formatting by
|
|
149
|
+
# default to avoid double-formatting. Override if needed:
|
|
150
|
+
lintro format --tool-options ruff:format=True # force Ruff to format
|
|
151
|
+
lintro check --tool-options ruff:format_check=True # force Ruff format check
|
|
150
152
|
```
|
|
151
153
|
|
|
152
154
|
### CI/CD Integration
|
|
@@ -105,15 +105,16 @@ lintro format
|
|
|
105
105
|
|
|
106
106
|
## 🛠️ Supported Tools
|
|
107
107
|
|
|
108
|
-
| Tool | Language/Format | Purpose
|
|
109
|
-
| -------------- | ---------------- |
|
|
110
|
-
| **Ruff** | Python | Linting & Formatting
|
|
111
|
-
| **
|
|
112
|
-
| **
|
|
113
|
-
| **
|
|
114
|
-
| **
|
|
115
|
-
| **
|
|
116
|
-
| **
|
|
108
|
+
| Tool | Language/Format | Purpose | Documentation |
|
|
109
|
+
| -------------- | ---------------- | ----------------------- | ---------------------------------------------------------- |
|
|
110
|
+
| **Ruff** | Python | Linting & Formatting | [Config Guide](configuration.md#ruff-configuration) |
|
|
111
|
+
| **Black** | Python | Formatting (Post-check) | [Config Guide](configuration.md#post-checks-configuration) |
|
|
112
|
+
| **Darglint** | Python | Docstring Validation | [Analysis](tool-analysis/darglint-analysis.md) |
|
|
113
|
+
| **Bandit** | Python | Security Linting | [Analysis](tool-analysis/bandit-analysis.md) |
|
|
114
|
+
| **Prettier** | JS/TS/JSON/CSS | Code Formatting | [Analysis](tool-analysis/prettier-analysis.md) |
|
|
115
|
+
| **Yamllint** | YAML | Syntax & Style | [Config Guide](configuration.md#yamllint-configuration) |
|
|
116
|
+
| **Actionlint** | GitHub Workflows | Workflow Linting | [Analysis](tool-analysis/actionlint-analysis.md) |
|
|
117
|
+
| **Hadolint** | Dockerfile | Best Practices | [Config Guide](configuration.md#hadolint-configuration) |
|
|
117
118
|
|
|
118
119
|
## 📋 Command Reference
|
|
119
120
|
|
|
@@ -69,6 +69,94 @@ format = true # run `ruff format` during fmt (default true)
|
|
|
69
69
|
lint_fix = true # run `ruff check --fix` during fmt (default true)
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
+
### Post-checks Configuration
|
|
73
|
+
|
|
74
|
+
Black is integrated as a post-check tool by default. Post-checks run after the
|
|
75
|
+
main tools complete and can be configured to enforce failure if issues are
|
|
76
|
+
found. This avoids double-formatting with Ruff and keeps formatting decisions
|
|
77
|
+
explicit.
|
|
78
|
+
|
|
79
|
+
```toml
|
|
80
|
+
[tool.lintro.post_checks]
|
|
81
|
+
enabled = true
|
|
82
|
+
tools = ["black"] # Black runs after core tools
|
|
83
|
+
enforce_failure = true # Fail the run if Black finds issues in check mode
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Notes:
|
|
87
|
+
|
|
88
|
+
- With post-checks enabled for Black, Ruff’s `format`/`format_check` stages can
|
|
89
|
+
be disabled or overridden via CLI when desired.
|
|
90
|
+
- In `lintro check`, Black runs with `--check` and contributes to failure when
|
|
91
|
+
`enforce_failure` is true. In `lintro format`, Black formats files in the
|
|
92
|
+
post-check phase.
|
|
93
|
+
|
|
94
|
+
#### Black Options via `--tool-options`
|
|
95
|
+
|
|
96
|
+
You can override Black behavior on the CLI. Supported options include
|
|
97
|
+
`line_length`, `target_version`, `fast`, `preview`, and `diff`.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Increase line length and target a specific Python version
|
|
101
|
+
lintro check --tool-options "black:line_length=100,black:target_version=py313"
|
|
102
|
+
|
|
103
|
+
# Enable fast and preview modes
|
|
104
|
+
lintro format --tool-options "black:fast=True,black:preview=True"
|
|
105
|
+
|
|
106
|
+
# Show diffs during formatting (in addition to applying changes)
|
|
107
|
+
lintro format --tool-options "black:diff=True"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
These options can also be set in `pyproject.toml` under `[tool.lintro.black]`:
|
|
111
|
+
|
|
112
|
+
```toml
|
|
113
|
+
[tool.lintro.black]
|
|
114
|
+
line_length = 100
|
|
115
|
+
target_version = "py313"
|
|
116
|
+
fast = false
|
|
117
|
+
preview = false
|
|
118
|
+
diff = false
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Ruff vs Black Policy (Python)
|
|
122
|
+
|
|
123
|
+
Lintro enforces Ruff-first linting and Black-first formatting when Black is
|
|
124
|
+
configured as a post-check.
|
|
125
|
+
|
|
126
|
+
- Ruff: primary linter (keep strict rules like `COM812` trailing commas and
|
|
127
|
+
`E501` line length enabled for checks)
|
|
128
|
+
- Black: primary formatter (applies formatting during post-checks; performs
|
|
129
|
+
safe line breaking where Ruff’s auto-format may be limited)
|
|
130
|
+
|
|
131
|
+
Runtime behavior with Black as post-check:
|
|
132
|
+
|
|
133
|
+
- lintro format
|
|
134
|
+
- Ruff fixes lint issues only (Ruff `format=False`) unless explicitly
|
|
135
|
+
overridden
|
|
136
|
+
- Black performs formatting in the post-check phase
|
|
137
|
+
|
|
138
|
+
- lintro check
|
|
139
|
+
- Ruff runs lint checks (Ruff `format_check=False`) unless explicitly
|
|
140
|
+
overridden
|
|
141
|
+
- Black runs `--check` as a post-check to enforce formatting
|
|
142
|
+
|
|
143
|
+
Overrides when needed:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Force Ruff to format during fmt
|
|
147
|
+
lintro format --tool-options ruff:format=True
|
|
148
|
+
|
|
149
|
+
# Force Ruff to include format check during check
|
|
150
|
+
lintro check --tool-options ruff:format_check=True
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Rationale:
|
|
154
|
+
|
|
155
|
+
- Avoids double-formatting churn (Ruff format followed by Black format) while
|
|
156
|
+
preserving Ruff’s stricter lint rules (e.g., `COM812`, `E501`).
|
|
157
|
+
- Black’s safe wrapping is preferred for long lines; Ruff continues to enforce
|
|
158
|
+
lint limits during checks.
|
|
159
|
+
|
|
72
160
|
### Python Tools
|
|
73
161
|
|
|
74
162
|
#### Ruff Configuration
|
|
@@ -120,11 +120,18 @@ lintro check src/ tests/ --tools ruff,darglint
|
|
|
120
120
|
|
|
121
121
|
# Format Python code
|
|
122
122
|
lintro format src/ --tools ruff
|
|
123
|
+
|
|
124
|
+
# Run Black as a post-check (configured via pyproject)
|
|
125
|
+
lintro check src/
|
|
126
|
+
|
|
127
|
+
# Override Black on the fly
|
|
128
|
+
lintro check src/ --tool-options "black:line_length=100,black:target_version=py313"
|
|
123
129
|
```
|
|
124
130
|
|
|
125
131
|
**Tools:**
|
|
126
132
|
|
|
127
133
|
- **Ruff** - Fast Python linter and formatter
|
|
134
|
+
- **Black** - Python formatter (runs as a post-check by default)
|
|
128
135
|
- **Darglint** - Docstring validation
|
|
129
136
|
|
|
130
137
|
### JavaScript/TypeScript Projects
|
|
@@ -23,6 +23,7 @@ The repository includes pre-configured GitHub Actions workflows. To activate the
|
|
|
23
23
|
- 📊 **Detailed reporting** in GitHub Actions summaries
|
|
24
24
|
- 🚀 **Multi-tool analysis:**
|
|
25
25
|
- Python: Ruff + Darglint
|
|
26
|
+
- Python formatting (post-check): Black
|
|
26
27
|
- YAML: Yamllint
|
|
27
28
|
- JSON: Prettier
|
|
28
29
|
- Docker: Hadolint
|
|
@@ -248,6 +249,7 @@ jobs:
|
|
|
248
249
|
|
|
249
250
|
- name: Run Lintro
|
|
250
251
|
run: |
|
|
252
|
+
# Run core tools, then post-checks (Black) per pyproject config
|
|
251
253
|
uv run lintro check --output-format grid --output lintro-results.txt
|
|
252
254
|
cat lintro-results.txt
|
|
253
255
|
|
|
@@ -60,6 +60,14 @@ This directory contains comprehensive analyses comparing Lintro's wrapper implem
|
|
|
60
60
|
- ⚠️ **Limited**: Runtime rule customization, Docker Compose support, auto-fixing
|
|
61
61
|
- 🚀 **Enhanced**: Issue normalization, Python integration, error parsing
|
|
62
62
|
|
|
63
|
+
### [Black Analysis](./black-analysis.md)
|
|
64
|
+
|
|
65
|
+
**Python Code Formatter**
|
|
66
|
+
|
|
67
|
+
- ✅ **Preserved**: Core formatting, pyproject config, check and write flows
|
|
68
|
+
- ⚙️ **Pass-throughs**: `line_length`, `target_version`, `fast`, `preview`, `diff`
|
|
69
|
+
- 🚀 **Notes**: Cooperates with Ruff via Lintro post-check policy
|
|
70
|
+
|
|
63
71
|
## Analysis Framework
|
|
64
72
|
|
|
65
73
|
Each analysis follows a consistent structure:
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Black Tool Analysis
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Black is the Python code formatter that provides opinionated, deterministic
|
|
6
|
+
formatting. This analysis compares Lintro's wrapper implementation with the
|
|
7
|
+
core Black tool.
|
|
8
|
+
|
|
9
|
+
## Core Tool Capabilities
|
|
10
|
+
|
|
11
|
+
Black provides a stable set of formatting capabilities:
|
|
12
|
+
|
|
13
|
+
- Code formatting with stable, minimal-diff output
|
|
14
|
+
- Check mode (`--check`) and write mode (default)
|
|
15
|
+
- Configuration via `pyproject.toml`
|
|
16
|
+
- Options such as `--line-length`, `--target-version`, `--fast`, `--preview`,
|
|
17
|
+
and `--diff`
|
|
18
|
+
|
|
19
|
+
## Lintro Implementation Analysis
|
|
20
|
+
|
|
21
|
+
### ✅ Preserved Features
|
|
22
|
+
|
|
23
|
+
- Formatting via Black with check and write flows
|
|
24
|
+
- Respect for Black's configuration in `pyproject.toml`
|
|
25
|
+
- Standard CLI behavior surfaced through the wrapper
|
|
26
|
+
|
|
27
|
+
### ⚙️ Runtime Options (Pass-through)
|
|
28
|
+
|
|
29
|
+
Lintro exposes a subset of Black's CLI options for controlled pass-through:
|
|
30
|
+
|
|
31
|
+
- `line_length` → `--line-length`
|
|
32
|
+
- `target_version` → `--target-version`
|
|
33
|
+
- `fast` → `--fast`
|
|
34
|
+
- `preview` → `--preview`
|
|
35
|
+
- `diff` → `--diff` (when formatting during fix)
|
|
36
|
+
|
|
37
|
+
These can be provided via `--tool-options` or through
|
|
38
|
+
`[tool.lintro.black]` in `pyproject.toml`.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# CLI overrides
|
|
42
|
+
lintro check . --tool-options "black:line_length=100,black:target_version=py313"
|
|
43
|
+
lintro format . --tool-options "black:fast=True,black:preview=True"
|
|
44
|
+
lintro format . --tool-options "black:diff=True"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```toml
|
|
48
|
+
[tool.lintro.black]
|
|
49
|
+
line_length = 100
|
|
50
|
+
target_version = "py313"
|
|
51
|
+
fast = false
|
|
52
|
+
preview = false
|
|
53
|
+
diff = false
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 🧩 Cooperation with Ruff
|
|
57
|
+
|
|
58
|
+
When Black is configured as a post-check in Lintro, Ruff focuses on linting by
|
|
59
|
+
default to avoid double-formatting. See the Ruff analysis for details on the
|
|
60
|
+
Ruff↔Black policy and how to override with `--tool-options`.
|
|
61
|
+
|
|
62
|
+
## Usage Comparison
|
|
63
|
+
|
|
64
|
+
### Core Black
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Check
|
|
68
|
+
black --check src/
|
|
69
|
+
|
|
70
|
+
# Format
|
|
71
|
+
black src/
|
|
72
|
+
|
|
73
|
+
# With options
|
|
74
|
+
black --line-length 100 --target-version py313 src/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Lintro Wrapper
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from lintro.tools.implementations.tool_black import BlackTool
|
|
81
|
+
|
|
82
|
+
tool = BlackTool()
|
|
83
|
+
tool.set_options(line_length=100, target_version="py313")
|
|
84
|
+
result = tool.check(["src/"])
|
|
85
|
+
# or
|
|
86
|
+
result = tool.fix(["src/"])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
With CLI overrides:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
lintro check src/ --tool-options "black:line_length=100,black:target_version=py313"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Configuration Strategy
|
|
96
|
+
|
|
97
|
+
- Primary configuration via Black's own `pyproject.toml`
|
|
98
|
+
- Optional overrides via `[tool.lintro.black]` and `--tool-options`
|
|
99
|
+
- Black can be used as a post-check via `[tool.lintro.post_checks]`
|
|
100
|
+
|
|
101
|
+
## ⚠️ Limited/Missing Features
|
|
102
|
+
|
|
103
|
+
- No JSON output; Black output is parsed from text
|
|
104
|
+
- Only a curated subset of Black options are passed through at runtime
|
|
105
|
+
- No stdin-based formatting via wrapper (run core Black for advanced usage)
|
|
106
|
+
|
|
107
|
+
## Recommendations
|
|
108
|
+
|
|
109
|
+
- Use Black post-checks to ensure final formatting consistency when combining
|
|
110
|
+
tools (Ruff for lint; Black for formatting)
|
|
111
|
+
- Prefer `pyproject.toml` for defaults; use `--tool-options` for ad-hoc runs
|
|
@@ -50,6 +50,27 @@ cmd = self._get_executable_command("ruff") + ["format"]
|
|
|
50
50
|
- ✅ **Fix options**: `fix_only`, `unsafe_fixes`, `show_fixes`
|
|
51
51
|
- ✅ **Formatting control**: `format` boolean to enable/disable formatting
|
|
52
52
|
|
|
53
|
+
### Cooperation with Black (Policy)
|
|
54
|
+
|
|
55
|
+
When Black is configured as a post-check in Lintro, Ruff focuses on linting by
|
|
56
|
+
default:
|
|
57
|
+
|
|
58
|
+
- In `lintro format`, Ruff fixes lint issues while `format=False` unless
|
|
59
|
+
explicitly overridden via `--tool-options ruff:format=True`.
|
|
60
|
+
- In `lintro check`, Ruff runs lint checks with `format_check=False` unless
|
|
61
|
+
explicitly overridden via `--tool-options ruff:format_check=True`.
|
|
62
|
+
|
|
63
|
+
This avoids double-formatting and lets Black handle final formatting. You can
|
|
64
|
+
override either side via CLI or `[tool.lintro.ruff]` and `[tool.lintro.post_checks]`.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Force Ruff to format even with Black post-checks enabled
|
|
68
|
+
lintro format --tool-options "ruff:format=True"
|
|
69
|
+
|
|
70
|
+
# Force Ruff to include format-check during check
|
|
71
|
+
lintro check --tool-options "ruff:format_check=True"
|
|
72
|
+
```
|
|
73
|
+
|
|
53
74
|
### ⚠️ Limited/Missing Features
|
|
54
75
|
|
|
55
76
|
**Advanced Configuration:**
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Formatter for Black issues."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from lintro.formatters.core.table_descriptor import TableDescriptor
|
|
6
|
+
from lintro.formatters.styles.csv import CsvStyle
|
|
7
|
+
from lintro.formatters.styles.grid import GridStyle
|
|
8
|
+
from lintro.formatters.styles.html import HtmlStyle
|
|
9
|
+
from lintro.formatters.styles.json import JsonStyle
|
|
10
|
+
from lintro.formatters.styles.markdown import MarkdownStyle
|
|
11
|
+
from lintro.formatters.styles.plain import PlainStyle
|
|
12
|
+
from lintro.parsers.black.black_issue import BlackIssue
|
|
13
|
+
from lintro.utils.path_utils import normalize_file_path_for_display
|
|
14
|
+
|
|
15
|
+
FORMAT_MAP = {
|
|
16
|
+
"plain": PlainStyle(),
|
|
17
|
+
"grid": GridStyle(),
|
|
18
|
+
"markdown": MarkdownStyle(),
|
|
19
|
+
"html": HtmlStyle(),
|
|
20
|
+
"json": JsonStyle(),
|
|
21
|
+
"csv": CsvStyle(),
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class BlackTableDescriptor(TableDescriptor):
|
|
26
|
+
def get_columns(self) -> list[str]:
|
|
27
|
+
return ["File", "Message"]
|
|
28
|
+
|
|
29
|
+
def get_rows(self, issues: list[BlackIssue]) -> list[list[str]]:
|
|
30
|
+
rows: list[list[str]] = []
|
|
31
|
+
for issue in issues:
|
|
32
|
+
rows.append(
|
|
33
|
+
[
|
|
34
|
+
normalize_file_path_for_display(issue.file),
|
|
35
|
+
issue.message,
|
|
36
|
+
],
|
|
37
|
+
)
|
|
38
|
+
return rows
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def format_black_issues(issues: list[BlackIssue], format: str = "grid") -> str:
|
|
42
|
+
descriptor = BlackTableDescriptor()
|
|
43
|
+
formatter = FORMAT_MAP.get(format, GridStyle())
|
|
44
|
+
columns = descriptor.get_columns()
|
|
45
|
+
rows = descriptor.get_rows(issues)
|
|
46
|
+
if format == "json":
|
|
47
|
+
return formatter.format(columns=columns, rows=rows, tool_name="black")
|
|
48
|
+
return formatter.format(columns=columns, rows=rows)
|
|
@@ -63,7 +63,9 @@ def format_darglint_issues(
|
|
|
63
63
|
# For JSON format, pass tool name
|
|
64
64
|
if format == "json":
|
|
65
65
|
formatted_table = formatter.format(
|
|
66
|
-
columns=columns,
|
|
66
|
+
columns=columns,
|
|
67
|
+
rows=rows,
|
|
68
|
+
tool_name="darglint",
|
|
67
69
|
)
|
|
68
70
|
else:
|
|
69
71
|
# For other formats, use standard formatting
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Black issue models.
|
|
2
|
+
|
|
3
|
+
This module defines lightweight dataclasses used to represent Black findings
|
|
4
|
+
in a normalized form that Lintro formatters can consume.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class BlackIssue:
|
|
14
|
+
"""Represents a Black formatting issue.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
file: Path to the file with a formatting difference.
|
|
18
|
+
message: Short human-readable description (e.g., "Would reformat file").
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
file: str
|
|
22
|
+
message: str
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Parser for Black output.
|
|
2
|
+
|
|
3
|
+
Black commonly emits terse messages like:
|
|
4
|
+
- "would reformat foo.py" (check mode with --check)
|
|
5
|
+
- "reformatted foo.py" (fix mode)
|
|
6
|
+
- a summary line like "1 file would be reformatted" or
|
|
7
|
+
"2 files reformatted" (with no per-file lines in some environments).
|
|
8
|
+
|
|
9
|
+
We normalize items into ``BlackIssue`` objects so the table formatter can
|
|
10
|
+
render consistent rows. When only a summary is present, we synthesize one
|
|
11
|
+
``BlackIssue`` per counted file with ``file`` set to "<unknown>" so totals
|
|
12
|
+
remain accurate across environments.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import re
|
|
18
|
+
from collections.abc import Iterable
|
|
19
|
+
|
|
20
|
+
from lintro.parsers.black.black_issue import BlackIssue
|
|
21
|
+
|
|
22
|
+
_WOULD_REFORMAT = re.compile(r"^would reformat\s+(?P<file>.+)$", re.IGNORECASE)
|
|
23
|
+
_REFORMATTED = re.compile(r"^reformatted\s+(?P<file>.+)$", re.IGNORECASE)
|
|
24
|
+
_SUMMARY_WOULD = re.compile(
|
|
25
|
+
r"(?P<count>\d+)\s+file(?:s)?\s+would\s+be\s+reformatted\.?",
|
|
26
|
+
re.IGNORECASE,
|
|
27
|
+
)
|
|
28
|
+
_SUMMARY_REFORMATTED = re.compile(
|
|
29
|
+
r"(?P<count>\d+)\s+file(?:s)?\s+reformatted\.?",
|
|
30
|
+
re.IGNORECASE,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _iter_issue_lines(lines: Iterable[str]) -> Iterable[str]:
|
|
35
|
+
for line in lines:
|
|
36
|
+
s = line.strip()
|
|
37
|
+
if not s:
|
|
38
|
+
continue
|
|
39
|
+
yield s
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def parse_black_output(output: str) -> list[BlackIssue]:
|
|
43
|
+
"""Parse Black CLI output into a list of ``BlackIssue`` objects.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
output: Raw stdout+stderr from a Black invocation.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
list[BlackIssue]: Per-file issues indicating formatting diffs. If only
|
|
50
|
+
a summary is present (no per-file lines), returns a synthesized list
|
|
51
|
+
sized to the summary count with ``file`` set to "<unknown>".
|
|
52
|
+
"""
|
|
53
|
+
if not output:
|
|
54
|
+
return []
|
|
55
|
+
|
|
56
|
+
issues: list[BlackIssue] = []
|
|
57
|
+
for line in _iter_issue_lines(output.splitlines()):
|
|
58
|
+
m = _WOULD_REFORMAT.match(line)
|
|
59
|
+
if m:
|
|
60
|
+
issues.append(
|
|
61
|
+
BlackIssue(file=m.group("file"), message="Would reformat file"),
|
|
62
|
+
)
|
|
63
|
+
continue
|
|
64
|
+
m = _REFORMATTED.match(line)
|
|
65
|
+
if m:
|
|
66
|
+
issues.append(BlackIssue(file=m.group("file"), message="Reformatted file"))
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
# Some environments (e.g., CI) may emit only a summary line without listing
|
|
70
|
+
# per-file entries. In that case, synthesize issues so counts remain
|
|
71
|
+
# consistent across environments.
|
|
72
|
+
if not issues:
|
|
73
|
+
m_sum = _SUMMARY_WOULD.search(output)
|
|
74
|
+
if not m_sum:
|
|
75
|
+
m_sum = _SUMMARY_REFORMATTED.search(output)
|
|
76
|
+
if m_sum:
|
|
77
|
+
try:
|
|
78
|
+
count = int(m_sum.group("count"))
|
|
79
|
+
except Exception:
|
|
80
|
+
count = 0
|
|
81
|
+
if count > 0:
|
|
82
|
+
for _ in range(count):
|
|
83
|
+
issues.append(
|
|
84
|
+
BlackIssue(
|
|
85
|
+
file="<unknown>",
|
|
86
|
+
message="Formatting change detected",
|
|
87
|
+
),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return issues
|
|
@@ -32,7 +32,7 @@ def parse_hadolint_output(output: str) -> list[HadolintIssue]:
|
|
|
32
32
|
|
|
33
33
|
# Pattern for hadolint output: filename:line code level: message
|
|
34
34
|
pattern: re.Pattern[str] = re.compile(
|
|
35
|
-
r"^(.+?):(\d+)\s+([A-Z]+\d+)\s+(error|warning|info|style):\s+(.+)$"
|
|
35
|
+
r"^(.+?):(\d+)\s+([A-Z]+\d+)\s+(error|warning|info|style):\s+(.+)$",
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
lines: list[str] = output.splitlines()
|
|
@@ -59,7 +59,7 @@ def parse_hadolint_output(output: str) -> list[HadolintIssue]:
|
|
|
59
59
|
level=level,
|
|
60
60
|
code=code,
|
|
61
61
|
message=message.strip(),
|
|
62
|
-
)
|
|
62
|
+
),
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
return issues
|