lintro 0.9.0__tar.gz → 0.12.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.9.0/lintro.egg-info → lintro-0.12.0}/PKG-INFO +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/ruff-analysis.md +4 -2
- {lintro-0.9.0 → lintro-0.12.0}/lintro/__init__.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/lintro/cli_utils/commands/format.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/prettier/prettier_parser.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/__init__.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/tool_executor.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/tool_utils.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0/lintro.egg-info}/PKG-INFO +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/lintro.egg-info/SOURCES.txt +6 -0
- {lintro-0.9.0 → lintro-0.12.0}/pyproject.toml +6 -6
- lintro-0.12.0/test_samples/ruff_annotations_violations.py +53 -0
- lintro-0.12.0/test_samples/ruff_bugbear_violations.py +243 -0
- lintro-0.12.0/test_samples/ruff_naming_violations.py +26 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/cli/test_cli.py +8 -8
- {lintro-0.9.0 → lintro-0.12.0}/tests/conftest.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/tests/formatters/test_formatters.py +16 -16
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/conftest.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_actionlint_integration.py +3 -3
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_darglint_integration.py +4 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_hadolint_integration.py +8 -8
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_prettier_integration.py +5 -5
- lintro-0.12.0/tests/integration/test_ruff_annotations.py +78 -0
- lintro-0.12.0/tests/integration/test_ruff_bugbear.py +165 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_ruff_integration.py +25 -22
- lintro-0.12.0/tests/integration/test_ruff_naming.py +31 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_yamllint_integration.py +9 -9
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_delete_previous_lintro_comments.py +5 -5
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_ghcr_prune_untagged.py +7 -7
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_script_environment.py +30 -18
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_shell_scripts.py +24 -24
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_ascii_normalize.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_bandit_parsing.py +7 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_black_formatter.py +3 -3
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_black_parser.py +3 -3
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_black_tool.py +8 -5
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_black_tool_more.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_cli_commands.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_cli_commands_more.py +5 -5
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_cli_programmatic.py +4 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_compatibility_ruff_black.py +9 -9
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_config_loader.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_config_loader_more.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_console_logger.py +7 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_console_logger_more.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_enums_and_normalizers.py +6 -6
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_exceptions.py +1 -1
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_formatters_tables.py +4 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_output_manager_reports.py +3 -3
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_parsers_actionlint.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_ruff_parser_additional.py +2 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_ruff_parser_more.py +4 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_subprocess_validator.py +4 -2
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_base_subprocess.py +5 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_executor.py +29 -28
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_executor_more.py +30 -18
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_executor_post_checks.py +15 -11
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_manager.py +3 -3
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_utils.py +5 -5
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_utils_fallbacks.py +8 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_utils_more.py +12 -4
- {lintro-0.9.0 → lintro-0.12.0}/tests/utils/test_formatting.py +3 -3
- {lintro-0.9.0 → lintro-0.12.0}/tests/utils/test_output_manager.py +7 -7
- {lintro-0.9.0 → lintro-0.12.0}/tests/utils/test_path_utils.py +7 -7
- {lintro-0.9.0 → lintro-0.12.0}/LICENSE +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/MANIFEST.in +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/README.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/assets/images/coverage-badge.svg +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/assets/images/lintro.png +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/README.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/configuration.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/contributing.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/coverage-setup.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/docker.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/getting-started.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/github-integration.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/lintro-self-use.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/security/assurance.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/security/requirements.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/style-guide.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/README.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/actionlint-analysis.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/bandit-analysis.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/black-analysis.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/darglint-analysis.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/hadolint-analysis.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/prettier-analysis.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/docs/tool-analysis/yamllint-analysis.md +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/__main__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/ascii-art/fail.txt +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/ascii-art/success.txt +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/cli.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/cli_utils/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/cli_utils/commands/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/cli_utils/commands/check.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/cli_utils/commands/list_tools.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/action.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/darglint_strictness.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/group_by.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/hadolint_enums.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/output_format.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/tool_name.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/tool_type.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/enums/yamllint_format.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/exceptions/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/exceptions/errors.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/core/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/core/output_style.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/core/table_descriptor.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/styles/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/styles/csv.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/styles/grid.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/styles/html.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/styles/json.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/styles/markdown.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/styles/plain.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/actionlint_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/bandit_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/black_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/darglint_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/hadolint_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/prettier_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/ruff_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/formatters/tools/yamllint_formatter.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/models/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/models/core/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/models/core/tool.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/models/core/tool_config.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/models/core/tool_result.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/actionlint/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/black/black_issue.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/black/black_parser.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/darglint/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/darglint/darglint_issue.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/darglint/darglint_parser.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/hadolint/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/prettier/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/prettier/prettier_issue.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/ruff/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/ruff/ruff_issue.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/ruff/ruff_parser.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/yamllint/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/core/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/core/tool_base.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/core/tool_manager.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_actionlint.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_bandit.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_black.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_darglint.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_hadolint.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_prettier.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_ruff.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/implementations/tool_yamllint.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/tools/tool_enum.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/ascii_normalize_cli.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/config.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/console_logger.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/formatting.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/output_manager.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro/utils/path_utils.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro.egg-info/dependency_links.txt +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro.egg-info/entry_points.txt +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro.egg-info/requires.txt +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/lintro.egg-info/top_level.txt +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/setup.cfg +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/Dockerfile.violations +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/actionlint_violations.yml +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/bandit_violations.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/darglint_violations.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/prettier_violations.js +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/ruff_black_e501_wrappable.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/ruff_clean.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/ruff_violations.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/test_samples/yaml_violations.yml +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/cli/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/cli/conftest.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/formatters/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/formatters/conftest.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_bandit_integration.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/integration/test_ruff_black_policy.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_ci_post_pr_comment.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_extract_version.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_github_comment_utilities.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/scripts/test_semantic_release_compute_next.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/test_documentation.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_bandit_command_building.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_bandit_config_hydration.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_bandit_formatter_mapping.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/unit/test_tool_executor_fmt_exclusion.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/utils/__init__.py +0 -0
- {lintro-0.9.0 → lintro-0.12.0}/tests/utils/conftest.py +0 -0
|
@@ -151,7 +151,7 @@ lintro check --tool-options "ruff:format_check=True"
|
|
|
151
151
|
ruff check src/
|
|
152
152
|
|
|
153
153
|
# With specific rules
|
|
154
|
-
ruff check --select E501,W503 src/
|
|
154
|
+
ruff check --select E501,W503,B006 src/
|
|
155
155
|
|
|
156
156
|
# Auto-fixing
|
|
157
157
|
ruff check --fix src/
|
|
@@ -176,7 +176,7 @@ ruff_tool.fix()
|
|
|
176
176
|
|
|
177
177
|
# With specific options
|
|
178
178
|
ruff_tool.set_options(
|
|
179
|
-
select=["E501", "W503"],
|
|
179
|
+
select=["E501", "W503", "B006"],
|
|
180
180
|
line_length=88,
|
|
181
181
|
unsafe_fixes=True
|
|
182
182
|
)
|
|
@@ -209,8 +209,10 @@ Lintro preserves all Ruff rule categories:
|
|
|
209
209
|
| **Pyflakes** | F | Logical errors and undefined names |
|
|
210
210
|
| **pycodestyle** | E, W | PEP 8 style violations |
|
|
211
211
|
| **isort** | I | Import sorting issues |
|
|
212
|
+
| **pep8-naming** | N | Naming conventions (PEP 8) |
|
|
212
213
|
| **pydocstyle** | D | Docstring style violations |
|
|
213
214
|
| **pyupgrade** | UP | Python upgrade suggestions |
|
|
215
|
+
| **flake8-annotations** | ANN | Type annotation requirements |
|
|
214
216
|
| **flake8-bugbear** | B | Bug detection and complexity |
|
|
215
217
|
| **flake8-comprehensions** | C4 | Comprehension improvements |
|
|
216
218
|
| **flake8-simplify** | SIM | Code simplification suggestions |
|
|
@@ -140,7 +140,7 @@ def format_code_legacy(
|
|
|
140
140
|
None: This function does not return a value.
|
|
141
141
|
|
|
142
142
|
Raises:
|
|
143
|
-
|
|
143
|
+
RuntimeError: If format fails for any reason.
|
|
144
144
|
"""
|
|
145
145
|
args: list[str] = []
|
|
146
146
|
if paths:
|
|
@@ -163,5 +163,5 @@ def format_code_legacy(
|
|
|
163
163
|
runner = CliRunner()
|
|
164
164
|
result = runner.invoke(format_code, args)
|
|
165
165
|
if result.exit_code != DEFAULT_EXIT_CODE:
|
|
166
|
-
raise
|
|
166
|
+
raise RuntimeError(f"Format failed: {result.output}")
|
|
167
167
|
return None
|
|
@@ -21,7 +21,7 @@ tool_manager = ToolManager()
|
|
|
21
21
|
AVAILABLE_TOOLS = {tool_enum: tool_enum.value for tool_enum in ToolEnum}
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
for
|
|
24
|
+
for _tool_enum, tool_class in AVAILABLE_TOOLS.items():
|
|
25
25
|
tool_manager.register_tool(tool_class)
|
|
26
26
|
|
|
27
27
|
# Consolidated exports
|
|
@@ -125,8 +125,11 @@ test_samples/actionlint_violations.yml
|
|
|
125
125
|
test_samples/bandit_violations.py
|
|
126
126
|
test_samples/darglint_violations.py
|
|
127
127
|
test_samples/prettier_violations.js
|
|
128
|
+
test_samples/ruff_annotations_violations.py
|
|
128
129
|
test_samples/ruff_black_e501_wrappable.py
|
|
130
|
+
test_samples/ruff_bugbear_violations.py
|
|
129
131
|
test_samples/ruff_clean.py
|
|
132
|
+
test_samples/ruff_naming_violations.py
|
|
130
133
|
test_samples/ruff_violations.py
|
|
131
134
|
test_samples/yaml_violations.yml
|
|
132
135
|
tests/__init__.py
|
|
@@ -145,8 +148,11 @@ tests/integration/test_bandit_integration.py
|
|
|
145
148
|
tests/integration/test_darglint_integration.py
|
|
146
149
|
tests/integration/test_hadolint_integration.py
|
|
147
150
|
tests/integration/test_prettier_integration.py
|
|
151
|
+
tests/integration/test_ruff_annotations.py
|
|
148
152
|
tests/integration/test_ruff_black_policy.py
|
|
153
|
+
tests/integration/test_ruff_bugbear.py
|
|
149
154
|
tests/integration/test_ruff_integration.py
|
|
155
|
+
tests/integration/test_ruff_naming.py
|
|
150
156
|
tests/integration/test_yamllint_integration.py
|
|
151
157
|
tests/scripts/__init__.py
|
|
152
158
|
tests/scripts/test_ci_post_pr_comment.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "lintro"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.12.0"
|
|
8
8
|
description = "A unified CLI tool for code formatting, linting, and quality assurance"
|
|
9
9
|
keywords = [ "linting", "formatting", "code-quality", "cli", "python", "javascript", "yaml", "docker",]
|
|
10
10
|
classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Quality Assurance", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Utilities",]
|
|
@@ -65,11 +65,8 @@ indent-style = "space"
|
|
|
65
65
|
skip-magic-trailing-comma = false
|
|
66
66
|
|
|
67
67
|
[tool.ruff.lint]
|
|
68
|
-
select = [ "E", "F", "W", "I", "COM", "D", "UP",]
|
|
69
|
-
ignore = []
|
|
70
|
-
|
|
71
|
-
[tool.ruff.pydocstyle]
|
|
72
|
-
convention = "google"
|
|
68
|
+
select = [ "E", "F", "W", "I", "COM", "N", "D", "UP", "ANN", "B",]
|
|
69
|
+
ignore = [ "ANN",]
|
|
73
70
|
|
|
74
71
|
[tool.lintro.post_checks]
|
|
75
72
|
enabled = true
|
|
@@ -81,3 +78,6 @@ testpaths = [ "tests",]
|
|
|
81
78
|
python_files = "test_*.py"
|
|
82
79
|
python_classes = "Test*"
|
|
83
80
|
python_functions = "test_*"
|
|
81
|
+
|
|
82
|
+
[tool.ruff.lint.pydocstyle]
|
|
83
|
+
convention = "google"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Sample file with flake8-annotations (ANN) violations for testing Ruff.
|
|
2
|
+
|
|
3
|
+
Intentionally violates several ANN-rules, such as:
|
|
4
|
+
- ANN101: missing type annotation for self
|
|
5
|
+
- ANN102: missing type annotation for cls
|
|
6
|
+
- ANN201: missing return type annotation for public function
|
|
7
|
+
- ANN204: missing return type annotation for special method
|
|
8
|
+
- ANN205: missing return type annotation for static method
|
|
9
|
+
- ANN003: missing type annotation for **kwargs
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SampleClass:
|
|
16
|
+
"""Sample class with annotation violations."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, value: int): # ANN101: missing type for self
|
|
19
|
+
self.value = value
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_string(cls, s: str): # ANN102: missing type for cls
|
|
23
|
+
return cls(int(s))
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def helper_func(x: int): # ANN205: missing return type
|
|
27
|
+
return x * 2
|
|
28
|
+
|
|
29
|
+
def __str__(self): # ANN204: missing return type for special method
|
|
30
|
+
return f"SampleClass({self.value})"
|
|
31
|
+
|
|
32
|
+
def public_method(self, data: list[str]): # ANN201: missing return type
|
|
33
|
+
return len(data)
|
|
34
|
+
|
|
35
|
+
def kwargs_method(self, **kwargs): # ANN003: missing type for **kwargs
|
|
36
|
+
return kwargs
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def public_function(a: int, b: str): # ANN201: missing return type
|
|
40
|
+
"""Public function without return type annotation."""
|
|
41
|
+
return f"{a}: {b}"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def kwargs_function(**kwargs): # ANN003: missing type for **kwargs
|
|
45
|
+
"""Function with kwargs without type annotation."""
|
|
46
|
+
return kwargs
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def nested_function():
|
|
50
|
+
"""Function that returns a nested function."""
|
|
51
|
+
def inner(x: int): # ANN201: missing return type
|
|
52
|
+
return x + 1
|
|
53
|
+
return inner
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""Test file with flake8-bugbear (B) rule violations for testing Ruff integration."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def mutable_default_argument(
|
|
8
|
+
items: list = None,
|
|
9
|
+
): # B006: Do not use mutable data structures for argument defaults
|
|
10
|
+
"""Function with mutable default argument."""
|
|
11
|
+
if items is None:
|
|
12
|
+
items = []
|
|
13
|
+
items.append("test")
|
|
14
|
+
return items
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def dictionary_comprehension_with_unused_loop_variable():
|
|
18
|
+
"""Dictionary comprehension with unused loop variable."""
|
|
19
|
+
data = {"a": 1, "b": 2, "c": 3}
|
|
20
|
+
# B007: Loop control variable not used within loop body
|
|
21
|
+
return {k: v for k, v in data.items() if v > 1}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def assert_without_message():
|
|
25
|
+
"""Function using assert without message."""
|
|
26
|
+
x = 5
|
|
27
|
+
# B011: Do not use assert False since Python -O removes these calls
|
|
28
|
+
raise AssertionError("This should not happen")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def exception_handling_without_exception():
|
|
32
|
+
"""Function with bare except clause."""
|
|
33
|
+
try:
|
|
34
|
+
risky_operation()
|
|
35
|
+
except: # B001: Do not use bare except
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def unused_variable_in_comprehension():
|
|
40
|
+
"""List comprehension with unused variable."""
|
|
41
|
+
numbers = [1, 2, 3, 4, 5]
|
|
42
|
+
# B023: Function definition does not bind loop variable
|
|
43
|
+
return [x for x in numbers if x > 2]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def risky_operation():
|
|
47
|
+
"""Placeholder for risky operation."""
|
|
48
|
+
raise ValueError("Simulated error")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
"""Main function to demonstrate flake8-bugbear violations."""
|
|
53
|
+
|
|
54
|
+
# B008: Do not perform function calls in argument defaults
|
|
55
|
+
def delayed_call(value=os.getcwd()):
|
|
56
|
+
return value
|
|
57
|
+
|
|
58
|
+
# B009: Do not call getattr with a constant attribute name
|
|
59
|
+
obj = {"attr": "value"}
|
|
60
|
+
result = getattr(obj, "attr", None)
|
|
61
|
+
|
|
62
|
+
# B010: Do not call setattr with a constant attribute name
|
|
63
|
+
obj.new_attr = "new_value"
|
|
64
|
+
|
|
65
|
+
# B012: Do not use break/continue/return inside finally
|
|
66
|
+
try:
|
|
67
|
+
return "success"
|
|
68
|
+
finally:
|
|
69
|
+
# This would trigger B012 if we had break/continue/return here
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# B013: A length-one tuple literal is redundant
|
|
73
|
+
single_item = (1,) # Should be just 1
|
|
74
|
+
|
|
75
|
+
# B014: Convert namedtuple to dataclass
|
|
76
|
+
from collections import namedtuple
|
|
77
|
+
|
|
78
|
+
Point = namedtuple("Point", ["x", "y"]) # B014
|
|
79
|
+
|
|
80
|
+
# B015: Do not use assert in a loop
|
|
81
|
+
for i in range(3):
|
|
82
|
+
assert i >= 0 # B015
|
|
83
|
+
|
|
84
|
+
# B016: Cannot raise a non-exception class
|
|
85
|
+
# This would be: raise "string" # B016
|
|
86
|
+
|
|
87
|
+
# B017: assertRaises(Exception) should be considered more specific
|
|
88
|
+
# This is more relevant in test code
|
|
89
|
+
|
|
90
|
+
# B018: Found useless expression
|
|
91
|
+
# This would be: 1 + 1 # B018 (useless expression)
|
|
92
|
+
|
|
93
|
+
# B019: Use functools.lru_cache instead of functools.cache
|
|
94
|
+
import functools
|
|
95
|
+
|
|
96
|
+
@functools.cache # B019
|
|
97
|
+
def cached_function(x):
|
|
98
|
+
return x * 2
|
|
99
|
+
|
|
100
|
+
# B020: Loop variable overrides iterable it iterates
|
|
101
|
+
items = [1, 2, 3]
|
|
102
|
+
for items in items: # B020
|
|
103
|
+
print(items)
|
|
104
|
+
|
|
105
|
+
# B021: f-string used as docstring
|
|
106
|
+
def f_string_docstring():
|
|
107
|
+
f"""This is an f-string docstring.""" # B021
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
# B022: No arguments passed to contextlib.suppress
|
|
111
|
+
import contextlib
|
|
112
|
+
|
|
113
|
+
with contextlib.suppress(): # B022
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
# B024: BaseException is too broad, prefer Exception
|
|
117
|
+
try:
|
|
118
|
+
risky_operation()
|
|
119
|
+
except BaseException: # B024
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
# B025: Missing required keyword-only arguments
|
|
123
|
+
def required_kwargs(*, required_arg):
|
|
124
|
+
return required_arg
|
|
125
|
+
|
|
126
|
+
# B026: Star-arg unpacking after a keyword argument
|
|
127
|
+
def star_arg_after_kwarg(**kwargs):
|
|
128
|
+
return kwargs
|
|
129
|
+
|
|
130
|
+
# B027: Empty method in an abstract base class
|
|
131
|
+
from abc import ABC, abstractmethod
|
|
132
|
+
|
|
133
|
+
class AbstractClass(ABC):
|
|
134
|
+
@abstractmethod
|
|
135
|
+
def empty_method(self): # B027
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
# B028: No explicit stacklevel in warnings.warn
|
|
139
|
+
import warnings
|
|
140
|
+
|
|
141
|
+
warnings.warn("This is a warning", stacklevel=2) # B028
|
|
142
|
+
|
|
143
|
+
# B029: Except handler does not have access to the exception
|
|
144
|
+
try:
|
|
145
|
+
risky_operation()
|
|
146
|
+
except ValueError:
|
|
147
|
+
# B029: This would trigger if we didn't bind the exception
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
# B030: Except handler does not have access to the exception
|
|
151
|
+
try:
|
|
152
|
+
risky_operation()
|
|
153
|
+
except ValueError as e:
|
|
154
|
+
# This is correct - we bind the exception
|
|
155
|
+
print(f"Error: {e}")
|
|
156
|
+
|
|
157
|
+
# B031: Except handler does not have access to the exception
|
|
158
|
+
try:
|
|
159
|
+
risky_operation()
|
|
160
|
+
except ValueError:
|
|
161
|
+
# B031: This would trigger if we didn't bind the exception
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
# B032: Possible hardcoded password
|
|
165
|
+
password = "secret123" # B032
|
|
166
|
+
|
|
167
|
+
# B033: Do not use assert in a loop
|
|
168
|
+
for i in range(3):
|
|
169
|
+
assert i >= 0 # B033
|
|
170
|
+
|
|
171
|
+
# B034: Do not use assert in a loop
|
|
172
|
+
for i in range(3):
|
|
173
|
+
assert i >= 0 # B034
|
|
174
|
+
|
|
175
|
+
# B035: Do not use assert in a loop
|
|
176
|
+
for i in range(3):
|
|
177
|
+
assert i >= 0 # B035
|
|
178
|
+
|
|
179
|
+
# B036: Do not use assert in a loop
|
|
180
|
+
for i in range(3):
|
|
181
|
+
assert i >= 0 # B036
|
|
182
|
+
|
|
183
|
+
# B037: Do not use assert in a loop
|
|
184
|
+
for i in range(3):
|
|
185
|
+
assert i >= 0 # B037
|
|
186
|
+
|
|
187
|
+
# B038: Do not use assert in a loop
|
|
188
|
+
for i in range(3):
|
|
189
|
+
assert i >= 0 # B038
|
|
190
|
+
|
|
191
|
+
# B039: Do not use assert in a loop
|
|
192
|
+
for i in range(3):
|
|
193
|
+
assert i >= 0 # B039
|
|
194
|
+
|
|
195
|
+
# B040: Do not use assert in a loop
|
|
196
|
+
for i in range(3):
|
|
197
|
+
assert i >= 0 # B040
|
|
198
|
+
|
|
199
|
+
# B041: Do not use assert in a loop
|
|
200
|
+
for i in range(3):
|
|
201
|
+
assert i >= 0 # B041
|
|
202
|
+
|
|
203
|
+
# B042: Do not use assert in a loop
|
|
204
|
+
for i in range(3):
|
|
205
|
+
assert i >= 0 # B042
|
|
206
|
+
|
|
207
|
+
# B043: Do not use assert in a loop
|
|
208
|
+
for i in range(3):
|
|
209
|
+
assert i >= 0 # B043
|
|
210
|
+
|
|
211
|
+
# B044: Do not use assert in a loop
|
|
212
|
+
for i in range(3):
|
|
213
|
+
assert i >= 0 # B044
|
|
214
|
+
|
|
215
|
+
# B045: Do not use assert in a loop
|
|
216
|
+
for i in range(3):
|
|
217
|
+
assert i >= 0 # B045
|
|
218
|
+
|
|
219
|
+
# B046: Do not use assert in a loop
|
|
220
|
+
for i in range(3):
|
|
221
|
+
assert i >= 0 # B046
|
|
222
|
+
|
|
223
|
+
# B047: Do not use assert in a loop
|
|
224
|
+
for i in range(3):
|
|
225
|
+
assert i >= 0 # B047
|
|
226
|
+
|
|
227
|
+
# B048: Do not use assert in a loop
|
|
228
|
+
for i in range(3):
|
|
229
|
+
assert i >= 0 # B048
|
|
230
|
+
|
|
231
|
+
# B049: Do not use assert in a loop
|
|
232
|
+
for i in range(3):
|
|
233
|
+
assert i >= 0 # B049
|
|
234
|
+
|
|
235
|
+
# B050: Do not use assert in a loop
|
|
236
|
+
for i in range(3):
|
|
237
|
+
assert i >= 0 # B050
|
|
238
|
+
|
|
239
|
+
return "Completed flake8-bugbear violations demonstration"
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
if __name__ == "__main__":
|
|
243
|
+
main()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Sample file with pep8-naming (N) violations for testing Ruff.
|
|
2
|
+
|
|
3
|
+
Intentionally violates several N-rules, such as:
|
|
4
|
+
- N802: function name should be lowercase
|
|
5
|
+
- N803: argument name should be lowercase
|
|
6
|
+
- N806: variable in function should be lowercase
|
|
7
|
+
- N815: mixedCase variable in class scope
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def BadFunctionName(BadArg: int) -> int: # N802, N803
|
|
12
|
+
BadLocal = BadArg + 1 # N806
|
|
13
|
+
return BadLocal
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SampleClass:
|
|
17
|
+
camelCaseAttr = 1 # N815
|
|
18
|
+
|
|
19
|
+
def GoodMethod(self, BadParam: int) -> int: # N803
|
|
20
|
+
BadLocalVar = BadParam * 2 # N806
|
|
21
|
+
return BadLocalVar
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
CONSTANT_ok = 1 # not enforcing caps here; focus on N8xx basics
|
|
25
|
+
|
|
26
|
+
|
|
@@ -9,7 +9,7 @@ from assertpy import assert_that
|
|
|
9
9
|
from lintro.cli import cli
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
def test_cli_help():
|
|
12
|
+
def test_cli_help() -> None:
|
|
13
13
|
"""Test that CLI shows help."""
|
|
14
14
|
from click.testing import CliRunner
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ def test_cli_help():
|
|
|
19
19
|
assert_that(result.output).contains("Lintro")
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def test_cli_version():
|
|
22
|
+
def test_cli_version() -> None:
|
|
23
23
|
"""Test that CLI shows version."""
|
|
24
24
|
from click.testing import CliRunner
|
|
25
25
|
|
|
@@ -29,7 +29,7 @@ def test_cli_version():
|
|
|
29
29
|
assert_that(result.output.lower()).contains("version")
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
def test_cli_commands_registered():
|
|
32
|
+
def test_cli_commands_registered() -> None:
|
|
33
33
|
"""Test that all commands are registered."""
|
|
34
34
|
from click.testing import CliRunner
|
|
35
35
|
|
|
@@ -42,7 +42,7 @@ def test_cli_commands_registered():
|
|
|
42
42
|
assert_that(result.exit_code).is_equal_to(0)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def test_main_function():
|
|
45
|
+
def test_main_function() -> None:
|
|
46
46
|
"""Test the main function."""
|
|
47
47
|
from click.testing import CliRunner
|
|
48
48
|
|
|
@@ -52,7 +52,7 @@ def test_main_function():
|
|
|
52
52
|
assert_that(result.output).contains("Lintro")
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
def test_cli_command_aliases():
|
|
55
|
+
def test_cli_command_aliases() -> None:
|
|
56
56
|
"""Test that command aliases work."""
|
|
57
57
|
from click.testing import CliRunner
|
|
58
58
|
|
|
@@ -65,7 +65,7 @@ def test_cli_command_aliases():
|
|
|
65
65
|
assert_that(result.exit_code).is_equal_to(0)
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
def test_cli_with_no_args():
|
|
68
|
+
def test_cli_with_no_args() -> None:
|
|
69
69
|
"""Test CLI with no arguments."""
|
|
70
70
|
from click.testing import CliRunner
|
|
71
71
|
|
|
@@ -75,7 +75,7 @@ def test_cli_with_no_args():
|
|
|
75
75
|
assert_that(result.output).is_equal_to("")
|
|
76
76
|
|
|
77
77
|
|
|
78
|
-
def test_main_module_execution():
|
|
78
|
+
def test_main_module_execution() -> None:
|
|
79
79
|
"""Test that __main__.py can be executed directly."""
|
|
80
80
|
with patch.object(sys, "argv", ["lintro", "--help"]):
|
|
81
81
|
import lintro.__main__
|
|
@@ -83,7 +83,7 @@ def test_main_module_execution():
|
|
|
83
83
|
assert_that(lintro.__main__).is_not_none()
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
def test_main_module_as_script():
|
|
86
|
+
def test_main_module_as_script() -> None:
|
|
87
87
|
"""Test that __main__.py works when run as a script."""
|
|
88
88
|
result = subprocess.run(
|
|
89
89
|
[sys.executable, "-m", "lintro", "--help"],
|
|
@@ -32,7 +32,7 @@ def _ensure_test_docker_images_built() -> None:
|
|
|
32
32
|
return
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def pytest_collection_modifyitems(config, items):
|
|
35
|
+
def pytest_collection_modifyitems(config, items) -> None:
|
|
36
36
|
"""Optionally skip docker tests locally unless explicitly enabled.
|
|
37
37
|
|
|
38
38
|
If `LINTRO_RUN_DOCKER_TESTS` is not set to "1", mark tests under
|