lintro 0.6.3__tar.gz → 0.8.0__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.6.3/lintro.egg-info → lintro-0.8.0}/PKG-INFO +46 -10
- {lintro-0.6.3 → lintro-0.8.0}/README.md +39 -3
- {lintro-0.6.3 → lintro-0.8.0}/assets/images/coverage-badge.svg +3 -3
- {lintro-0.6.3 → lintro-0.8.0}/docs/README.md +5 -4
- lintro-0.8.0/docs/security/assurance.md +79 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/__init__.py +1 -1
- {lintro-0.6.3 → lintro-0.8.0}/lintro/cli.py +6 -0
- lintro-0.8.0/lintro/enums/__init__.py +1 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/darglint_strictness.py +10 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/hadolint_enums.py +22 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/yamllint_format.py +11 -0
- lintro-0.8.0/lintro/exceptions/__init__.py +1 -0
- lintro-0.8.0/lintro/formatters/__init__.py +1 -0
- lintro-0.8.0/lintro/formatters/core/__init__.py +1 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/core/output_style.py +11 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/core/table_descriptor.py +8 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/csv.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/grid.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/html.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/json.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/markdown.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/plain.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/black_formatter.py +27 -5
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/darglint_formatter.py +16 -1
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/hadolint_formatter.py +13 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/prettier_formatter.py +15 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/ruff_formatter.py +16 -1
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/yamllint_formatter.py +14 -1
- lintro-0.8.0/lintro/models/__init__.py +1 -0
- lintro-0.8.0/lintro/models/core/__init__.py +1 -0
- lintro-0.8.0/lintro/models/core/tool_config.py +27 -0
- lintro-0.8.0/lintro/parsers/darglint/__init__.py +1 -0
- lintro-0.8.0/lintro/parsers/darglint/darglint_issue.py +20 -0
- lintro-0.8.0/lintro/parsers/prettier/__init__.py +1 -0
- lintro-0.8.0/lintro/parsers/prettier/prettier_issue.py +22 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/ruff/ruff_parser.py +6 -2
- lintro-0.8.0/lintro/parsers/yamllint/__init__.py +1 -0
- lintro-0.8.0/lintro/tools/core/__init__.py +1 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/core/tool_base.py +32 -6
- lintro-0.8.0/lintro/tools/implementations/__init__.py +1 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_bandit.py +11 -22
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_darglint.py +3 -1
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/tool_enum.py +2 -0
- lintro-0.8.0/lintro/utils/__init__.py +1 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/ascii_normalize_cli.py +5 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/tool_utils.py +6 -10
- {lintro-0.6.3 → lintro-0.8.0/lintro.egg-info}/PKG-INFO +46 -10
- {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/SOURCES.txt +4 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/requires.txt +6 -6
- {lintro-0.6.3 → lintro-0.8.0}/pyproject.toml +8 -5
- {lintro-0.6.3 → lintro-0.8.0}/tests/conftest.py +2 -2
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_darglint_integration.py +21 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_prettier_integration.py +8 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_ruff_black_policy.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_ruff_integration.py +1 -2
- lintro-0.8.0/tests/scripts/test_ci_post_pr_comment.py +336 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_extract_version.py +21 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_ghcr_prune_untagged.py +32 -2
- lintro-0.8.0/tests/scripts/test_github_comment_utilities.py +433 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_script_environment.py +263 -1
- {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_semantic_release_compute_next.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_shell_scripts.py +76 -2
- {lintro-0.6.3 → lintro-0.8.0}/tests/test_documentation.py +1 -1
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_ascii_normalize.py +8 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_command_building.py +3 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_config_hydration.py +10 -1
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_formatter.py +5 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_parser.py +5 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_tool.py +32 -1
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_tool_more.py +7 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_cli_commands.py +3 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_cli_commands_more.py +17 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_cli_programmatic.py +17 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_compatibility_ruff_black.py +79 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_config_loader.py +8 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_config_loader_more.py +6 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_console_logger.py +14 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_console_logger_more.py +7 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_enums_and_normalizers.py +6 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_exceptions.py +3 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_formatters_tables.py +22 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_output_manager_reports.py +27 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_parsers_actionlint.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_ruff_parser_additional.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_ruff_parser_more.py +7 -1
- lintro-0.8.0/tests/unit/test_subprocess_validator.py +78 -0
- lintro-0.8.0/tests/unit/test_tool_base_subprocess.py +93 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor.py +146 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor_fmt_exclusion.py +1 -1
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor_post_checks.py +42 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_manager.py +9 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_utils.py +14 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_utils_fallbacks.py +2 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_utils_more.py +12 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/utils/test_output_manager.py +28 -0
- lintro-0.6.3/docs/security/assurance.md +0 -27
- lintro-0.6.3/lintro/enums/__init__.py +0 -0
- lintro-0.6.3/lintro/exceptions/__init__.py +0 -0
- lintro-0.6.3/lintro/formatters/__init__.py +0 -0
- lintro-0.6.3/lintro/formatters/core/__init__.py +0 -0
- lintro-0.6.3/lintro/models/__init__.py +0 -0
- lintro-0.6.3/lintro/models/core/__init__.py +0 -0
- lintro-0.6.3/lintro/models/core/tool_config.py +0 -23
- lintro-0.6.3/lintro/parsers/darglint/__init__.py +0 -0
- lintro-0.6.3/lintro/parsers/darglint/darglint_issue.py +0 -9
- lintro-0.6.3/lintro/parsers/prettier/__init__.py +0 -0
- lintro-0.6.3/lintro/parsers/prettier/prettier_issue.py +0 -10
- lintro-0.6.3/lintro/parsers/yamllint/__init__.py +0 -0
- lintro-0.6.3/lintro/tools/core/__init__.py +0 -0
- lintro-0.6.3/lintro/tools/implementations/__init__.py +0 -0
- lintro-0.6.3/lintro/utils/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/LICENSE +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/MANIFEST.in +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/assets/images/lintro.png +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/configuration.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/contributing.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/coverage-setup.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/docker.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/getting-started.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/github-integration.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/lintro-self-use.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/security/requirements.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/style-guide.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/README.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/actionlint-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/bandit-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/black-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/darglint-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/hadolint-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/prettier-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/ruff-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/yamllint-analysis.md +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/__main__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/ascii-art/fail.txt +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/ascii-art/success.txt +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/check.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/format.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/list_tools.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/action.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/group_by.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/output_format.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/tool_name.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/tool_type.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/exceptions/errors.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/actionlint_formatter.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/bandit_formatter.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/models/core/tool.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/models/core/tool_result.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/actionlint/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/black/black_issue.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/black/black_parser.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/darglint/darglint_parser.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/hadolint/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/prettier/prettier_parser.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/ruff/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/ruff/ruff_issue.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/core/tool_manager.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_actionlint.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_black.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_hadolint.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_prettier.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_ruff.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_yamllint.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/config.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/console_logger.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/formatting.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/output_manager.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/path_utils.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/tool_executor.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/dependency_links.txt +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/entry_points.txt +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/top_level.txt +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/setup.cfg +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/Dockerfile.violations +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/actionlint_violations.yml +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/bandit_violations.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/darglint_violations.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/prettier_violations.js +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/ruff_black_e501_wrappable.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/ruff_clean.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/ruff_violations.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/test_samples/yaml_violations.yml +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/cli/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/cli/conftest.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/cli/test_cli.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/formatters/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/formatters/conftest.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/formatters/test_formatters.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/conftest.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_actionlint_integration.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_bandit_integration.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_hadolint_integration.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_yamllint_integration.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_delete_previous_lintro_comments.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_formatter_mapping.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_parsing.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor_more.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/utils/__init__.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/utils/conftest.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/tests/utils/test_formatting.py +0 -0
- {lintro-0.6.3 → lintro-0.8.0}/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.8.0
|
|
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
|
|
@@ -50,21 +50,21 @@ Requires-Dist: toml==0.10.2
|
|
|
50
50
|
Requires-Dist: defusedxml==0.7.1
|
|
51
51
|
Provides-Extra: dev
|
|
52
52
|
Requires-Dist: pytest==8.4.2; extra == "dev"
|
|
53
|
-
Requires-Dist: pytest-cov==
|
|
54
|
-
Requires-Dist: pytest-mock==3.15.
|
|
53
|
+
Requires-Dist: pytest-cov==7.0.0; extra == "dev"
|
|
54
|
+
Requires-Dist: pytest-mock==3.15.1; extra == "dev"
|
|
55
55
|
Requires-Dist: pytest-xdist==3.8.0; extra == "dev"
|
|
56
|
-
Requires-Dist: tox==4.30.
|
|
56
|
+
Requires-Dist: tox==4.30.3; extra == "dev"
|
|
57
57
|
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.
|
|
61
|
+
Requires-Dist: python-semantic-release==10.4.1; 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
|
|
65
65
|
Requires-Dist: pytest==8.4.2; extra == "test"
|
|
66
|
-
Requires-Dist: pytest-cov==
|
|
67
|
-
Requires-Dist: pytest-mock==3.15.
|
|
66
|
+
Requires-Dist: pytest-cov==7.0.0; extra == "test"
|
|
67
|
+
Requires-Dist: pytest-mock==3.15.1; extra == "test"
|
|
68
68
|
Requires-Dist: pytest-xdist==3.8.0; extra == "test"
|
|
69
69
|
Requires-Dist: assertpy==1.1; extra == "test"
|
|
70
70
|
Provides-Extra: typing
|
|
@@ -88,12 +88,12 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
88
88
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/test-and-coverage.yml?query=branch%3Amain)
|
|
89
89
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/ci-lintro-analysis.yml?query=branch%3Amain)
|
|
90
90
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/docker-build-publish.yml?query=branch%3Amain)
|
|
91
|
+
[&branch=main>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml?query=branch%3Amain)
|
|
92
|
+
[&event=push>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/publish-pypi-on-tag.yml?query=event%3Apush)
|
|
91
93
|
[](https://pypi.org/project/lintro/)
|
|
92
94
|
|
|
93
95
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/codeql.yml?query=branch%3Amain)
|
|
94
|
-
[](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro)
|
|
95
|
-
|
|
96
|
-
[](https://www.bestpractices.dev/projects/11142)
|
|
96
|
+
[](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro) [](docs/security/assurance.md) [](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml) [](https://www.bestpractices.dev/projects/11142)
|
|
97
97
|
|
|
98
98
|
### Why Lintro?
|
|
99
99
|
|
|
@@ -114,6 +114,42 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
114
114
|
- **Docker support** for containerized environments
|
|
115
115
|
- **CI/CD integration** with GitHub Actions
|
|
116
116
|
|
|
117
|
+
## Security & Compliance
|
|
118
|
+
|
|
119
|
+
Lintro follows modern security best practices and provides comprehensive supply chain transparency:
|
|
120
|
+
|
|
121
|
+
- **SBOM Generation**: Automated Software Bill of Materials on every push to main
|
|
122
|
+
- **Formats**: CycloneDX 1.6 and SPDX 2.3 (industry standards)
|
|
123
|
+
- **Compliance**: Meets Executive Order 14028 requirements for federal software
|
|
124
|
+
- **Download**: [Latest SBOM artifacts](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml)
|
|
125
|
+
- **Documentation**: See [Security Assurance](docs/security/assurance.md) for details
|
|
126
|
+
|
|
127
|
+
### What's in the SBOM?
|
|
128
|
+
|
|
129
|
+
The SBOM provides a complete inventory of all dependencies:
|
|
130
|
+
|
|
131
|
+
- All Python packages with exact versions
|
|
132
|
+
- All npm packages (like Prettier)
|
|
133
|
+
- All GitHub Actions dependencies (pinned by SHA)
|
|
134
|
+
- Transitive dependencies
|
|
135
|
+
- License information
|
|
136
|
+
|
|
137
|
+
### For Enterprise Users
|
|
138
|
+
|
|
139
|
+
Download SBOMs for security auditing and compliance:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Download latest SBOM artifacts
|
|
143
|
+
gh run download -R TurboCoder13/py-lintro \
|
|
144
|
+
--name sbom-artifacts \
|
|
145
|
+
$(gh run list -R TurboCoder13/py-lintro \
|
|
146
|
+
-w "Security - SBOM Generation" -L 1 \
|
|
147
|
+
--json databaseId -q '.[0].databaseId')
|
|
148
|
+
|
|
149
|
+
# Scan for vulnerabilities (requires grype)
|
|
150
|
+
grype sbom:main-*-py-lintro-sbom.spdx-2.3.json
|
|
151
|
+
```
|
|
152
|
+
|
|
117
153
|
## Supported Tools
|
|
118
154
|
|
|
119
155
|
| Tool | Language | Auto-fix |
|
|
@@ -14,12 +14,12 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
14
14
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/test-and-coverage.yml?query=branch%3Amain)
|
|
15
15
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/ci-lintro-analysis.yml?query=branch%3Amain)
|
|
16
16
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/docker-build-publish.yml?query=branch%3Amain)
|
|
17
|
+
[&branch=main>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml?query=branch%3Amain)
|
|
18
|
+
[&event=push>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/publish-pypi-on-tag.yml?query=event%3Apush)
|
|
17
19
|
[](https://pypi.org/project/lintro/)
|
|
18
20
|
|
|
19
21
|
[](https://github.com/TurboCoder13/py-lintro/actions/workflows/codeql.yml?query=branch%3Amain)
|
|
20
|
-
[](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro)
|
|
21
|
-
|
|
22
|
-
[](https://www.bestpractices.dev/projects/11142)
|
|
22
|
+
[](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro) [](docs/security/assurance.md) [](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml) [](https://www.bestpractices.dev/projects/11142)
|
|
23
23
|
|
|
24
24
|
### Why Lintro?
|
|
25
25
|
|
|
@@ -40,6 +40,42 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
40
40
|
- **Docker support** for containerized environments
|
|
41
41
|
- **CI/CD integration** with GitHub Actions
|
|
42
42
|
|
|
43
|
+
## Security & Compliance
|
|
44
|
+
|
|
45
|
+
Lintro follows modern security best practices and provides comprehensive supply chain transparency:
|
|
46
|
+
|
|
47
|
+
- **SBOM Generation**: Automated Software Bill of Materials on every push to main
|
|
48
|
+
- **Formats**: CycloneDX 1.6 and SPDX 2.3 (industry standards)
|
|
49
|
+
- **Compliance**: Meets Executive Order 14028 requirements for federal software
|
|
50
|
+
- **Download**: [Latest SBOM artifacts](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml)
|
|
51
|
+
- **Documentation**: See [Security Assurance](docs/security/assurance.md) for details
|
|
52
|
+
|
|
53
|
+
### What's in the SBOM?
|
|
54
|
+
|
|
55
|
+
The SBOM provides a complete inventory of all dependencies:
|
|
56
|
+
|
|
57
|
+
- All Python packages with exact versions
|
|
58
|
+
- All npm packages (like Prettier)
|
|
59
|
+
- All GitHub Actions dependencies (pinned by SHA)
|
|
60
|
+
- Transitive dependencies
|
|
61
|
+
- License information
|
|
62
|
+
|
|
63
|
+
### For Enterprise Users
|
|
64
|
+
|
|
65
|
+
Download SBOMs for security auditing and compliance:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Download latest SBOM artifacts
|
|
69
|
+
gh run download -R TurboCoder13/py-lintro \
|
|
70
|
+
--name sbom-artifacts \
|
|
71
|
+
$(gh run list -R TurboCoder13/py-lintro \
|
|
72
|
+
-w "Security - SBOM Generation" -L 1 \
|
|
73
|
+
--json databaseId -q '.[0].databaseId')
|
|
74
|
+
|
|
75
|
+
# Scan for vulnerabilities (requires grype)
|
|
76
|
+
grype sbom:main-*-py-lintro-sbom.spdx-2.3.json
|
|
77
|
+
```
|
|
78
|
+
|
|
43
79
|
## Supported Tools
|
|
44
80
|
|
|
45
81
|
| Tool | Language | Auto-fix |
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
</clipPath>
|
|
10
10
|
<g clip-path="url(#a)">
|
|
11
11
|
<path fill="#555" d="M0 0h63v20H0z"/>
|
|
12
|
-
<path fill="#
|
|
12
|
+
<path fill="#4c1" d="M63 0h36v20H63z"/>
|
|
13
13
|
<path fill="url(#b)" d="M0 0h99v20H0z"/>
|
|
14
14
|
</g>
|
|
15
15
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
|
|
16
16
|
<text x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">coverage</text>
|
|
17
17
|
<text x="325" y="140" transform="scale(.1)" textLength="530">coverage</text>
|
|
18
|
-
<text x="800" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="260">83.
|
|
19
|
-
<text x="800" y="140" transform="scale(.1)" textLength="260">83.
|
|
18
|
+
<text x="800" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="260">83.9%</text>
|
|
19
|
+
<text x="800" y="140" transform="scale(.1)" textLength="260">83.9%</text>
|
|
20
20
|
</g>
|
|
21
21
|
</svg>
|
|
@@ -30,7 +30,6 @@ Welcome to the Lintro documentation! This hub provides comprehensive guides for
|
|
|
30
30
|
- **[Style Guide](style-guide.md)** - Coding standards and best practices
|
|
31
31
|
- **[Coverage Setup](coverage-setup.md)** - Test coverage configuration reference
|
|
32
32
|
- **[Self-Use Documentation](lintro-self-use.md)** - How Lintro uses itself
|
|
33
|
-
- **[Removed CLI Options](removed_cli_options.md)** - Deprecated features reference
|
|
34
33
|
|
|
35
34
|
## 🚀 Quick Links
|
|
36
35
|
|
|
@@ -171,10 +170,12 @@ docker run --rm -v "$(pwd):/code" lintro:latest check
|
|
|
171
170
|
|
|
172
171
|
## 🆕 Recent Updates
|
|
173
172
|
|
|
173
|
+
- **Security audit framework** - Comprehensive security verification for workflows and scripts
|
|
174
|
+
- **DRY consolidation** - Reduced duplicate patterns across workflows and actions
|
|
175
|
+
- **Shell-free design** - Moved inline shell commands to dedicated scripts
|
|
176
|
+
- **Environment standardization** - Consistent variable usage across all workflows
|
|
174
177
|
- **Documentation restructure** - Improved organization and navigation
|
|
175
|
-
- **
|
|
176
|
-
- **Enhanced GitHub integration** - More workflow examples
|
|
177
|
-
- **Comprehensive configuration guide** - All tools covered
|
|
178
|
+
- **Enhanced tool analysis** - Detailed comparisons with core tools
|
|
178
179
|
|
|
179
180
|
## 🤝 Contributing to Documentation
|
|
180
181
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Security Assurance (Overview)
|
|
2
|
+
|
|
3
|
+
This assurance note explains how `py-lintro` meets its documented security requirements and provides pointers to evidence.
|
|
4
|
+
|
|
5
|
+
## Requirements Coverage
|
|
6
|
+
|
|
7
|
+
- Governance and Roles — see `GOVERNANCE.md`
|
|
8
|
+
- Contribution Integrity — DCO sign-offs required; see `DCO.md` and CI checks
|
|
9
|
+
- Responsible Disclosure — see `SECURITY.md`
|
|
10
|
+
- Branch Protection — enforced via Allstar (`.allstar/branch_protection.yaml`)
|
|
11
|
+
- Dependency Hygiene — Renovate, Dependency Review CI, `uv.lock`
|
|
12
|
+
- Static/SAST — Ruff, Bandit, CodeQL; policy checks for workflows (Actionlint)
|
|
13
|
+
- Container and Dockerfile — Hadolint
|
|
14
|
+
- SBOM (Software Bill of Materials) — Automated generation in CycloneDX 1.6 and SPDX 2.3 formats
|
|
15
|
+
- Workflow: `.github/workflows/sbom-on-main.yml`
|
|
16
|
+
- Generated on every push to main branch
|
|
17
|
+
- Includes all Python, npm, and GitHub Actions dependencies
|
|
18
|
+
- Artifacts available via GitHub Actions (90-day retention)
|
|
19
|
+
- Meets Executive Order 14028 federal software requirements
|
|
20
|
+
- Documentation and Versioning — `README.md`, `CHANGELOG.md`, semantic releases
|
|
21
|
+
|
|
22
|
+
## Evidence Pointers
|
|
23
|
+
|
|
24
|
+
- CI Workflows: `.github/workflows/*.yml`
|
|
25
|
+
- Allstar Policy: `.allstar/branch_protection.yaml`
|
|
26
|
+
- Scorecard: badge in `README.md`
|
|
27
|
+
- Coverage: `coverage.xml` and README badge
|
|
28
|
+
|
|
29
|
+
## SBOM (Supply Chain Transparency)
|
|
30
|
+
|
|
31
|
+
py-lintro automatically generates Software Bill of Materials (SBOM) for supply chain security:
|
|
32
|
+
|
|
33
|
+
### What is Generated
|
|
34
|
+
|
|
35
|
+
- **CycloneDX 1.6 JSON**: Industry-standard format for dependency tracking
|
|
36
|
+
- **SPDX 2.3 JSON**: Linux Foundation standard for license compliance
|
|
37
|
+
- **Complete inventory**: All direct and transitive dependencies
|
|
38
|
+
- **Cryptographic hashes**: For verification and integrity checking
|
|
39
|
+
|
|
40
|
+
### How to Access
|
|
41
|
+
|
|
42
|
+
1. **Via GitHub Actions UI**:
|
|
43
|
+
- Navigate to [SBOM workflow runs](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml)
|
|
44
|
+
- Select the latest successful run
|
|
45
|
+
- Download "sbom-artifacts" from the Artifacts section
|
|
46
|
+
|
|
47
|
+
2. **Via GitHub CLI**:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
gh run download -R TurboCoder13/py-lintro --name sbom-artifacts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
3. **Via API**:
|
|
54
|
+
```bash
|
|
55
|
+
gh api repos/TurboCoder13/py-lintro/actions/artifacts \
|
|
56
|
+
--jq '.artifacts[] | select(.name=="sbom-artifacts") | .archive_download_url'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Use Cases
|
|
60
|
+
|
|
61
|
+
- **Security Scanning**: Feed into vulnerability scanners (Grype, Snyk, etc.)
|
|
62
|
+
- **License Compliance**: Audit all dependency licenses
|
|
63
|
+
- **Supply Chain Security**: Track all software components
|
|
64
|
+
- **Federal Compliance**: Meets EO 14028 requirements
|
|
65
|
+
- **Enterprise Procurement**: Satisfy security questionnaires
|
|
66
|
+
|
|
67
|
+
### File Naming Convention
|
|
68
|
+
|
|
69
|
+
SBOM files are named: `{branch}-{commit-sha}-py-lintro-sbom.{format}.json`
|
|
70
|
+
|
|
71
|
+
Example: `main-3b97378f3438-py-lintro-sbom.cyclonedx-1.6.json`
|
|
72
|
+
|
|
73
|
+
This ensures traceability to exact codebase versions.
|
|
74
|
+
|
|
75
|
+
## Continuous Improvement
|
|
76
|
+
|
|
77
|
+
- Periodic updates via Renovate
|
|
78
|
+
- Automated analyses (Scorecard, CodeQL)
|
|
79
|
+
- Maintainer reviews for all changes
|
|
@@ -9,6 +9,12 @@ from lintro.cli_utils.commands.list_tools import list_tools_command
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class LintroGroup(click.Group):
|
|
12
|
+
"""Custom Click group with enhanced help rendering.
|
|
13
|
+
|
|
14
|
+
This group prints command aliases alongside their canonical names to make
|
|
15
|
+
the CLI help output more discoverable.
|
|
16
|
+
"""
|
|
17
|
+
|
|
12
18
|
def format_commands(
|
|
13
19
|
self,
|
|
14
20
|
ctx: click.Context,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Enumeration types used throughout the Lintro codebase."""
|
|
@@ -6,6 +6,8 @@ from enum import StrEnum, auto
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class DarglintStrictness(StrEnum):
|
|
9
|
+
"""Strictness levels recognized by Darglint checks."""
|
|
10
|
+
|
|
9
11
|
SHORT = auto()
|
|
10
12
|
LONG = auto()
|
|
11
13
|
FULL = auto()
|
|
@@ -14,6 +16,14 @@ class DarglintStrictness(StrEnum):
|
|
|
14
16
|
def normalize_darglint_strictness(
|
|
15
17
|
value: str | DarglintStrictness,
|
|
16
18
|
) -> DarglintStrictness:
|
|
19
|
+
"""Normalize a strictness value, defaulting to FULL on error.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
value: String or enum member representing strictness.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
DarglintStrictness: Normalized strictness enum value.
|
|
26
|
+
"""
|
|
17
27
|
if isinstance(value, DarglintStrictness):
|
|
18
28
|
return value
|
|
19
29
|
try:
|
|
@@ -6,6 +6,8 @@ from enum import StrEnum, auto
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class HadolintFormat(StrEnum):
|
|
9
|
+
"""Supported output formats for Hadolint."""
|
|
10
|
+
|
|
9
11
|
TTY = auto()
|
|
10
12
|
JSON = auto()
|
|
11
13
|
CHECKSTYLE = auto()
|
|
@@ -18,6 +20,8 @@ class HadolintFormat(StrEnum):
|
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
class HadolintFailureThreshold(StrEnum):
|
|
23
|
+
"""Hadolint failure thresholds used to gate exit status."""
|
|
24
|
+
|
|
21
25
|
ERROR = auto()
|
|
22
26
|
WARNING = auto()
|
|
23
27
|
INFO = auto()
|
|
@@ -27,6 +31,15 @@ class HadolintFailureThreshold(StrEnum):
|
|
|
27
31
|
|
|
28
32
|
|
|
29
33
|
def normalize_hadolint_format(value: str | HadolintFormat) -> HadolintFormat:
|
|
34
|
+
"""Normalize user input to a HadolintFormat.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
value: Existing enum member or string name of the format.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
HadolintFormat: Canonical enum value, defaulting to ``TTY`` when
|
|
41
|
+
parsing fails.
|
|
42
|
+
"""
|
|
30
43
|
if isinstance(value, HadolintFormat):
|
|
31
44
|
return value
|
|
32
45
|
try:
|
|
@@ -38,6 +51,15 @@ def normalize_hadolint_format(value: str | HadolintFormat) -> HadolintFormat:
|
|
|
38
51
|
def normalize_hadolint_threshold(
|
|
39
52
|
value: str | HadolintFailureThreshold,
|
|
40
53
|
) -> HadolintFailureThreshold:
|
|
54
|
+
"""Normalize user input to a HadolintFailureThreshold.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
value: Existing enum member or string name of the threshold.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
HadolintFailureThreshold: Canonical enum value, defaulting to ``INFO``
|
|
61
|
+
when parsing fails.
|
|
62
|
+
"""
|
|
41
63
|
if isinstance(value, HadolintFailureThreshold):
|
|
42
64
|
return value
|
|
43
65
|
try:
|
|
@@ -6,6 +6,8 @@ from enum import StrEnum, auto
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class YamllintFormat(StrEnum):
|
|
9
|
+
"""Output styles supported by Yamllint's CLI."""
|
|
10
|
+
|
|
9
11
|
PARSABLE = auto()
|
|
10
12
|
STANDARD = auto()
|
|
11
13
|
COLORED = auto()
|
|
@@ -14,6 +16,15 @@ class YamllintFormat(StrEnum):
|
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
def normalize_yamllint_format(value: str | YamllintFormat) -> YamllintFormat:
|
|
19
|
+
"""Normalize a value to a YamllintFormat enum member.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
value: Existing enum member or string name of the format.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
YamllintFormat: Canonical enum value, defaulting to ``PARSABLE`` when
|
|
26
|
+
parsing fails.
|
|
27
|
+
"""
|
|
17
28
|
if isinstance(value, YamllintFormat):
|
|
18
29
|
return value
|
|
19
30
|
try:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Project-specific exception classes and error helpers."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Formatters for converting tool outputs into human-friendly tables."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Core formatting abstractions for tool-agnostic table rendering."""
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
"""Output style abstraction for rendering tabular data.
|
|
2
|
+
|
|
3
|
+
Defines a minimal interface consumed by format-specific implementations.
|
|
4
|
+
"""
|
|
5
|
+
|
|
1
6
|
from abc import ABC, abstractmethod
|
|
2
7
|
from typing import Any
|
|
3
8
|
|
|
4
9
|
|
|
5
10
|
class OutputStyle(ABC):
|
|
11
|
+
"""Abstract base class for output style renderers.
|
|
12
|
+
|
|
13
|
+
Implementations convert tabular data into a concrete textual
|
|
14
|
+
representation (e.g., grid, markdown, plain).
|
|
15
|
+
"""
|
|
16
|
+
|
|
6
17
|
@abstractmethod
|
|
7
18
|
def format(
|
|
8
19
|
self,
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
"""Interfaces for describing table columns and rows for tool issues."""
|
|
2
|
+
|
|
1
3
|
from abc import ABC, abstractmethod
|
|
2
4
|
from typing import Any
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
class TableDescriptor(ABC):
|
|
8
|
+
"""Describe how to extract tabular data for a tool's issues.
|
|
9
|
+
|
|
10
|
+
Concrete implementations define column ordering and how to map issue
|
|
11
|
+
objects into a list of column values.
|
|
12
|
+
"""
|
|
13
|
+
|
|
6
14
|
@abstractmethod
|
|
7
15
|
def get_columns(self) -> list[str]:
|
|
8
16
|
"""Return the list of column names in order."""
|
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from lintro.formatters.core.table_descriptor import TableDescriptor
|
|
6
5
|
from lintro.formatters.styles.csv import CsvStyle
|
|
7
6
|
from lintro.formatters.styles.grid import GridStyle
|
|
8
7
|
from lintro.formatters.styles.html import HtmlStyle
|
|
9
8
|
from lintro.formatters.styles.json import JsonStyle
|
|
10
9
|
from lintro.formatters.styles.markdown import MarkdownStyle
|
|
11
10
|
from lintro.formatters.styles.plain import PlainStyle
|
|
12
|
-
from lintro.parsers.black.black_issue import BlackIssue
|
|
13
11
|
from lintro.utils.path_utils import normalize_file_path_for_display
|
|
14
12
|
|
|
15
13
|
FORMAT_MAP = {
|
|
@@ -22,11 +20,26 @@ FORMAT_MAP = {
|
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
|
|
25
|
-
class BlackTableDescriptor
|
|
23
|
+
class BlackTableDescriptor:
|
|
24
|
+
"""Column layout for Black issues in tabular output."""
|
|
25
|
+
|
|
26
26
|
def get_columns(self) -> list[str]:
|
|
27
|
+
"""Return ordered column headers for Black output rows.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
list[str]: Column names for the formatted table.
|
|
31
|
+
"""
|
|
27
32
|
return ["File", "Message"]
|
|
28
33
|
|
|
29
|
-
def get_rows(self, issues: list
|
|
34
|
+
def get_rows(self, issues: list) -> list[list[str]]:
|
|
35
|
+
"""Return formatted rows for Black issues.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
issues: Parsed Black issues to render.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
list[list[str]]: Table rows with normalized file paths and messages.
|
|
42
|
+
"""
|
|
30
43
|
rows: list[list[str]] = []
|
|
31
44
|
for issue in issues:
|
|
32
45
|
rows.append(
|
|
@@ -38,7 +51,16 @@ class BlackTableDescriptor(TableDescriptor):
|
|
|
38
51
|
return rows
|
|
39
52
|
|
|
40
53
|
|
|
41
|
-
def format_black_issues(issues
|
|
54
|
+
def format_black_issues(issues, format: str) -> str:
|
|
55
|
+
"""Format Black issues according to the chosen style.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
issues: Parsed Black issues.
|
|
59
|
+
format: Output style identifier.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
str: Rendered table string.
|
|
63
|
+
"""
|
|
42
64
|
descriptor = BlackTableDescriptor()
|
|
43
65
|
formatter = FORMAT_MAP.get(format, GridStyle())
|
|
44
66
|
columns = descriptor.get_columns()
|
|
@@ -21,13 +21,28 @@ FORMAT_MAP = {
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class DarglintTableDescriptor(TableDescriptor):
|
|
24
|
+
"""Describe columns and rows for Darglint issues."""
|
|
25
|
+
|
|
24
26
|
def get_columns(self) -> list[str]:
|
|
27
|
+
"""Return column headers for the Darglint issues table.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
list[str]: Column names for the formatted table.
|
|
31
|
+
"""
|
|
25
32
|
return ["File", "Line", "Code", "Message"]
|
|
26
33
|
|
|
27
34
|
def get_rows(
|
|
28
35
|
self,
|
|
29
36
|
issues: list[DarglintIssue],
|
|
30
37
|
) -> list[list[str]]:
|
|
38
|
+
"""Return rows for the Darglint table.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
issues: Parsed Darglint issues to format.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
list[list[str]]: Table rows with normalized path, line, code, message.
|
|
45
|
+
"""
|
|
31
46
|
rows = []
|
|
32
47
|
for issue in issues:
|
|
33
48
|
rows.append(
|
|
@@ -52,7 +67,7 @@ def format_darglint_issues(
|
|
|
52
67
|
format: Output format (plain, grid, markdown, html, json, csv).
|
|
53
68
|
|
|
54
69
|
Returns:
|
|
55
|
-
Formatted string representation of the issues.
|
|
70
|
+
str: Formatted string representation of the issues.
|
|
56
71
|
"""
|
|
57
72
|
descriptor = DarglintTableDescriptor()
|
|
58
73
|
columns = descriptor.get_columns()
|
|
@@ -19,6 +19,11 @@ class HadolintTableDescriptor(TableDescriptor):
|
|
|
19
19
|
"""Describe hadolint issue columns and row extraction."""
|
|
20
20
|
|
|
21
21
|
def get_columns(self) -> list[str]:
|
|
22
|
+
"""Return ordered column headers for the Hadolint table.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
list[str]: Column names for the formatted table.
|
|
26
|
+
"""
|
|
22
27
|
return [
|
|
23
28
|
"File",
|
|
24
29
|
"Line",
|
|
@@ -32,6 +37,14 @@ class HadolintTableDescriptor(TableDescriptor):
|
|
|
32
37
|
self,
|
|
33
38
|
issues: list[HadolintIssue],
|
|
34
39
|
) -> list[list[Any]]:
|
|
40
|
+
"""Return rows for the Hadolint issues table.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
issues: Parsed Hadolint issues to render.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
list[list[Any]]: Table rows with normalized file path and fields.
|
|
47
|
+
"""
|
|
35
48
|
rows: list[list[Any]] = []
|
|
36
49
|
for issue in issues:
|
|
37
50
|
rows.append(
|
|
@@ -21,13 +21,28 @@ FORMAT_MAP = {
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class PrettierTableDescriptor(TableDescriptor):
|
|
24
|
+
"""Describe columns and rows for Prettier issues."""
|
|
25
|
+
|
|
24
26
|
def get_columns(self) -> list[str]:
|
|
27
|
+
"""Return ordered column headers for the Prettier table.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
list[str]: Column names for the formatted table.
|
|
31
|
+
"""
|
|
25
32
|
return ["File", "Line", "Column", "Code", "Message"]
|
|
26
33
|
|
|
27
34
|
def get_rows(
|
|
28
35
|
self,
|
|
29
36
|
issues: list[PrettierIssue],
|
|
30
37
|
) -> list[list[str]]:
|
|
38
|
+
"""Return rows for the Prettier issues table.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
issues: Parsed Prettier issues to render.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
list[list[str]]: Table rows with normalized file path and fields.
|
|
45
|
+
"""
|
|
31
46
|
rows = []
|
|
32
47
|
for issue in issues:
|
|
33
48
|
rows.append(
|