lintro 0.3.2__tar.gz → 0.4.2__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 (183) hide show
  1. {lintro-0.3.2 → lintro-0.4.2}/LICENSE +1 -1
  2. {lintro-0.3.2/lintro.egg-info → lintro-0.4.2}/PKG-INFO +35 -28
  3. {lintro-0.3.2 → lintro-0.4.2}/README.md +23 -19
  4. {lintro-0.3.2 → lintro-0.4.2}/assets/images/coverage-badge.svg +2 -2
  5. {lintro-0.3.2 → lintro-0.4.2}/docs/README.md +9 -7
  6. {lintro-0.3.2 → lintro-0.4.2}/docs/configuration.md +64 -2
  7. {lintro-0.3.2 → lintro-0.4.2}/docs/contributing.md +61 -0
  8. {lintro-0.3.2 → lintro-0.4.2}/docs/getting-started.md +8 -2
  9. {lintro-0.3.2 → lintro-0.4.2}/docs/github-integration.md +33 -5
  10. {lintro-0.3.2 → lintro-0.4.2}/docs/tool-analysis/README.md +16 -0
  11. lintro-0.4.2/docs/tool-analysis/actionlint-analysis.md +68 -0
  12. lintro-0.4.2/docs/tool-analysis/bandit-analysis.md +76 -0
  13. {lintro-0.3.2 → lintro-0.4.2}/docs/tool-analysis/darglint-analysis.md +9 -3
  14. {lintro-0.3.2 → lintro-0.4.2}/docs/tool-analysis/hadolint-analysis.md +7 -1
  15. {lintro-0.3.2 → lintro-0.4.2}/docs/tool-analysis/prettier-analysis.md +12 -5
  16. {lintro-0.3.2 → lintro-0.4.2}/docs/tool-analysis/ruff-analysis.md +12 -4
  17. {lintro-0.3.2 → lintro-0.4.2}/docs/tool-analysis/yamllint-analysis.md +6 -0
  18. {lintro-0.3.2 → lintro-0.4.2}/lintro/__init__.py +1 -1
  19. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/tools/__init__.py +12 -0
  20. lintro-0.4.2/lintro/formatters/tools/actionlint_formatter.py +82 -0
  21. lintro-0.4.2/lintro/formatters/tools/bandit_formatter.py +100 -0
  22. lintro-0.4.2/lintro/parsers/__init__.py +21 -0
  23. lintro-0.4.2/lintro/parsers/actionlint/__init__.py +1 -0
  24. lintro-0.4.2/lintro/parsers/actionlint/actionlint_issue.py +24 -0
  25. lintro-0.4.2/lintro/parsers/actionlint/actionlint_parser.py +67 -0
  26. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/__init__.py +4 -0
  27. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/core/tool_base.py +6 -4
  28. lintro-0.4.2/lintro/tools/implementations/tool_actionlint.py +151 -0
  29. lintro-0.4.2/lintro/tools/implementations/tool_bandit.py +445 -0
  30. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/implementations/tool_darglint.py +2 -2
  31. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/implementations/tool_hadolint.py +1 -1
  32. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/implementations/tool_yamllint.py +1 -1
  33. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/tool_enum.py +4 -0
  34. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/console_logger.py +21 -5
  35. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/formatting.py +4 -2
  36. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/tool_executor.py +11 -6
  37. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/tool_utils.py +19 -0
  38. {lintro-0.3.2 → lintro-0.4.2/lintro.egg-info}/PKG-INFO +35 -28
  39. {lintro-0.3.2 → lintro-0.4.2}/lintro.egg-info/SOURCES.txt +21 -0
  40. {lintro-0.3.2 → lintro-0.4.2}/lintro.egg-info/requires.txt +9 -6
  41. {lintro-0.3.2 → lintro-0.4.2}/pyproject.toml +12 -8
  42. lintro-0.4.2/test_samples/actionlint_violations.yml +9 -0
  43. lintro-0.4.2/test_samples/bandit_violations.py +43 -0
  44. {lintro-0.3.2 → lintro-0.4.2}/tests/cli/test_cli.py +19 -34
  45. {lintro-0.3.2 → lintro-0.4.2}/tests/conftest.py +5 -52
  46. {lintro-0.3.2 → lintro-0.4.2}/tests/formatters/test_formatters.py +46 -57
  47. lintro-0.4.2/tests/integration/test_actionlint_integration.py +85 -0
  48. lintro-0.4.2/tests/integration/test_bandit_integration.py +51 -0
  49. {lintro-0.3.2 → lintro-0.4.2}/tests/integration/test_hadolint_integration.py +25 -61
  50. {lintro-0.3.2 → lintro-0.4.2}/tests/integration/test_ruff_integration.py +86 -119
  51. {lintro-0.3.2 → lintro-0.4.2}/tests/integration/test_yamllint_integration.py +28 -63
  52. {lintro-0.3.2 → lintro-0.4.2}/tests/scripts/test_delete_previous_lintro_comments.py +3 -11
  53. {lintro-0.3.2 → lintro-0.4.2}/tests/scripts/test_extract_version.py +6 -13
  54. lintro-0.4.2/tests/scripts/test_ghcr_prune_untagged.py +218 -0
  55. {lintro-0.3.2 → lintro-0.4.2}/tests/scripts/test_script_environment.py +63 -112
  56. lintro-0.4.2/tests/scripts/test_semantic_release_compute_next.py +128 -0
  57. {lintro-0.3.2 → lintro-0.4.2}/tests/scripts/test_shell_scripts.py +163 -59
  58. lintro-0.4.2/tests/unit/test_ascii_normalize.py +31 -0
  59. lintro-0.4.2/tests/unit/test_bandit_command_building.py +48 -0
  60. lintro-0.4.2/tests/unit/test_bandit_config_hydration.py +38 -0
  61. lintro-0.4.2/tests/unit/test_bandit_formatter_mapping.py +38 -0
  62. lintro-0.4.2/tests/unit/test_bandit_parsing.py +218 -0
  63. lintro-0.4.2/tests/unit/test_cli_commands.py +18 -0
  64. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_cli_commands_more.py +8 -11
  65. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_cli_programmatic.py +8 -22
  66. lintro-0.4.2/tests/unit/test_config_loader.py +29 -0
  67. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_console_logger.py +37 -27
  68. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_console_logger_more.py +5 -2
  69. lintro-0.4.2/tests/unit/test_enums_and_normalizers.py +66 -0
  70. lintro-0.4.2/tests/unit/test_exceptions.py +21 -0
  71. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_formatters_tables.py +21 -13
  72. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_output_manager_reports.py +5 -4
  73. lintro-0.4.2/tests/unit/test_parsers_actionlint.py +29 -0
  74. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_tool_executor.py +49 -35
  75. lintro-0.4.2/tests/unit/test_tool_executor_fmt_exclusion.py +24 -0
  76. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_tool_manager.py +12 -20
  77. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_tool_utils.py +19 -11
  78. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/test_tool_utils_more.py +29 -6
  79. {lintro-0.3.2 → lintro-0.4.2}/tests/utils/test_formatting.py +5 -9
  80. {lintro-0.3.2 → lintro-0.4.2}/tests/utils/test_output_manager.py +22 -32
  81. {lintro-0.3.2 → lintro-0.4.2}/tests/utils/test_path_utils.py +8 -16
  82. lintro-0.3.2/lintro/utils/__init__.py +0 -0
  83. lintro-0.3.2/tests/unit/test_ascii_normalize.py +0 -38
  84. lintro-0.3.2/tests/unit/test_cli_commands.py +0 -19
  85. lintro-0.3.2/tests/unit/test_config_loader.py +0 -30
  86. lintro-0.3.2/tests/unit/test_enums_and_normalizers.py +0 -54
  87. lintro-0.3.2/tests/unit/test_exceptions.py +0 -20
  88. {lintro-0.3.2 → lintro-0.4.2}/MANIFEST.in +0 -0
  89. {lintro-0.3.2 → lintro-0.4.2}/assets/images/lintro.png +0 -0
  90. {lintro-0.3.2 → lintro-0.4.2}/docs/coverage-setup.md +0 -0
  91. {lintro-0.3.2 → lintro-0.4.2}/docs/docker.md +0 -0
  92. {lintro-0.3.2 → lintro-0.4.2}/docs/lintro-self-use.md +0 -0
  93. {lintro-0.3.2 → lintro-0.4.2}/docs/style-guide.md +0 -0
  94. {lintro-0.3.2 → lintro-0.4.2}/lintro/__main__.py +0 -0
  95. {lintro-0.3.2 → lintro-0.4.2}/lintro/ascii-art/fail.txt +0 -0
  96. {lintro-0.3.2 → lintro-0.4.2}/lintro/ascii-art/success.txt +0 -0
  97. {lintro-0.3.2 → lintro-0.4.2}/lintro/cli.py +0 -0
  98. {lintro-0.3.2 → lintro-0.4.2}/lintro/cli_utils/__init__.py +0 -0
  99. {lintro-0.3.2 → lintro-0.4.2}/lintro/cli_utils/commands/__init__.py +0 -0
  100. {lintro-0.3.2 → lintro-0.4.2}/lintro/cli_utils/commands/check.py +0 -0
  101. {lintro-0.3.2 → lintro-0.4.2}/lintro/cli_utils/commands/format.py +0 -0
  102. {lintro-0.3.2 → lintro-0.4.2}/lintro/cli_utils/commands/list_tools.py +0 -0
  103. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/__init__.py +0 -0
  104. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/action.py +0 -0
  105. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/darglint_strictness.py +0 -0
  106. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/group_by.py +0 -0
  107. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/hadolint_enums.py +0 -0
  108. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/output_format.py +0 -0
  109. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/tool_name.py +0 -0
  110. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/tool_type.py +0 -0
  111. {lintro-0.3.2 → lintro-0.4.2}/lintro/enums/yamllint_format.py +0 -0
  112. {lintro-0.3.2 → lintro-0.4.2}/lintro/exceptions/__init__.py +0 -0
  113. {lintro-0.3.2 → lintro-0.4.2}/lintro/exceptions/errors.py +0 -0
  114. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/__init__.py +0 -0
  115. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/core/__init__.py +0 -0
  116. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/core/output_style.py +0 -0
  117. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/core/table_descriptor.py +0 -0
  118. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/styles/__init__.py +0 -0
  119. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/styles/csv.py +0 -0
  120. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/styles/grid.py +0 -0
  121. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/styles/html.py +0 -0
  122. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/styles/json.py +0 -0
  123. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/styles/markdown.py +0 -0
  124. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/styles/plain.py +0 -0
  125. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/tools/darglint_formatter.py +0 -0
  126. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/tools/hadolint_formatter.py +0 -0
  127. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/tools/prettier_formatter.py +0 -0
  128. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/tools/ruff_formatter.py +0 -0
  129. {lintro-0.3.2 → lintro-0.4.2}/lintro/formatters/tools/yamllint_formatter.py +0 -0
  130. {lintro-0.3.2 → lintro-0.4.2}/lintro/models/__init__.py +0 -0
  131. {lintro-0.3.2 → lintro-0.4.2}/lintro/models/core/__init__.py +0 -0
  132. {lintro-0.3.2 → lintro-0.4.2}/lintro/models/core/tool.py +0 -0
  133. {lintro-0.3.2 → lintro-0.4.2}/lintro/models/core/tool_config.py +0 -0
  134. {lintro-0.3.2 → lintro-0.4.2}/lintro/models/core/tool_result.py +0 -0
  135. {lintro-0.3.2/lintro/parsers → lintro-0.4.2/lintro/parsers/darglint}/__init__.py +0 -0
  136. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/darglint/darglint_issue.py +0 -0
  137. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/darglint/darglint_parser.py +0 -0
  138. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/hadolint/__init__.py +0 -0
  139. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
  140. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
  141. {lintro-0.3.2/lintro/parsers/darglint → lintro-0.4.2/lintro/parsers/prettier}/__init__.py +0 -0
  142. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/prettier/prettier_issue.py +0 -0
  143. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/prettier/prettier_parser.py +0 -0
  144. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/ruff/__init__.py +0 -0
  145. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/ruff/ruff_issue.py +0 -0
  146. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/ruff/ruff_parser.py +0 -0
  147. {lintro-0.3.2/lintro/parsers/prettier → lintro-0.4.2/lintro/parsers/yamllint}/__init__.py +0 -0
  148. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
  149. {lintro-0.3.2 → lintro-0.4.2}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
  150. {lintro-0.3.2/lintro/parsers/yamllint → lintro-0.4.2/lintro/tools/core}/__init__.py +0 -0
  151. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/core/tool_manager.py +0 -0
  152. {lintro-0.3.2/lintro/tools/core → lintro-0.4.2/lintro/tools/implementations}/__init__.py +0 -0
  153. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/implementations/tool_prettier.py +0 -0
  154. {lintro-0.3.2 → lintro-0.4.2}/lintro/tools/implementations/tool_ruff.py +0 -0
  155. {lintro-0.3.2/lintro/tools/implementations → lintro-0.4.2/lintro/utils}/__init__.py +0 -0
  156. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/ascii_normalize_cli.py +0 -0
  157. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/config.py +0 -0
  158. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/output_manager.py +0 -0
  159. {lintro-0.3.2 → lintro-0.4.2}/lintro/utils/path_utils.py +0 -0
  160. {lintro-0.3.2 → lintro-0.4.2}/lintro.egg-info/dependency_links.txt +0 -0
  161. {lintro-0.3.2 → lintro-0.4.2}/lintro.egg-info/entry_points.txt +0 -0
  162. {lintro-0.3.2 → lintro-0.4.2}/lintro.egg-info/top_level.txt +0 -0
  163. {lintro-0.3.2 → lintro-0.4.2}/setup.cfg +0 -0
  164. {lintro-0.3.2 → lintro-0.4.2}/test_samples/Dockerfile.violations +0 -0
  165. {lintro-0.3.2 → lintro-0.4.2}/test_samples/darglint_violations.py +0 -0
  166. {lintro-0.3.2 → lintro-0.4.2}/test_samples/prettier_violations.js +0 -0
  167. {lintro-0.3.2 → lintro-0.4.2}/test_samples/ruff_clean.py +0 -0
  168. {lintro-0.3.2 → lintro-0.4.2}/test_samples/ruff_violations.py +0 -0
  169. {lintro-0.3.2 → lintro-0.4.2}/test_samples/yaml_violations.yml +0 -0
  170. {lintro-0.3.2 → lintro-0.4.2}/tests/__init__.py +0 -0
  171. {lintro-0.3.2 → lintro-0.4.2}/tests/cli/__init__.py +0 -0
  172. {lintro-0.3.2 → lintro-0.4.2}/tests/cli/conftest.py +0 -0
  173. {lintro-0.3.2 → lintro-0.4.2}/tests/formatters/__init__.py +0 -0
  174. {lintro-0.3.2 → lintro-0.4.2}/tests/formatters/conftest.py +0 -0
  175. {lintro-0.3.2 → lintro-0.4.2}/tests/integration/__init__.py +0 -0
  176. {lintro-0.3.2 → lintro-0.4.2}/tests/integration/conftest.py +0 -0
  177. {lintro-0.3.2 → lintro-0.4.2}/tests/integration/test_darglint_integration.py +0 -0
  178. {lintro-0.3.2 → lintro-0.4.2}/tests/integration/test_prettier_integration.py +0 -0
  179. {lintro-0.3.2 → lintro-0.4.2}/tests/scripts/__init__.py +0 -0
  180. {lintro-0.3.2 → lintro-0.4.2}/tests/test_documentation.py +0 -0
  181. {lintro-0.3.2 → lintro-0.4.2}/tests/unit/__init__.py +0 -0
  182. {lintro-0.3.2 → lintro-0.4.2}/tests/utils/__init__.py +0 -0
  183. {lintro-0.3.2 → lintro-0.4.2}/tests/utils/conftest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Eitel Dagnin
3
+ Copyright (c) 2024 TurboCoder13
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lintro
3
- Version: 0.3.2
3
+ Version: 0.4.2
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
7
7
 
8
- Copyright (c) 2024 Eitel Dagnin
8
+ Copyright (c) 2024 TurboCoder13
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy
11
11
  of this software and associated documentation files (the "Software"), to deal
@@ -36,10 +36,10 @@ Classifier: Programming Language :: Python :: 3.13
36
36
  Classifier: Topic :: Software Development :: Quality Assurance
37
37
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
38
  Classifier: Topic :: Utilities
39
- Requires-Python: <3.14,>=3.13
39
+ Requires-Python: ==3.13.7
40
40
  Description-Content-Type: text/markdown
41
41
  License-File: LICENSE
42
- Requires-Dist: click==8.2.1
42
+ Requires-Dist: click==8.1.8
43
43
  Requires-Dist: coverage-badge==1.1.2
44
44
  Requires-Dist: darglint==1.8.1
45
45
  Requires-Dist: loguru==0.7.3
@@ -47,25 +47,28 @@ Requires-Dist: tabulate==0.9.0
47
47
  Requires-Dist: yamllint==1.37.1
48
48
  Requires-Dist: httpx==0.28.1
49
49
  Requires-Dist: toml==0.10.2
50
- Requires-Dist: python-semantic-release>=9.12.0
50
+ Requires-Dist: defusedxml==0.7.1
51
51
  Provides-Extra: dev
52
52
  Requires-Dist: pytest==8.4.1; extra == "dev"
53
53
  Requires-Dist: pytest-cov==6.2.1; extra == "dev"
54
54
  Requires-Dist: pytest-mock==3.14.1; extra == "dev"
55
- Requires-Dist: pytest-xdist==3.6.1; extra == "dev"
55
+ Requires-Dist: pytest-xdist==3.8.0; extra == "dev"
56
56
  Requires-Dist: tox==4.28.4; 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==9.12.0; extra == "dev"
61
+ Requires-Dist: python-semantic-release==10.3.1; extra == "dev"
62
+ Requires-Dist: assertpy==1.1; extra == "dev"
63
+ Requires-Dist: httpx==0.28.1; extra == "dev"
62
64
  Provides-Extra: test
63
65
  Requires-Dist: pytest==8.4.1; extra == "test"
64
66
  Requires-Dist: pytest-cov==6.2.1; extra == "test"
65
67
  Requires-Dist: pytest-mock==3.14.1; extra == "test"
66
- Requires-Dist: pytest-xdist==3.6.1; extra == "test"
68
+ Requires-Dist: pytest-xdist==3.8.0; extra == "test"
69
+ Requires-Dist: assertpy==1.1; extra == "test"
67
70
  Provides-Extra: typing
68
- Requires-Dist: types-setuptools==80.9.0.20250809; extra == "typing"
71
+ Requires-Dist: types-setuptools==80.9.0.20250822; extra == "typing"
69
72
  Requires-Dist: types-tabulate==0.9.0.20241207; extra == "typing"
70
73
  Dynamic: license-file
71
74
 
@@ -79,6 +82,17 @@ A comprehensive CLI tool that unifies various code formatting, linting, and qual
79
82
 
80
83
  Lintro is a unified command-line interface that brings together multiple code quality tools into a single, easy-to-use package. Instead of managing separate tools like Ruff, Prettier, Yamllint, and others individually, Lintro provides a consistent interface for all your code quality needs.
81
84
 
85
+ [![Python](https://img.shields.io/badge/python-3.13-blue)](https://www.python.org/downloads/)
86
+ [![Coverage](https://codecov.io/gh/TurboCoder13/py-lintro/branch/main/graph/badge.svg)](https://codecov.io/gh/TurboCoder13/py-lintro)
87
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
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
+ [![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
+ [![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
+ [![PyPI](https://img.shields.io/pypi/v/lintro?label=pypi)](https://pypi.org/project/lintro/)
92
+
93
+ [![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.securityscorecards.dev/projects/github.com/turbocoder13/py-lintro/badge)](https://securityscorecards.dev/viewer/?uri=github.com/turbocoder13/py-lintro)
95
+
82
96
  ### Why Lintro?
83
97
 
84
98
  - **🚀 Unified Interface**: One command to run all your linting and formatting tools
@@ -89,15 +103,6 @@ Lintro is a unified command-line interface that brings together multiple code qu
89
103
  - **⚡ Fast**: Optimized execution with efficient tool management
90
104
  - **🔒 Reliable**: Comprehensive test suite with 84% coverage
91
105
 
92
- [![Python](https://img.shields.io/badge/python-3.13-blue)](https://www.python.org/downloads/)
93
- [![Coverage](assets/images/coverage-badge.svg)](docs/coverage-setup.md)
94
- [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
95
- [![Tests](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/test-and-coverage.yml?label=tests)](https://github.com/TurboCoder13/py-lintro/actions/workflows/test-and-coverage.yml)
96
- [![CI](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/ci-lintro-analysis.yml?label=ci)](https://github.com/TurboCoder13/py-lintro/actions/workflows/ci-lintro-analysis.yml)
97
- [![Docker](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/docker-build-publish.yml?label=docker&logo=docker)](https://github.com/TurboCoder13/py-lintro/actions/workflows/docker-build-publish.yml)
98
- [![Code Style](https://img.shields.io/badge/code%20style-ruff-black-blue)](https://github.com/astral-sh/ruff)
99
- [![PyPI](https://img.shields.io/pypi/v/lintro?label=pypi)](https://pypi.org/project/lintro/)
100
-
101
106
  ## Features
102
107
 
103
108
  - **Unified CLI** for multiple code quality tools
@@ -109,13 +114,15 @@ Lintro is a unified command-line interface that brings together multiple code qu
109
114
 
110
115
  ## Supported Tools
111
116
 
112
- | Tool | Language/Format | Purpose | Auto-fix |
113
- | ------------ | --------------- | -------------------- | -------- |
114
- | **Ruff** | Python | Linting & Formatting | |
115
- | **Darglint** | Python | Docstring Validation | - |
116
- | **Prettier** | JS/TS/JSON | Code Formatting | |
117
- | **Yamllint** | YAML | Syntax & Style | - |
118
- | **Hadolint** | Dockerfile | Best Practices | - |
117
+ | Tool | Language | Auto-fix |
118
+ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -------- |
119
+ | [![Actionlint](https://img.shields.io/badge/Actionlint-GitHub%20Workflows-24292e?logo=github&logoColor=white)](https://github.com/rhysd/actionlint) | ⚙️ GitHub Workflows | - |
120
+ | [![Bandit](https://img.shields.io/badge/Bandit-security-yellow?logo=python&logoColor=white)](https://github.com/PyCQA/bandit) | 🐍 Python | - |
121
+ | [![Darglint](https://img.shields.io/badge/Darglint-docstrings-3776AB?logo=python&logoColor=white)](https://github.com/terrencepreilly/darglint) | 🐍 Python | - |
122
+ | [![Hadolint](https://img.shields.io/badge/Hadolint-lint-2496ED?logo=docker&logoColor=white)](https://github.com/hadolint/hadolint) | 🐳 Dockerfile | - |
123
+ | [![Prettier](https://img.shields.io/badge/Prettier-format-1a2b34?logo=prettier&logoColor=white)](https://prettier.io/) | 🟨 JS/TS · 🧾 JSON | |
124
+ | [![Ruff](https://img.shields.io/badge/Ruff-lint%2Bformat-000?logo=ruff&logoColor=white)](https://github.com/astral-sh/ruff) | 🐍 Python | ✅ |
125
+ | [![Yamllint](https://img.shields.io/badge/Yamllint-lint-cb171e?logo=yaml&logoColor=white)](https://github.com/adrienverge/yamllint) | 🧾 YAML | - |
119
126
 
120
127
  ## Quick Start
121
128
 
@@ -149,7 +156,7 @@ lintro format
149
156
  lintro check --output-format grid
150
157
 
151
158
  # Run specific tools only
152
- lintro check --tools ruff,prettier
159
+ lintro check --tools ruff,prettier,actionlint
153
160
 
154
161
  # List all available tools
155
162
  lintro list-tools
@@ -206,8 +213,8 @@ lintro check --output-format grid --group-by code # Group by error type
206
213
  # Exclude patterns
207
214
  lintro check --exclude "migrations,node_modules,dist"
208
215
 
209
- # Tool-specific options
210
- lintro check --tool-options "ruff:--line-length=88,prettier:--print-width=80"
216
+ # Tool-specific options use key=value (lists with |)
217
+ lintro check --tool-options "ruff:line_length=88,prettier:print_width=80"
211
218
 
212
219
  # Ruff fix configuration (fmt):
213
220
  # By default, fmt applies both lint fixes and formatting for Ruff.
@@ -8,6 +8,17 @@ A comprehensive CLI tool that unifies various code formatting, linting, and qual
8
8
 
9
9
  Lintro is a unified command-line interface that brings together multiple code quality tools into a single, easy-to-use package. Instead of managing separate tools like Ruff, Prettier, Yamllint, and others individually, Lintro provides a consistent interface for all your code quality needs.
10
10
 
11
+ [![Python](https://img.shields.io/badge/python-3.13-blue)](https://www.python.org/downloads/)
12
+ [![Coverage](https://codecov.io/gh/TurboCoder13/py-lintro/branch/main/graph/badge.svg)](https://codecov.io/gh/TurboCoder13/py-lintro)
13
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
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
+ [![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
+ [![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
+ [![PyPI](https://img.shields.io/pypi/v/lintro?label=pypi)](https://pypi.org/project/lintro/)
18
+
19
+ [![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.securityscorecards.dev/projects/github.com/turbocoder13/py-lintro/badge)](https://securityscorecards.dev/viewer/?uri=github.com/turbocoder13/py-lintro)
21
+
11
22
  ### Why Lintro?
12
23
 
13
24
  - **🚀 Unified Interface**: One command to run all your linting and formatting tools
@@ -18,15 +29,6 @@ Lintro is a unified command-line interface that brings together multiple code qu
18
29
  - **⚡ Fast**: Optimized execution with efficient tool management
19
30
  - **🔒 Reliable**: Comprehensive test suite with 84% coverage
20
31
 
21
- [![Python](https://img.shields.io/badge/python-3.13-blue)](https://www.python.org/downloads/)
22
- [![Coverage](assets/images/coverage-badge.svg)](docs/coverage-setup.md)
23
- [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
24
- [![Tests](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/test-and-coverage.yml?label=tests)](https://github.com/TurboCoder13/py-lintro/actions/workflows/test-and-coverage.yml)
25
- [![CI](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/ci-lintro-analysis.yml?label=ci)](https://github.com/TurboCoder13/py-lintro/actions/workflows/ci-lintro-analysis.yml)
26
- [![Docker](https://img.shields.io/github/actions/workflow/status/TurboCoder13/py-lintro/docker-build-publish.yml?label=docker&logo=docker)](https://github.com/TurboCoder13/py-lintro/actions/workflows/docker-build-publish.yml)
27
- [![Code Style](https://img.shields.io/badge/code%20style-ruff-black-blue)](https://github.com/astral-sh/ruff)
28
- [![PyPI](https://img.shields.io/pypi/v/lintro?label=pypi)](https://pypi.org/project/lintro/)
29
-
30
32
  ## Features
31
33
 
32
34
  - **Unified CLI** for multiple code quality tools
@@ -38,13 +40,15 @@ Lintro is a unified command-line interface that brings together multiple code qu
38
40
 
39
41
  ## Supported Tools
40
42
 
41
- | Tool | Language/Format | Purpose | Auto-fix |
42
- | ------------ | --------------- | -------------------- | -------- |
43
- | **Ruff** | Python | Linting & Formatting | |
44
- | **Darglint** | Python | Docstring Validation | - |
45
- | **Prettier** | JS/TS/JSON | Code Formatting | |
46
- | **Yamllint** | YAML | Syntax & Style | - |
47
- | **Hadolint** | Dockerfile | Best Practices | - |
43
+ | Tool | Language | Auto-fix |
44
+ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -------- |
45
+ | [![Actionlint](https://img.shields.io/badge/Actionlint-GitHub%20Workflows-24292e?logo=github&logoColor=white)](https://github.com/rhysd/actionlint) | ⚙️ GitHub Workflows | - |
46
+ | [![Bandit](https://img.shields.io/badge/Bandit-security-yellow?logo=python&logoColor=white)](https://github.com/PyCQA/bandit) | 🐍 Python | - |
47
+ | [![Darglint](https://img.shields.io/badge/Darglint-docstrings-3776AB?logo=python&logoColor=white)](https://github.com/terrencepreilly/darglint) | 🐍 Python | - |
48
+ | [![Hadolint](https://img.shields.io/badge/Hadolint-lint-2496ED?logo=docker&logoColor=white)](https://github.com/hadolint/hadolint) | 🐳 Dockerfile | - |
49
+ | [![Prettier](https://img.shields.io/badge/Prettier-format-1a2b34?logo=prettier&logoColor=white)](https://prettier.io/) | 🟨 JS/TS · 🧾 JSON | |
50
+ | [![Ruff](https://img.shields.io/badge/Ruff-lint%2Bformat-000?logo=ruff&logoColor=white)](https://github.com/astral-sh/ruff) | 🐍 Python | ✅ |
51
+ | [![Yamllint](https://img.shields.io/badge/Yamllint-lint-cb171e?logo=yaml&logoColor=white)](https://github.com/adrienverge/yamllint) | 🧾 YAML | - |
48
52
 
49
53
  ## Quick Start
50
54
 
@@ -78,7 +82,7 @@ lintro format
78
82
  lintro check --output-format grid
79
83
 
80
84
  # Run specific tools only
81
- lintro check --tools ruff,prettier
85
+ lintro check --tools ruff,prettier,actionlint
82
86
 
83
87
  # List all available tools
84
88
  lintro list-tools
@@ -135,8 +139,8 @@ lintro check --output-format grid --group-by code # Group by error type
135
139
  # Exclude patterns
136
140
  lintro check --exclude "migrations,node_modules,dist"
137
141
 
138
- # Tool-specific options
139
- lintro check --tool-options "ruff:--line-length=88,prettier:--print-width=80"
142
+ # Tool-specific options use key=value (lists with |)
143
+ lintro check --tool-options "ruff:line_length=88,prettier:print_width=80"
140
144
 
141
145
  # Ruff fix configuration (fmt):
142
146
  # By default, fmt applies both lint fixes and formatting for Ruff.
@@ -15,7 +15,7 @@
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">80.3%</text>
19
- <text x="800" y="140" transform="scale(.1)" textLength="260">80.3%</text>
18
+ <text x="800" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="260">82.0%</text>
19
+ <text x="800" y="140" transform="scale(.1)" textLength="260">82.0%</text>
20
20
  </g>
21
21
  </svg>
@@ -105,13 +105,15 @@ lintro format
105
105
 
106
106
  ## 🛠️ Supported Tools
107
107
 
108
- | Tool | Language/Format | Purpose | Documentation |
109
- | ------------ | --------------- | -------------------- | ------------------------------------------------------- |
110
- | **Ruff** | Python | Linting & Formatting | [Config Guide](configuration.md#ruff-configuration) |
111
- | **Darglint** | Python | Docstring Validation | [Analysis](tool-analysis/darglint-analysis.md) |
112
- | **Prettier** | JS/TS/JSON/CSS | Code Formatting | [Analysis](tool-analysis/prettier-analysis.md) |
113
- | **Yamllint** | YAML | Syntax & Style | [Config Guide](configuration.md#yamllint-configuration) |
114
- | **Hadolint** | Dockerfile | Best Practices | [Config Guide](configuration.md#hadolint-configuration) |
108
+ | Tool | Language/Format | Purpose | Documentation |
109
+ | -------------- | ---------------- | -------------------- | ------------------------------------------------------- |
110
+ | **Ruff** | Python | Linting & Formatting | [Config Guide](configuration.md#ruff-configuration) |
111
+ | **Darglint** | Python | Docstring Validation | [Analysis](tool-analysis/darglint-analysis.md) |
112
+ | **Bandit** | Python | Security Linting | [Analysis](tool-analysis/bandit-analysis.md) |
113
+ | **Prettier** | JS/TS/JSON/CSS | Code Formatting | [Analysis](tool-analysis/prettier-analysis.md) |
114
+ | **Yamllint** | YAML | Syntax & Style | [Config Guide](configuration.md#yamllint-configuration) |
115
+ | **Actionlint** | GitHub Workflows | Workflow Linting | [Analysis](tool-analysis/actionlint-analysis.md) |
116
+ | **Hadolint** | Dockerfile | Best Practices | [Config Guide](configuration.md#hadolint-configuration) |
115
117
 
116
118
  ## 📋 Command Reference
117
119
 
@@ -27,8 +27,11 @@ lintro check path/to/files # Check specific paths
27
27
  #### Tool-Specific Options
28
28
 
29
29
  ```bash
30
- # Tool-specific options
31
- lintro check --tool-options "ruff:--line-length=88,prettier:--print-width=80"
30
+ # Tool-specific options (key=value; lists use |)
31
+ lintro check --tool-options "ruff:line_length=88,prettier:print_width=80"
32
+
33
+ # Example with lists and booleans
34
+ lintro check --tool-options "ruff:select=E|F|W,ruff:preview=True"
32
35
 
33
36
  # Exclude patterns
34
37
  lintro check --exclude "*.pyc,venv,node_modules"
@@ -132,6 +135,46 @@ select = E,W,F,I,N,D
132
135
  exclude = .git,__pycache__,.venv
133
136
  ```
134
137
 
138
+ #### Bandit Configuration
139
+
140
+ **File:** `pyproject.toml`
141
+
142
+ ```toml
143
+ [tool.bandit]
144
+ exclude_dirs = ["tests", "venv", ".git"]
145
+ tests = ["B101,B102,B103"] # Specific test IDs to run
146
+ skips = ["B101"] # Test IDs to skip
147
+ confidence = "MEDIUM" # Minimum confidence level
148
+ severity = "LOW" # Minimum severity level
149
+
150
+ [tool.bandit.assert_used]
151
+ exclude = ["test_*.py"] # Files to exclude from assert_used test
152
+ ```
153
+
154
+ **File:** `.bandit`
155
+
156
+ ```ini
157
+ [bandit]
158
+ exclude = tests,venv,.git
159
+ tests = B101,B102,B103
160
+ skips = B101
161
+ confidence = MEDIUM
162
+ severity = LOW
163
+
164
+ [[tool.bandit.assert_used]]
165
+ exclude = test_*.py
166
+ ```
167
+
168
+ **Available Options:**
169
+
170
+ - `tests`: Comma-separated list of test IDs to run
171
+ - `skips`: Comma-separated list of test IDs to skip
172
+ - `exclude`: Comma-separated list of paths to exclude
173
+ - `exclude_dirs`: List of directories to exclude (pyproject.toml only)
174
+ - `severity`: Minimum severity level (`LOW`, `MEDIUM`, `HIGH`)
175
+ - `confidence`: Minimum confidence level (`LOW`, `MEDIUM`, `HIGH`)
176
+ - `baseline`: Path to baseline report for comparison
177
+
135
178
  #### Darglint Configuration
136
179
 
137
180
  **File:** `.darglint`
@@ -326,6 +369,25 @@ RUN apt-get update && apt-get install -y \
326
369
  python3-pip
327
370
  ```
328
371
 
372
+ #### Actionlint Configuration
373
+
374
+ Actionlint validates GitHub Actions workflows. Lintro discovers workflow files
375
+ under `/.github/workflows/` when you run `lintro check .` and invokes the
376
+ `actionlint` binary.
377
+
378
+ - Discovery: YAML files filtered to those in `/.github/workflows/`
379
+ - Defaults: Lintro does not pass special flags; native actionlint defaults are used
380
+ - Local install: use `scripts/utils/install-tools.sh --local` to place `actionlint` on PATH
381
+ - Docker/CI: the Docker image installs `actionlint` during build, so CI tests run it
382
+
383
+ ```bash
384
+ # Validate workflows only
385
+ lintro check --tools actionlint
386
+
387
+ # Validate workflows along with other tools
388
+ lintro check --tools ruff,actionlint
389
+ ```
390
+
329
391
  ## Project-Specific Configuration
330
392
 
331
393
  ### Multi-Language Projects
@@ -81,3 +81,64 @@ Release automation:
81
81
  - Tag push publishes to PyPI (OIDC) and creates a GitHub Release with artifacts.
82
82
 
83
83
  For detailed contribution guidelines, see the project documentation or contact a maintainer.
84
+
85
+ ---
86
+
87
+ ## Tool Integration Guidelines
88
+
89
+ This section describes how to add a new external tool to Lintro while keeping a
90
+ consistent UX and maintainable implementation.
91
+
92
+ ### Principles
93
+
94
+ - Minimal defaults: invoke the native CLI without forcing special formats.
95
+ - Predictable discovery: put file-discovery rules into the tool implementation
96
+ (e.g., Actionlint filters to `/.github/workflows/`).
97
+ - Wrapper, not replacement: rely on tool defaults and parse its standard
98
+ output; only add switches when strictly necessary for parsing.
99
+
100
+ ### Implementation Steps
101
+
102
+ 1. Core code
103
+
104
+ - Create a tool class in `lintro/tools/implementations/` (subclass `BaseTool`).
105
+ - Implement `check()` (and `fix()` only if the tool supports auto-fixes).
106
+ - Add a parser module in `lintro/parsers/<tool>/` for the tool's default output.
107
+ - Add a formatter in `lintro/formatters/tools/` with a `TableDescriptor`.
108
+ - Register the tool in `lintro/tools/tool_enum.py`.
109
+ - Register the table formatter in `TOOL_TABLE_FORMATTERS` within
110
+ `lintro/utils/tool_utils.py`.
111
+
112
+ 2. Tests
113
+
114
+ - Put minimal violation samples in `test_samples/`.
115
+ - Add unit tests for the parser.
116
+ - Add integration tests that:
117
+ - Run the tool directly (CLI) on the sample
118
+ - Run the tool via Lintro and compare parity (issue counts, status)
119
+ - Use realistic paths (e.g., `.github/workflows/` for Actionlint)
120
+ - Allow local skip when a system binary is missing (CI/Docker installs tools).
121
+
122
+ 3. Installer support
123
+
124
+ - Update `scripts/utils/install-tools.sh` to install the binary.
125
+ - Prefer upstream installers when available (uv/pip, npm, official script,
126
+ Homebrew). For OS/arch tarballs, encapsulate download/extract in a helper.
127
+ - Verify checksums when possible.
128
+
129
+ 4. Docs checklist
130
+
131
+ - Update `README.md` Supported Tools table and CLI examples.
132
+ - Update `docs/getting-started.md` with a short usage example.
133
+ - Update `docs/configuration.md` with discovery notes and usage tips.
134
+
135
+ 5. CI and Docker
136
+
137
+ - The Docker image installs all supported tools; integration tests should run
138
+ without skipping inside Docker/CI.
139
+
140
+ ### Pass-through Options (optional)
141
+
142
+ Expose native flags via `--tool-options tool:key=value` only after the core
143
+ behavior is stable. Keep defaults minimal to avoid surprising users and to
144
+ maintain parity with direct CLI behavior.
@@ -149,6 +149,12 @@ lintro check .github/ config/ --tools yamllint
149
149
  **Tools:**
150
150
 
151
151
  - **Yamllint** - YAML syntax and style validation
152
+ - **Actionlint** - GitHub Actions workflow validation (files under `.github/workflows/`)
153
+
154
+ ```bash
155
+ # Validate GitHub workflows
156
+ lintro check --tools actionlint
157
+ ```
152
158
 
153
159
  ### Docker Files
154
160
 
@@ -247,8 +253,8 @@ rules:
247
253
  ### Lintro-Specific Options
248
254
 
249
255
  ```bash
250
- # Tool timeouts
251
- lintro check --tool-options "ruff:--line-length=88,prettier:--print-width=80"
256
+ # Tool options use key=value (lists with |, booleans True/False)
257
+ lintro check --tool-options "ruff:line_length=88,prettier:print_width=80"
252
258
 
253
259
  # Exclude patterns
254
260
  lintro check --exclude "migrations,node_modules,dist"
@@ -133,7 +133,7 @@ Edit the workflow files to match your project structure:
133
133
  uv run lintro check *.json --tools prettier --output-format grid
134
134
  ```
135
135
 
136
- ### 3. Configure Repository Settings
136
+ ### 3. Configure Repository Settings (optional for Pages)
137
137
 
138
138
  **Enable GitHub Pages:**
139
139
 
@@ -141,18 +141,18 @@ Edit the workflow files to match your project structure:
141
141
  2. Select **Source:** "GitHub Actions"
142
142
  3. Your coverage badge will be available at: `https://TurboCoder13.github.io/py-lintro/badges/coverage.svg`
143
143
 
144
- ## Release Automation
144
+ ## Release Automation (Single Release Train)
145
145
 
146
146
  The repository ships with fully automated semantic releases and PyPI publishing.
147
147
 
148
148
  - **Automated Release PR** (`.github/workflows/semantic-release.yml`)
149
149
  - On push to `main`, computes the next version from Conventional Commits
150
150
  - Updates `pyproject.toml` and `lintro/__init__.py`
151
- - Opens a Release PR and enables auto-merge; once checks pass, it merges
151
+ - Opens a Release PR (no direct push to main) and enables auto-merge; once checks pass, it merges
152
152
 
153
153
  - **Auto Tag on Main** (`.github/workflows/auto-tag-on-main.yml`)
154
- - After the Release PR is merged, detects the new version in `pyproject.toml`
155
- - Creates and pushes a matching git tag if it does not already exist
154
+ - After the Release PR is merged, a guard step ensures the last commit matches `chore(release):` pattern
155
+ - Detects the new version in `pyproject.toml`, and creates/pushes the tag if it does not already exist
156
156
 
157
157
  - **Publish to PyPI on Tag** (`.github/workflows/publish-pypi-on-tag.yml`)
158
158
  - On tag push (e.g., `1.2.3`), verifies tag equals `pyproject.toml` version
@@ -161,6 +161,34 @@ The repository ships with fully automated semantic releases and PyPI publishing.
161
161
 
162
162
  > End-to-end: Conventional commits → Release PR (auto-merged) → Tag created → PyPI publish.
163
163
 
164
+ ### Permissions Model (least privilege)
165
+
166
+ - Default each workflow to `permissions: { contents: read }`.
167
+ - Grant elevated permissions only where required:
168
+ - Tag creation job: `contents: write`.
169
+ - PyPI publish job: `id-token: write` (for OIDC) and `contents: write` only if creating a GH Release.
170
+ - PR comment jobs: `pull-requests: write`.
171
+
172
+ ### Why we do not allow `astral-sh/setup-uv`
173
+
174
+ Our Actions policy requires that all actions (including transitive actions used by
175
+ composites) are allowlisted and pinned to a full commit SHA. The
176
+ `astral-sh/setup-uv` action invokes `actions/setup-python@v5` internally, which
177
+ is both not on our allowlist and referenced by tag (not a 40-char SHA). This
178
+ causes policy enforcement to block any job that uses `setup-uv`.
179
+
180
+ To comply, we replaced it with an internal composite `setup-env` that:
181
+ - installs `uv` via `pip` (no nested actions),
182
+ - provisions the requested Python version via `uv python install`, and
183
+ - syncs dependencies, keeping our pipeline policy-compliant.
184
+
185
+ Deprecated/manual flows (e.g., direct Release creation workflows) are removed to avoid parallel release paths.
186
+
187
+ ### Labels & guards
188
+
189
+ - Release PRs are labeled `release-bump` to make them easy to target in policies.
190
+ - Tagging is guarded in `auto-tag-on-main.yml` by checking the last commit title starts with `chore(release):` to ensure tags are only created after Release PR merges.
191
+
164
192
  ### Security & Pinning
165
193
 
166
194
  - Third-party actions are pinned to commit SHAs for reproducibility and supply-chain safety.
@@ -38,6 +38,22 @@ This directory contains comprehensive analyses comparing Lintro's wrapper implem
38
38
 
39
39
  ### [Hadolint Analysis](./hadolint-analysis.md)
40
40
 
41
+ ### [Bandit Analysis](./bandit-analysis.md)
42
+
43
+ **Python Security Linter**
44
+
45
+ - ✅ **Preserved**: Recursive scanning, severity/confidence gates, config/baseline
46
+ - ⚠️ **Defaults**: JSON output and quiet logs for stable parsing
47
+ - 🚀 **Notes**: Robust JSON extraction; normalized reporting
48
+
49
+ ### [Actionlint Analysis](./actionlint-analysis.md)
50
+
51
+ **GitHub Actions Workflow Linter**
52
+
53
+ - ✅ **Preserved**: Default output, rule detection, workflow path targeting
54
+ - ⚠️ **Defaults**: No flags; filtered to `/.github/workflows/`
55
+ - 🚀 **Notes**: Normalized parsing and formatting
56
+
41
57
  **Dockerfile Linter for Best Practices**
42
58
 
43
59
  - ✅ **Preserved**: Dockerfile analysis, shell script linting, best practices, security scanning
@@ -0,0 +1,68 @@
1
+ # Actionlint Tool Analysis
2
+
3
+ ## Overview
4
+
5
+ Actionlint is a linter for GitHub Actions workflow files. This analysis compares
6
+ Lintro's wrapper with the core Actionlint tool.
7
+
8
+ ## Core Tool Capabilities
9
+
10
+ - **Workflow linting**: Checks YAML under `.github/workflows/`
11
+ - **ShellCheck integration**: Lints shell snippets in `run:` steps
12
+ - **Rule configuration**: Enable/disable specific checks via config or flags
13
+ - **Formatting**: Default text output, `-format`/`-oneline`, color toggles
14
+
15
+ ## Lintro Implementation Analysis
16
+
17
+ ### ✅ Preserved Features
18
+
19
+ - ✅ Uses default Actionlint output; robust parser maps to structured issues
20
+ - ✅ Filters input files to `/.github/workflows/` paths
21
+ - ✅ Respects workflow discovery through file walking
22
+
23
+ ### ⚠️ Defaults and Notes
24
+
25
+ - ⚠️ No flags by default (portable across versions and platforms)
26
+ - ⚠️ ShellCheck behavior left to upstream defaults
27
+
28
+ ### 🚀 Enhancements
29
+
30
+ - ✅ Normalized output (tables/JSON) via Lintro formatters
31
+ - ✅ Unified CLI and reporting experience
32
+
33
+ ## Usage Comparison
34
+
35
+ ### Core Actionlint
36
+
37
+ ```bash
38
+ actionlint .github/workflows/ci.yml
39
+ actionlint -no-color -format oneline .github/workflows/
40
+ ```
41
+
42
+ ### Lintro Wrapper
43
+
44
+ ```python
45
+ from lintro.tools.implementations.tool_actionlint import ActionlintTool
46
+
47
+ tool = ActionlintTool()
48
+ result = tool.check(["."])
49
+ ```
50
+
51
+ ## ⚠️ Limited/Missing Features
52
+
53
+ - ⚠️ ShellCheck toggles (`-shellcheck`, `-no-shellcheck`) not exposed
54
+ - ⚠️ Config path (`-config-file`) not exposed
55
+ - ⚠️ Rule enable/disable flags not exposed
56
+ - ⚠️ Output formatting flags (`-format`, `-oneline`, color) not exposed
57
+
58
+ ### 🔧 Proposed runtime pass-throughs
59
+
60
+ - `--tool-options actionlint:shellcheck=False`
61
+ - `--tool-options actionlint:config=.actionlint.yaml`
62
+ - `--tool-options actionlint:disable=rule1|rule2`
63
+ - `--tool-options actionlint:format=oneline,actionlint:no_color=True`
64
+
65
+ ## Recommendations
66
+
67
+ - Keep defaults minimal; add pass-throughs where CI or local workflows need
68
+ parity with upstream CLI settings.