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.

Files changed (217) hide show
  1. {lintro-0.6.3/lintro.egg-info → lintro-0.8.0}/PKG-INFO +46 -10
  2. {lintro-0.6.3 → lintro-0.8.0}/README.md +39 -3
  3. {lintro-0.6.3 → lintro-0.8.0}/assets/images/coverage-badge.svg +3 -3
  4. {lintro-0.6.3 → lintro-0.8.0}/docs/README.md +5 -4
  5. lintro-0.8.0/docs/security/assurance.md +79 -0
  6. {lintro-0.6.3 → lintro-0.8.0}/lintro/__init__.py +1 -1
  7. {lintro-0.6.3 → lintro-0.8.0}/lintro/cli.py +6 -0
  8. lintro-0.8.0/lintro/enums/__init__.py +1 -0
  9. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/darglint_strictness.py +10 -0
  10. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/hadolint_enums.py +22 -0
  11. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/yamllint_format.py +11 -0
  12. lintro-0.8.0/lintro/exceptions/__init__.py +1 -0
  13. lintro-0.8.0/lintro/formatters/__init__.py +1 -0
  14. lintro-0.8.0/lintro/formatters/core/__init__.py +1 -0
  15. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/core/output_style.py +11 -0
  16. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/core/table_descriptor.py +8 -0
  17. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/csv.py +2 -0
  18. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/grid.py +2 -0
  19. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/html.py +2 -0
  20. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/json.py +2 -0
  21. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/markdown.py +2 -0
  22. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/plain.py +2 -0
  23. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/black_formatter.py +27 -5
  24. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/darglint_formatter.py +16 -1
  25. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/hadolint_formatter.py +13 -0
  26. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/prettier_formatter.py +15 -0
  27. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/ruff_formatter.py +16 -1
  28. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/yamllint_formatter.py +14 -1
  29. lintro-0.8.0/lintro/models/__init__.py +1 -0
  30. lintro-0.8.0/lintro/models/core/__init__.py +1 -0
  31. lintro-0.8.0/lintro/models/core/tool_config.py +27 -0
  32. lintro-0.8.0/lintro/parsers/darglint/__init__.py +1 -0
  33. lintro-0.8.0/lintro/parsers/darglint/darglint_issue.py +20 -0
  34. lintro-0.8.0/lintro/parsers/prettier/__init__.py +1 -0
  35. lintro-0.8.0/lintro/parsers/prettier/prettier_issue.py +22 -0
  36. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/ruff/ruff_parser.py +6 -2
  37. lintro-0.8.0/lintro/parsers/yamllint/__init__.py +1 -0
  38. lintro-0.8.0/lintro/tools/core/__init__.py +1 -0
  39. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/core/tool_base.py +32 -6
  40. lintro-0.8.0/lintro/tools/implementations/__init__.py +1 -0
  41. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_bandit.py +11 -22
  42. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_darglint.py +3 -1
  43. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/tool_enum.py +2 -0
  44. lintro-0.8.0/lintro/utils/__init__.py +1 -0
  45. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/ascii_normalize_cli.py +5 -0
  46. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/tool_utils.py +6 -10
  47. {lintro-0.6.3 → lintro-0.8.0/lintro.egg-info}/PKG-INFO +46 -10
  48. {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/SOURCES.txt +4 -0
  49. {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/requires.txt +6 -6
  50. {lintro-0.6.3 → lintro-0.8.0}/pyproject.toml +8 -5
  51. {lintro-0.6.3 → lintro-0.8.0}/tests/conftest.py +2 -2
  52. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_darglint_integration.py +21 -0
  53. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_prettier_integration.py +8 -0
  54. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_ruff_black_policy.py +2 -0
  55. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_ruff_integration.py +1 -2
  56. lintro-0.8.0/tests/scripts/test_ci_post_pr_comment.py +336 -0
  57. {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_extract_version.py +21 -0
  58. {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_ghcr_prune_untagged.py +32 -2
  59. lintro-0.8.0/tests/scripts/test_github_comment_utilities.py +433 -0
  60. {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_script_environment.py +263 -1
  61. {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_semantic_release_compute_next.py +2 -0
  62. {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_shell_scripts.py +76 -2
  63. {lintro-0.6.3 → lintro-0.8.0}/tests/test_documentation.py +1 -1
  64. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_ascii_normalize.py +8 -0
  65. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_command_building.py +3 -0
  66. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_config_hydration.py +10 -1
  67. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_formatter.py +5 -0
  68. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_parser.py +5 -0
  69. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_tool.py +32 -1
  70. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_black_tool_more.py +7 -0
  71. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_cli_commands.py +3 -0
  72. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_cli_commands_more.py +17 -0
  73. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_cli_programmatic.py +17 -0
  74. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_compatibility_ruff_black.py +79 -0
  75. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_config_loader.py +8 -0
  76. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_config_loader_more.py +6 -0
  77. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_console_logger.py +14 -0
  78. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_console_logger_more.py +7 -0
  79. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_enums_and_normalizers.py +6 -0
  80. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_exceptions.py +3 -0
  81. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_formatters_tables.py +22 -0
  82. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_output_manager_reports.py +27 -0
  83. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_parsers_actionlint.py +2 -0
  84. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_ruff_parser_additional.py +2 -0
  85. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_ruff_parser_more.py +7 -1
  86. lintro-0.8.0/tests/unit/test_subprocess_validator.py +78 -0
  87. lintro-0.8.0/tests/unit/test_tool_base_subprocess.py +93 -0
  88. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor.py +146 -0
  89. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor_fmt_exclusion.py +1 -1
  90. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor_post_checks.py +42 -0
  91. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_manager.py +9 -0
  92. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_utils.py +14 -0
  93. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_utils_fallbacks.py +2 -0
  94. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_utils_more.py +12 -0
  95. {lintro-0.6.3 → lintro-0.8.0}/tests/utils/test_output_manager.py +28 -0
  96. lintro-0.6.3/docs/security/assurance.md +0 -27
  97. lintro-0.6.3/lintro/enums/__init__.py +0 -0
  98. lintro-0.6.3/lintro/exceptions/__init__.py +0 -0
  99. lintro-0.6.3/lintro/formatters/__init__.py +0 -0
  100. lintro-0.6.3/lintro/formatters/core/__init__.py +0 -0
  101. lintro-0.6.3/lintro/models/__init__.py +0 -0
  102. lintro-0.6.3/lintro/models/core/__init__.py +0 -0
  103. lintro-0.6.3/lintro/models/core/tool_config.py +0 -23
  104. lintro-0.6.3/lintro/parsers/darglint/__init__.py +0 -0
  105. lintro-0.6.3/lintro/parsers/darglint/darglint_issue.py +0 -9
  106. lintro-0.6.3/lintro/parsers/prettier/__init__.py +0 -0
  107. lintro-0.6.3/lintro/parsers/prettier/prettier_issue.py +0 -10
  108. lintro-0.6.3/lintro/parsers/yamllint/__init__.py +0 -0
  109. lintro-0.6.3/lintro/tools/core/__init__.py +0 -0
  110. lintro-0.6.3/lintro/tools/implementations/__init__.py +0 -0
  111. lintro-0.6.3/lintro/utils/__init__.py +0 -0
  112. {lintro-0.6.3 → lintro-0.8.0}/LICENSE +0 -0
  113. {lintro-0.6.3 → lintro-0.8.0}/MANIFEST.in +0 -0
  114. {lintro-0.6.3 → lintro-0.8.0}/assets/images/lintro.png +0 -0
  115. {lintro-0.6.3 → lintro-0.8.0}/docs/configuration.md +0 -0
  116. {lintro-0.6.3 → lintro-0.8.0}/docs/contributing.md +0 -0
  117. {lintro-0.6.3 → lintro-0.8.0}/docs/coverage-setup.md +0 -0
  118. {lintro-0.6.3 → lintro-0.8.0}/docs/docker.md +0 -0
  119. {lintro-0.6.3 → lintro-0.8.0}/docs/getting-started.md +0 -0
  120. {lintro-0.6.3 → lintro-0.8.0}/docs/github-integration.md +0 -0
  121. {lintro-0.6.3 → lintro-0.8.0}/docs/lintro-self-use.md +0 -0
  122. {lintro-0.6.3 → lintro-0.8.0}/docs/security/requirements.md +0 -0
  123. {lintro-0.6.3 → lintro-0.8.0}/docs/style-guide.md +0 -0
  124. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/README.md +0 -0
  125. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/actionlint-analysis.md +0 -0
  126. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/bandit-analysis.md +0 -0
  127. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/black-analysis.md +0 -0
  128. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/darglint-analysis.md +0 -0
  129. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/hadolint-analysis.md +0 -0
  130. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/prettier-analysis.md +0 -0
  131. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/ruff-analysis.md +0 -0
  132. {lintro-0.6.3 → lintro-0.8.0}/docs/tool-analysis/yamllint-analysis.md +0 -0
  133. {lintro-0.6.3 → lintro-0.8.0}/lintro/__main__.py +0 -0
  134. {lintro-0.6.3 → lintro-0.8.0}/lintro/ascii-art/fail.txt +0 -0
  135. {lintro-0.6.3 → lintro-0.8.0}/lintro/ascii-art/success.txt +0 -0
  136. {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/__init__.py +0 -0
  137. {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/__init__.py +0 -0
  138. {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/check.py +0 -0
  139. {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/format.py +0 -0
  140. {lintro-0.6.3 → lintro-0.8.0}/lintro/cli_utils/commands/list_tools.py +0 -0
  141. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/action.py +0 -0
  142. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/group_by.py +0 -0
  143. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/output_format.py +0 -0
  144. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/tool_name.py +0 -0
  145. {lintro-0.6.3 → lintro-0.8.0}/lintro/enums/tool_type.py +0 -0
  146. {lintro-0.6.3 → lintro-0.8.0}/lintro/exceptions/errors.py +0 -0
  147. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/styles/__init__.py +0 -0
  148. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/__init__.py +0 -0
  149. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/actionlint_formatter.py +0 -0
  150. {lintro-0.6.3 → lintro-0.8.0}/lintro/formatters/tools/bandit_formatter.py +0 -0
  151. {lintro-0.6.3 → lintro-0.8.0}/lintro/models/core/tool.py +0 -0
  152. {lintro-0.6.3 → lintro-0.8.0}/lintro/models/core/tool_result.py +0 -0
  153. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/__init__.py +0 -0
  154. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/actionlint/__init__.py +0 -0
  155. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
  156. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
  157. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/black/black_issue.py +0 -0
  158. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/black/black_parser.py +0 -0
  159. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/darglint/darglint_parser.py +0 -0
  160. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/hadolint/__init__.py +0 -0
  161. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
  162. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
  163. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/prettier/prettier_parser.py +0 -0
  164. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/ruff/__init__.py +0 -0
  165. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/ruff/ruff_issue.py +0 -0
  166. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
  167. {lintro-0.6.3 → lintro-0.8.0}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
  168. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/__init__.py +0 -0
  169. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/core/tool_manager.py +0 -0
  170. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_actionlint.py +0 -0
  171. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_black.py +0 -0
  172. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_hadolint.py +0 -0
  173. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_prettier.py +0 -0
  174. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_ruff.py +0 -0
  175. {lintro-0.6.3 → lintro-0.8.0}/lintro/tools/implementations/tool_yamllint.py +0 -0
  176. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/config.py +0 -0
  177. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/console_logger.py +0 -0
  178. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/formatting.py +0 -0
  179. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/output_manager.py +0 -0
  180. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/path_utils.py +0 -0
  181. {lintro-0.6.3 → lintro-0.8.0}/lintro/utils/tool_executor.py +0 -0
  182. {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/dependency_links.txt +0 -0
  183. {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/entry_points.txt +0 -0
  184. {lintro-0.6.3 → lintro-0.8.0}/lintro.egg-info/top_level.txt +0 -0
  185. {lintro-0.6.3 → lintro-0.8.0}/setup.cfg +0 -0
  186. {lintro-0.6.3 → lintro-0.8.0}/test_samples/Dockerfile.violations +0 -0
  187. {lintro-0.6.3 → lintro-0.8.0}/test_samples/actionlint_violations.yml +0 -0
  188. {lintro-0.6.3 → lintro-0.8.0}/test_samples/bandit_violations.py +0 -0
  189. {lintro-0.6.3 → lintro-0.8.0}/test_samples/darglint_violations.py +0 -0
  190. {lintro-0.6.3 → lintro-0.8.0}/test_samples/prettier_violations.js +0 -0
  191. {lintro-0.6.3 → lintro-0.8.0}/test_samples/ruff_black_e501_wrappable.py +0 -0
  192. {lintro-0.6.3 → lintro-0.8.0}/test_samples/ruff_clean.py +0 -0
  193. {lintro-0.6.3 → lintro-0.8.0}/test_samples/ruff_violations.py +0 -0
  194. {lintro-0.6.3 → lintro-0.8.0}/test_samples/yaml_violations.yml +0 -0
  195. {lintro-0.6.3 → lintro-0.8.0}/tests/__init__.py +0 -0
  196. {lintro-0.6.3 → lintro-0.8.0}/tests/cli/__init__.py +0 -0
  197. {lintro-0.6.3 → lintro-0.8.0}/tests/cli/conftest.py +0 -0
  198. {lintro-0.6.3 → lintro-0.8.0}/tests/cli/test_cli.py +0 -0
  199. {lintro-0.6.3 → lintro-0.8.0}/tests/formatters/__init__.py +0 -0
  200. {lintro-0.6.3 → lintro-0.8.0}/tests/formatters/conftest.py +0 -0
  201. {lintro-0.6.3 → lintro-0.8.0}/tests/formatters/test_formatters.py +0 -0
  202. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/__init__.py +0 -0
  203. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/conftest.py +0 -0
  204. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_actionlint_integration.py +0 -0
  205. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_bandit_integration.py +0 -0
  206. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_hadolint_integration.py +0 -0
  207. {lintro-0.6.3 → lintro-0.8.0}/tests/integration/test_yamllint_integration.py +0 -0
  208. {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/__init__.py +0 -0
  209. {lintro-0.6.3 → lintro-0.8.0}/tests/scripts/test_delete_previous_lintro_comments.py +0 -0
  210. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/__init__.py +0 -0
  211. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_formatter_mapping.py +0 -0
  212. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_bandit_parsing.py +0 -0
  213. {lintro-0.6.3 → lintro-0.8.0}/tests/unit/test_tool_executor_more.py +0 -0
  214. {lintro-0.6.3 → lintro-0.8.0}/tests/utils/__init__.py +0 -0
  215. {lintro-0.6.3 → lintro-0.8.0}/tests/utils/conftest.py +0 -0
  216. {lintro-0.6.3 → lintro-0.8.0}/tests/utils/test_formatting.py +0 -0
  217. {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.6.3
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==6.3.0; extra == "dev"
54
- Requires-Dist: pytest-mock==3.15.0; extra == "dev"
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.1; extra == "dev"
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.3.2; extra == "dev"
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==6.3.0; extra == "test"
67
- Requires-Dist: pytest-mock==3.15.0; extra == "test"
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
  [![Tests](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/test-and-coverage.yml?label=tests&branch=main&logo=githubactions&logoColor=white)](https://github.com/TurboCoder13/py-lintro/actions/workflows/test-and-coverage.yml?query=branch%3Amain)
89
89
  [![CI](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/ci-lintro-analysis.yml?label=ci&branch=main&logo=githubactions&logoColor=white)](https://github.com/TurboCoder13/py-lintro/actions/workflows/ci-lintro-analysis.yml?query=branch%3Amain)
90
90
  [![Docker](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/docker-build-publish.yml?label=docker&logo=docker&branch=main)](https://github.com/TurboCoder13/py-lintro/actions/workflows/docker-build-publish.yml?query=branch%3Amain)
91
+ [![SBOM (main)](<https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/sbom-on-main.yml?label=sbom%20(main)&branch=main>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml?query=branch%3Amain)
92
+ [![Release pipeline (tags)](<https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/publish-pypi-on-tag.yml?label=release%20pipeline%20(tags)&event=push>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/publish-pypi-on-tag.yml?query=event%3Apush)
91
93
  [![PyPI](https://img.shields.io/pypi/v/lintro?label=pypi)](https://pypi.org/project/lintro/)
92
94
 
93
95
  [![CodeQL](https://github.com/TurboCoder13/py-lintro/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/TurboCoder13/py-lintro/actions/workflows/codeql.yml?query=branch%3Amain)
94
- [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/TurboCoder13/py-lintro/badge)](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro)
95
-
96
- [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/11142/badge)](https://www.bestpractices.dev/projects/11142)
96
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/TurboCoder13/py-lintro/badge)](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro) [![SBOM](https://img.shields.io/badge/SBOM-enabled-brightgreen)](docs/security/assurance.md) [![Download SBOM](https://img.shields.io/badge/SBOM-download_latest-blue?logo=github)](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/11142/badge)](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
  [![Tests](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/test-and-coverage.yml?label=tests&branch=main&logo=githubactions&logoColor=white)](https://github.com/TurboCoder13/py-lintro/actions/workflows/test-and-coverage.yml?query=branch%3Amain)
15
15
  [![CI](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/ci-lintro-analysis.yml?label=ci&branch=main&logo=githubactions&logoColor=white)](https://github.com/TurboCoder13/py-lintro/actions/workflows/ci-lintro-analysis.yml?query=branch%3Amain)
16
16
  [![Docker](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/docker-build-publish.yml?label=docker&logo=docker&branch=main)](https://github.com/TurboCoder13/py-lintro/actions/workflows/docker-build-publish.yml?query=branch%3Amain)
17
+ [![SBOM (main)](<https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/sbom-on-main.yml?label=sbom%20(main)&branch=main>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml?query=branch%3Amain)
18
+ [![Release pipeline (tags)](<https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/publish-pypi-on-tag.yml?label=release%20pipeline%20(tags)&event=push>)](https://github.com/TurboCoder13/py-lintro/actions/workflows/publish-pypi-on-tag.yml?query=event%3Apush)
17
19
  [![PyPI](https://img.shields.io/pypi/v/lintro?label=pypi)](https://pypi.org/project/lintro/)
18
20
 
19
21
  [![CodeQL](https://github.com/TurboCoder13/py-lintro/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/TurboCoder13/py-lintro/actions/workflows/codeql.yml?query=branch%3Amain)
20
- [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/TurboCoder13/py-lintro/badge)](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro)
21
-
22
- [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/11142/badge)](https://www.bestpractices.dev/projects/11142)
22
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/TurboCoder13/py-lintro/badge)](https://scorecard.dev/viewer/?uri=github.com/TurboCoder13/py-lintro) [![SBOM](https://img.shields.io/badge/SBOM-enabled-brightgreen)](docs/security/assurance.md) [![Download SBOM](https://img.shields.io/badge/SBOM-download_latest-blue?logo=github)](https://github.com/TurboCoder13/py-lintro/actions/workflows/sbom-on-main.yml) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/11142/badge)](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="#e05d44" d="M63 0h36v20H63z"/>
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.7%</text>
19
- <text x="800" y="140" transform="scale(.1)" textLength="260">83.7%</text>
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
- - **New tool analysis** - Detailed comparisons with core tools
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
@@ -1,3 +1,3 @@
1
1
  """Lintro - A unified CLI core for code formatting, linting, and quality assurance."""
2
2
 
3
- __version__ = "0.6.3"
3
+ __version__ = "0.8.0"
@@ -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."""
@@ -1,3 +1,5 @@
1
+ """CSV output style implementation."""
2
+
1
3
  import csv
2
4
  import io
3
5
  from typing import Any
@@ -1,3 +1,5 @@
1
+ """Grid output style implementation."""
2
+
1
3
  from typing import Any
2
4
 
3
5
  from lintro.formatters.core.output_style import OutputStyle
@@ -1,3 +1,5 @@
1
+ """HTML output style implementation."""
2
+
1
3
  from typing import Any
2
4
 
3
5
  from lintro.formatters.core.output_style import OutputStyle
@@ -1,3 +1,5 @@
1
+ """JSON output style implementation."""
2
+
1
3
  import json
2
4
  from datetime import datetime
3
5
  from typing import Any
@@ -1,3 +1,5 @@
1
+ """Markdown output style implementation."""
2
+
1
3
  from typing import Any
2
4
 
3
5
  from lintro.formatters.core.output_style import OutputStyle
@@ -1,3 +1,5 @@
1
+ """Plain text output style implementation."""
2
+
1
3
  from typing import Any
2
4
 
3
5
  from lintro.formatters.core.output_style import OutputStyle
@@ -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(TableDescriptor):
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[BlackIssue]) -> list[list[str]]:
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: list[BlackIssue], format: str = "grid") -> str:
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(