lintro 0.6.2__tar.gz → 0.7.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.2/lintro.egg-info → lintro-0.7.0}/PKG-INFO +46 -8
- {lintro-0.6.2 → lintro-0.7.0}/README.md +39 -1
- {lintro-0.6.2 → lintro-0.7.0}/assets/images/coverage-badge.svg +3 -3
- {lintro-0.6.2 → lintro-0.7.0}/docs/README.md +5 -4
- {lintro-0.6.2 → lintro-0.7.0}/docs/contributing.md +13 -0
- lintro-0.7.0/docs/security/assurance.md +79 -0
- lintro-0.7.0/docs/security/requirements.md +42 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/__init__.py +1 -1
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_prettier.py +7 -1
- {lintro-0.6.2 → lintro-0.7.0/lintro.egg-info}/PKG-INFO +46 -8
- {lintro-0.6.2 → lintro-0.7.0}/lintro.egg-info/SOURCES.txt +4 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro.egg-info/requires.txt +6 -6
- {lintro-0.6.2 → lintro-0.7.0}/pyproject.toml +4 -4
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_prettier_integration.py +32 -0
- lintro-0.7.0/tests/scripts/test_ci_post_pr_comment.py +336 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/scripts/test_ghcr_prune_untagged.py +2 -2
- lintro-0.7.0/tests/scripts/test_github_comment_utilities.py +435 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/scripts/test_script_environment.py +263 -1
- {lintro-0.6.2 → lintro-0.7.0}/tests/scripts/test_shell_scripts.py +76 -2
- {lintro-0.6.2 → lintro-0.7.0}/tests/test_documentation.py +1 -1
- {lintro-0.6.2 → lintro-0.7.0}/LICENSE +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/MANIFEST.in +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/assets/images/lintro.png +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/configuration.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/coverage-setup.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/docker.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/getting-started.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/github-integration.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/lintro-self-use.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/style-guide.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/README.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/actionlint-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/bandit-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/black-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/darglint-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/hadolint-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/prettier-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/ruff-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/docs/tool-analysis/yamllint-analysis.md +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/__main__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/ascii-art/fail.txt +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/ascii-art/success.txt +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/cli.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/cli_utils/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/cli_utils/commands/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/cli_utils/commands/check.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/cli_utils/commands/format.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/cli_utils/commands/list_tools.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/action.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/darglint_strictness.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/group_by.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/hadolint_enums.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/output_format.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/tool_name.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/tool_type.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/enums/yamllint_format.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/exceptions/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/exceptions/errors.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/core/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/core/output_style.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/core/table_descriptor.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/styles/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/styles/csv.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/styles/grid.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/styles/html.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/styles/json.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/styles/markdown.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/styles/plain.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/actionlint_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/bandit_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/black_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/darglint_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/hadolint_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/prettier_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/ruff_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/formatters/tools/yamllint_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/models/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/models/core/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/models/core/tool.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/models/core/tool_config.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/models/core/tool_result.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/actionlint/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/black/black_issue.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/black/black_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/darglint/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/darglint/darglint_issue.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/darglint/darglint_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/hadolint/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/prettier/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/prettier/prettier_issue.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/prettier/prettier_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/ruff/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/ruff/ruff_issue.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/ruff/ruff_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/yamllint/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/core/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/core/tool_base.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/core/tool_manager.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_actionlint.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_bandit.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_black.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_darglint.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_hadolint.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_ruff.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/implementations/tool_yamllint.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/tools/tool_enum.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/ascii_normalize_cli.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/config.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/console_logger.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/formatting.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/output_manager.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/path_utils.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/tool_executor.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro/utils/tool_utils.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro.egg-info/dependency_links.txt +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro.egg-info/entry_points.txt +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/lintro.egg-info/top_level.txt +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/setup.cfg +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/Dockerfile.violations +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/actionlint_violations.yml +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/bandit_violations.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/darglint_violations.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/prettier_violations.js +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/ruff_black_e501_wrappable.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/ruff_clean.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/ruff_violations.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/test_samples/yaml_violations.yml +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/cli/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/cli/conftest.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/cli/test_cli.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/conftest.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/formatters/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/formatters/conftest.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/formatters/test_formatters.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/conftest.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_actionlint_integration.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_bandit_integration.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_darglint_integration.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_hadolint_integration.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_ruff_black_policy.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_ruff_integration.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/integration/test_yamllint_integration.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/scripts/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/scripts/test_delete_previous_lintro_comments.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/scripts/test_extract_version.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/scripts/test_semantic_release_compute_next.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_ascii_normalize.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_bandit_command_building.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_bandit_config_hydration.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_bandit_formatter_mapping.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_bandit_parsing.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_black_formatter.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_black_parser.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_black_tool.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_black_tool_more.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_cli_commands.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_cli_commands_more.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_cli_programmatic.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_compatibility_ruff_black.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_config_loader.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_config_loader_more.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_console_logger.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_console_logger_more.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_enums_and_normalizers.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_exceptions.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_formatters_tables.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_output_manager_reports.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_parsers_actionlint.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_ruff_parser_additional.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_ruff_parser_more.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_executor.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_executor_fmt_exclusion.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_executor_more.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_executor_post_checks.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_manager.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_utils.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_utils_fallbacks.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/unit/test_tool_utils_more.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/utils/__init__.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/utils/conftest.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/utils/test_formatting.py +0 -0
- {lintro-0.6.2 → lintro-0.7.0}/tests/utils/test_output_manager.py +0 -0
- {lintro-0.6.2 → lintro-0.7.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.7.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,10 +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)
|
|
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)
|
|
95
97
|
|
|
96
98
|
### Why Lintro?
|
|
97
99
|
|
|
@@ -112,6 +114,42 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
112
114
|
- **Docker support** for containerized environments
|
|
113
115
|
- **CI/CD integration** with GitHub Actions
|
|
114
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
|
+
|
|
115
153
|
## Supported Tools
|
|
116
154
|
|
|
117
155
|
| Tool | Language | Auto-fix |
|
|
@@ -14,10 +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)
|
|
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)
|
|
21
23
|
|
|
22
24
|
### Why Lintro?
|
|
23
25
|
|
|
@@ -38,6 +40,42 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
38
40
|
- **Docker support** for containerized environments
|
|
39
41
|
- **CI/CD integration** with GitHub Actions
|
|
40
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
|
+
|
|
41
79
|
## Supported Tools
|
|
42
80
|
|
|
43
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="#e05d44" 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">
|
|
19
|
-
<text x="800" y="140" transform="scale(.1)" textLength="260">
|
|
18
|
+
<text x="800" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="260">83.6%</text>
|
|
19
|
+
<text x="800" y="140" transform="scale(.1)" textLength="260">83.6%</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
|
|
|
@@ -53,6 +53,19 @@ Notes:
|
|
|
53
53
|
- If work is ambiguous (e.g., a large refactor), explicitly signal with `!` or a `BREAKING CHANGE:` footer.
|
|
54
54
|
- The PR title validator (`.github/workflows/semantic-pr-title.yml`) enforces the format before merge.
|
|
55
55
|
|
|
56
|
+
## Developer Certificate of Origin (required)
|
|
57
|
+
|
|
58
|
+
All contributions must be signed off under the Developer Certificate of
|
|
59
|
+
Origin (DCO). Use `git commit -s` (or `--signoff`) so your commit message
|
|
60
|
+
contains a line like:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Signed-off-by: Your Name <your.email@example.com>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
See `DCO.md` for details. Pull requests without DCO sign-offs will be asked
|
|
67
|
+
to amend commits before merge.
|
|
68
|
+
|
|
56
69
|
## Quick Start
|
|
57
70
|
|
|
58
71
|
1. Clone the repository:
|
|
@@ -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
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Security Requirements
|
|
2
|
+
|
|
3
|
+
This document summarizes security requirements adopted by `py-lintro` to support OpenSSF Best Practices (Silver).
|
|
4
|
+
|
|
5
|
+
## Project and Process
|
|
6
|
+
|
|
7
|
+
- FLOSS license (MIT) and public repository
|
|
8
|
+
- Governance documented in `GOVERNANCE.md`
|
|
9
|
+
- Responsible disclosure process in `SECURITY.md`
|
|
10
|
+
- DCO required for contributions (`DCO.md`), enforced via commit sign-offs
|
|
11
|
+
|
|
12
|
+
## Source Integrity and Branch Protection
|
|
13
|
+
|
|
14
|
+
- All changes land via PR with maintainer review
|
|
15
|
+
- Branch protection enforced on `main` (no force pushes; required reviews; admins included)
|
|
16
|
+
|
|
17
|
+
## Dependencies and Supply Chain
|
|
18
|
+
|
|
19
|
+
- Dependencies managed via `pyproject.toml` and `uv.lock`
|
|
20
|
+
- Automated dependency updates (Renovate) with CI validation
|
|
21
|
+
- Dependency Review workflow enabled in CI
|
|
22
|
+
|
|
23
|
+
## Static and Policy Analysis
|
|
24
|
+
|
|
25
|
+
- Linting/formatting: Ruff, Black, Prettier, Yamllint, Hadolint, Actionlint
|
|
26
|
+
- Security linting: Bandit; GitHub CodeQL configured
|
|
27
|
+
- OpenSSF Scorecard monitored
|
|
28
|
+
|
|
29
|
+
## Build and Release
|
|
30
|
+
|
|
31
|
+
- CI builds, tests, and coverage for PRs and `main`
|
|
32
|
+
- Semantic versioning; signed release artifacts published via CI using OIDC
|
|
33
|
+
|
|
34
|
+
## Testing and Coverage
|
|
35
|
+
|
|
36
|
+
- Automated test suite with ~84% statement coverage
|
|
37
|
+
- New code requires tests and coverage reporting
|
|
38
|
+
|
|
39
|
+
## Secure Defaults
|
|
40
|
+
|
|
41
|
+
- No execution of untrusted code
|
|
42
|
+
- Docker image and scripts follow hardening practices (pinned actions, validated inputs)
|
|
@@ -142,11 +142,14 @@ class PrettierTool(BaseTool):
|
|
|
142
142
|
# so the unified logger prints a single, consistent success line.
|
|
143
143
|
if success:
|
|
144
144
|
output = None
|
|
145
|
-
|
|
145
|
+
|
|
146
|
+
# Return full ToolResult so table rendering can use parsed issues
|
|
147
|
+
return ToolResult(
|
|
146
148
|
name=self.name,
|
|
147
149
|
success=success,
|
|
148
150
|
output=output,
|
|
149
151
|
issues_count=issues_count,
|
|
152
|
+
issues=issues,
|
|
150
153
|
)
|
|
151
154
|
|
|
152
155
|
def fix(
|
|
@@ -264,6 +267,9 @@ class PrettierTool(BaseTool):
|
|
|
264
267
|
output=final_output,
|
|
265
268
|
# For fix operations, issues_count represents remaining for summaries
|
|
266
269
|
issues_count=remaining_count,
|
|
270
|
+
# Provide issues so formatters can render tables. Use initial issues
|
|
271
|
+
# (auto-fixable set) for display; fall back to remaining when none.
|
|
272
|
+
issues=(initial_issues if initial_issues else remaining_issues),
|
|
267
273
|
initial_issues_count=initial_count,
|
|
268
274
|
fixed_issues_count=fixed_count,
|
|
269
275
|
remaining_issues_count=remaining_count,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lintro
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.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,10 +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)
|
|
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)
|
|
95
97
|
|
|
96
98
|
### Why Lintro?
|
|
97
99
|
|
|
@@ -112,6 +114,42 @@ Lintro is a unified command-line interface that brings together multiple code qu
|
|
|
112
114
|
- **Docker support** for containerized environments
|
|
113
115
|
- **CI/CD integration** with GitHub Actions
|
|
114
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
|
+
|
|
115
153
|
## Supported Tools
|
|
116
154
|
|
|
117
155
|
| Tool | Language | Auto-fix |
|
|
@@ -13,6 +13,8 @@ docs/getting-started.md
|
|
|
13
13
|
docs/github-integration.md
|
|
14
14
|
docs/lintro-self-use.md
|
|
15
15
|
docs/style-guide.md
|
|
16
|
+
docs/security/assurance.md
|
|
17
|
+
docs/security/requirements.md
|
|
16
18
|
docs/tool-analysis/README.md
|
|
17
19
|
docs/tool-analysis/actionlint-analysis.md
|
|
18
20
|
docs/tool-analysis/bandit-analysis.md
|
|
@@ -147,9 +149,11 @@ tests/integration/test_ruff_black_policy.py
|
|
|
147
149
|
tests/integration/test_ruff_integration.py
|
|
148
150
|
tests/integration/test_yamllint_integration.py
|
|
149
151
|
tests/scripts/__init__.py
|
|
152
|
+
tests/scripts/test_ci_post_pr_comment.py
|
|
150
153
|
tests/scripts/test_delete_previous_lintro_comments.py
|
|
151
154
|
tests/scripts/test_extract_version.py
|
|
152
155
|
tests/scripts/test_ghcr_prune_untagged.py
|
|
156
|
+
tests/scripts/test_github_comment_utilities.py
|
|
153
157
|
tests/scripts/test_script_environment.py
|
|
154
158
|
tests/scripts/test_semantic_release_compute_next.py
|
|
155
159
|
tests/scripts/test_shell_scripts.py
|
|
@@ -10,22 +10,22 @@ defusedxml==0.7.1
|
|
|
10
10
|
|
|
11
11
|
[dev]
|
|
12
12
|
pytest==8.4.2
|
|
13
|
-
pytest-cov==
|
|
14
|
-
pytest-mock==3.15.
|
|
13
|
+
pytest-cov==7.0.0
|
|
14
|
+
pytest-mock==3.15.1
|
|
15
15
|
pytest-xdist==3.8.0
|
|
16
|
-
tox==4.30.
|
|
16
|
+
tox==4.30.3
|
|
17
17
|
allure-pytest==2.15.0
|
|
18
18
|
ruff
|
|
19
19
|
mypy
|
|
20
20
|
coverage-badge==1.1.2
|
|
21
|
-
python-semantic-release==10.
|
|
21
|
+
python-semantic-release==10.4.1
|
|
22
22
|
assertpy==1.1
|
|
23
23
|
httpx==0.28.1
|
|
24
24
|
|
|
25
25
|
[test]
|
|
26
26
|
pytest==8.4.2
|
|
27
|
-
pytest-cov==
|
|
28
|
-
pytest-mock==3.15.
|
|
27
|
+
pytest-cov==7.0.0
|
|
28
|
+
pytest-mock==3.15.1
|
|
29
29
|
pytest-xdist==3.8.0
|
|
30
30
|
assertpy==1.1
|
|
31
31
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "lintro"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.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",]
|
|
@@ -15,7 +15,7 @@ name = "TurboCoder13"
|
|
|
15
15
|
email = "turbocoder13@gmail.com"
|
|
16
16
|
|
|
17
17
|
[dependency-groups]
|
|
18
|
-
dev = [ "build==1.3.0", "pytest==8.4.2", "pytest-cov==
|
|
18
|
+
dev = [ "build==1.3.0", "pytest==8.4.2", "pytest-cov==7.0.0", "pytest-xdist==3.8.0", "twine==6.2.0", "assertpy==1.1",]
|
|
19
19
|
|
|
20
20
|
[project.license]
|
|
21
21
|
file = "LICENSE"
|
|
@@ -25,8 +25,8 @@ file = "README.md"
|
|
|
25
25
|
content-type = "text/markdown"
|
|
26
26
|
|
|
27
27
|
[project.optional-dependencies]
|
|
28
|
-
dev = [ "pytest==8.4.2", "pytest-cov==
|
|
29
|
-
test = [ "pytest==8.4.2", "pytest-cov==
|
|
28
|
+
dev = [ "pytest==8.4.2", "pytest-cov==7.0.0", "pytest-mock==3.15.1", "pytest-xdist==3.8.0", "tox==4.30.3", "allure-pytest==2.15.0", "ruff", "mypy", "coverage-badge==1.1.2", "python-semantic-release==10.4.1", "assertpy==1.1", "httpx==0.28.1",]
|
|
29
|
+
test = [ "pytest==8.4.2", "pytest-cov==7.0.0", "pytest-mock==3.15.1", "pytest-xdist==3.8.0", "assertpy==1.1",]
|
|
30
30
|
typing = [ "types-setuptools==80.9.0.20250822", "types-tabulate==0.9.0.20241207",]
|
|
31
31
|
|
|
32
32
|
[project.scripts]
|
|
@@ -8,6 +8,7 @@ from loguru import logger
|
|
|
8
8
|
|
|
9
9
|
from lintro.parsers.prettier.prettier_parser import parse_prettier_output
|
|
10
10
|
from lintro.tools.implementations.tool_prettier import PrettierTool
|
|
11
|
+
from lintro.utils.tool_utils import format_tool_output
|
|
11
12
|
|
|
12
13
|
logger.remove()
|
|
13
14
|
logger.add(lambda msg: print(msg, end=""), level="INFO")
|
|
@@ -167,3 +168,34 @@ def test_prettier_output_consistency_direct_vs_lintro(temp_prettier_file):
|
|
|
167
168
|
f"Issue count mismatch: CLI={direct_issues}, Lintro={result.issues_count}\n"
|
|
168
169
|
f"CLI Output:\n{direct_output}\nLintro Output:\n{result.output}"
|
|
169
170
|
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def test_prettier_fix_sets_issues_for_table(temp_prettier_file):
|
|
174
|
+
"""PrettierTool.fix should populate issues for table rendering.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
temp_prettier_file: Pytest fixture providing a temporary file with violations.
|
|
178
|
+
"""
|
|
179
|
+
tool = PrettierTool()
|
|
180
|
+
tool.set_options()
|
|
181
|
+
|
|
182
|
+
# Ensure there are initial issues
|
|
183
|
+
pre_result = tool.check([str(temp_prettier_file)])
|
|
184
|
+
assert pre_result.issues_count > 0
|
|
185
|
+
|
|
186
|
+
# Run fix and assert issues are provided for table formatting
|
|
187
|
+
fix_result = tool.fix([str(temp_prettier_file)])
|
|
188
|
+
assert fix_result.success is True
|
|
189
|
+
assert fix_result.remaining_issues_count == 0
|
|
190
|
+
assert fix_result.issues is not None
|
|
191
|
+
assert len(fix_result.issues) == pre_result.issues_count
|
|
192
|
+
|
|
193
|
+
# Verify that formatted output renders a table section for auto-fixables
|
|
194
|
+
formatted = format_tool_output(
|
|
195
|
+
tool_name="prettier",
|
|
196
|
+
output=fix_result.output or "",
|
|
197
|
+
group_by="auto",
|
|
198
|
+
output_format="grid",
|
|
199
|
+
issues=fix_result.issues,
|
|
200
|
+
)
|
|
201
|
+
assert "Auto-fixable issues" in formatted or formatted
|