repomatic 7.3.0__tar.gz → 7.4.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.
Files changed (168) hide show
  1. {repomatic-7.3.0 → repomatic-7.4.0}/PKG-INFO +4 -7
  2. repomatic-7.4.0/pyproject.toml +337 -0
  3. repomatic-7.3.0/pyproject.toml → repomatic-7.4.0/pyproject.toml.orig +56 -26
  4. {repomatic-7.3.0 → repomatic-7.4.0}/readme.md +0 -4
  5. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/__init__.py +2 -2
  6. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/binaries_page.py +44 -13
  7. repomatic-7.4.0/repomatic/binary.py +493 -0
  8. repomatic-7.4.0/repomatic/bundle.py +67 -0
  9. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/changelog.py +27 -12
  10. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/checksums.py +29 -17
  11. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/cli.py +227 -362
  12. repomatic-7.4.0/repomatic/compat.py +33 -0
  13. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/config.py +37 -4
  14. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/_release-engine.yaml +96 -54
  15. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/action-publish-pypi.yaml +1 -1
  16. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/agent-sphinx-docs.md +149 -60
  17. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/autofix.yaml +101 -89
  18. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/cancel-runs.yaml +3 -3
  19. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/changelog.yaml +26 -24
  20. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/debug.yaml +5 -5
  21. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/docs.yaml +16 -12
  22. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/labels.yaml +18 -18
  23. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/lint.yaml +45 -35
  24. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/lychee.toml +10 -1
  25. repomatic-7.4.0/repomatic/data/pytest.toml +35 -0
  26. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/release.yaml +17 -1
  27. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-babysit-ci.md +11 -3
  28. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-repomatic-audit.md +1 -1
  29. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-repomatic-changelog.md +2 -2
  30. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-repomatic-deps.md +3 -3
  31. repomatic-7.4.0/repomatic/data/skill-repomatic-ship.md +194 -0
  32. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-sphinx-docs-sync.md +15 -6
  33. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/tests.yaml +19 -9
  34. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/typos.toml +2 -2
  35. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/unsubscribe.yaml +3 -3
  36. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/uv.toml +4 -3
  37. repomatic-7.3.0/repomatic/deps_graph.py → repomatic-7.4.0/repomatic/dep_graph.py +7 -6
  38. repomatic-7.4.0/repomatic/dep_report.py +664 -0
  39. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/dep_sources.py +6 -7
  40. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/docs.py +67 -32
  41. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/git_ops.py +77 -0
  42. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/actions.py +24 -15
  43. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/dev_release.py +2 -31
  44. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/issue.py +72 -3
  45. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/pr_body.py +1 -15
  46. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/release_sync.py +8 -13
  47. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/releases.py +35 -5
  48. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/status.py +8 -10
  49. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/token.py +0 -8
  50. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/workflow_sync.py +4 -71
  51. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/gitignore.py +2 -3
  52. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/http.py +71 -3
  53. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/images.py +6 -9
  54. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/init_project.py +14 -222
  55. repomatic-7.4.0/repomatic/labels.py +332 -0
  56. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/lint_repo.py +390 -235
  57. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/mailmap.py +8 -17
  58. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/metadata.py +109 -84
  59. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/npm.py +12 -24
  60. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/prepare_release.py +57 -0
  61. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/pypi.py +14 -37
  62. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/registry.py +3 -3
  63. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/setup_guide.py +28 -9
  64. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/sync_ops.py +164 -105
  65. repomatic-7.4.0/repomatic/templates/setup-guide-sha-pinning-required.md +18 -0
  66. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide.md +3 -1
  67. repomatic-7.3.0/repomatic/templates/update-deps-graph.md → repomatic-7.4.0/repomatic/templates/update-dep-graph.md +1 -1
  68. repomatic-7.3.0/repomatic/tool_runner.py → repomatic-7.4.0/repomatic/tool_registry.py +100 -1015
  69. repomatic-7.4.0/repomatic/tool_runner.py +972 -0
  70. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/tool_runner_page.py +1 -1
  71. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/uv.py +82 -719
  72. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/version_sync.py +10 -28
  73. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/virustotal.py +8 -16
  74. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/vulnerable_deps.py +24 -14
  75. repomatic-7.3.0/repomatic/binary.py +0 -315
  76. repomatic-7.3.0/repomatic/data/pytest.toml +0 -21
  77. repomatic-7.3.0/repomatic/data/skill-repomatic-ship.md +0 -153
  78. repomatic-7.3.0/repomatic/github/pr.py +0 -95
  79. {repomatic-7.3.0 → repomatic-7.4.0}/license +0 -0
  80. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/__main__.py +0 -0
  81. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/broken_links.py +0 -0
  82. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/cache.py +0 -0
  83. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/__init__.py +0 -0
  84. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/agent-grunt-qa.md +0 -0
  85. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/agent-qa-engineer.md +0 -0
  86. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/autolock.yaml +0 -0
  87. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/.github/ISSUE_TEMPLATE/config.yml +0 -0
  88. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/.github/ISSUE_TEMPLATE/new-link.yaml +0 -0
  89. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/.github/code-of-conduct.md +0 -0
  90. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/.github/contributing.md +0 -0
  91. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/.github/contributing.zh.md +0 -0
  92. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/.github/funding.yml +0 -0
  93. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/.github/pull_request_template.md +0 -0
  94. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/__init__.py +0 -0
  95. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/awesome_template/license +0 -0
  96. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/bumpversion.toml +0 -0
  97. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/codecov.yaml +0 -0
  98. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/labeller-content-based.yaml +0 -0
  99. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/labeller-file-based.yaml +0 -0
  100. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/labels.toml +0 -0
  101. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/mdformat.toml +0 -0
  102. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/mypy.toml +0 -0
  103. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/ruff.toml +0 -0
  104. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-av-false-positive.md +0 -0
  105. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-awesome-triage.md +0 -0
  106. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-benchmark-update.md +0 -0
  107. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-brand-assets.md +0 -0
  108. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-file-bug-report.md +0 -0
  109. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-repomatic-init.md +0 -0
  110. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-repomatic-topics.md +0 -0
  111. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-translation-sync.md +0 -0
  112. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/skill-upstream-audit.md +0 -0
  113. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/yamllint.yaml +0 -0
  114. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/data/zizmor.yaml +0 -0
  115. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/__init__.py +0 -0
  116. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/gh.py +0 -0
  117. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/matrix.py +0 -0
  118. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/sponsor.py +0 -0
  119. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/github/unsubscribe.py +0 -0
  120. /repomatic-7.3.0/repomatic/test_matrix.py → /repomatic-7.4.0/repomatic/matrix_axes.py +0 -0
  121. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/py.typed +0 -0
  122. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/pyproject.py +0 -0
  123. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/__init__.py +0 -0
  124. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/available-admonition.md +0 -0
  125. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/broken-links-issue.md +0 -0
  126. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/bump-version.md +0 -0
  127. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/detect-squash-merge.md +0 -0
  128. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/development-warning.md +0 -0
  129. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/fix-changelog.md +0 -0
  130. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/fix-typos.md +0 -0
  131. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/fix-vulnerable-deps.md +0 -0
  132. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/format-images.md +0 -0
  133. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/format-json.md +0 -0
  134. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/format-markdown.md +0 -0
  135. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/format-pyproject.md +0 -0
  136. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/format-python.md +0 -0
  137. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/format-shell.md +0 -0
  138. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/generated-footer.md +0 -0
  139. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/github-releases.md +0 -0
  140. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/immutable-releases.md +0 -0
  141. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/pr-metadata.md.noformat +0 -0
  142. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/prepare-release.md +0 -0
  143. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/refresh-tip.md +0 -0
  144. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/release-notes.md +0 -0
  145. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/release-sync-report.md +0 -0
  146. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-branch-ruleset.md +0 -0
  147. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-dependabot.md +0 -0
  148. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-fork-pr-approval.md +0 -0
  149. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-notifications-pat.md +0 -0
  150. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-pages-source.md +0 -0
  151. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-pypi-trusted-publisher.md +0 -0
  152. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-token.md +0 -0
  153. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-verify.md +0 -0
  154. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/setup-guide-virustotal.md +0 -0
  155. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-action-pins.md +0 -0
  156. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-bumpversion.md +0 -0
  157. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-dep-sources.md +0 -0
  158. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-gitignore.md +0 -0
  159. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-mailmap.md +0 -0
  160. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-repomatic.md +0 -0
  161. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-tool-versions.md +0 -0
  162. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-uv-lock.md +0 -0
  163. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/sync-workflow-pins.md +0 -0
  164. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/unavailable-admonition.md +0 -0
  165. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/unsubscribe-phase1.md +0 -0
  166. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/unsubscribe-phase2.md +0 -0
  167. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/update-docs.md +0 -0
  168. {repomatic-7.3.0 → repomatic-7.4.0}/repomatic/templates/yanked-admonition.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: repomatic
3
- Version: 7.3.0
3
+ Version: 7.4.0
4
4
  Summary: 🏭 Automate repository maintenance, releases, and CI/CD workflows
5
5
  Keywords: changelog-formatter,dependabot-alternative,github-actions,github-labels,github-workflow,gitignore,mailmap,mypy,nuitka,python-automation,release-automation,repository-automation,repository-management,reusable-workflows,software-factory,sphinx-doc,typo,uv,workflow-reusable
6
6
  Author: Kevin Deldycke
@@ -46,10 +46,11 @@ Classifier: Typing :: Typed
46
46
  Requires-Dist: arrow>=1.3
47
47
  Requires-Dist: backports-strenum>=1 ; python_full_version < '3.11'
48
48
  Requires-Dist: boltons>=25
49
- Requires-Dist: click-extra>=8.5
49
+ Requires-Dist: click-extra>=8.8
50
50
  Requires-Dist: extra-platforms>=12.0.2
51
51
  Requires-Dist: packaging>=17
52
52
  Requires-Dist: py-walk>=0.3.1
53
+ Requires-Dist: pyelftools>=0.33
53
54
  Requires-Dist: pyproject-metadata>=0.9
54
55
  Requires-Dist: pyyaml>=6.0.3
55
56
  Requires-Dist: tomlrt>=1.7.6
@@ -58,7 +59,7 @@ Requires-Dist: wcmatch>=10
58
59
  Requires-Python: >=3.10
59
60
  Project-URL: Changelog, https://github.com/kdeldycke/repomatic/blob/main/changelog.md
60
61
  Project-URL: Documentation, https://kdeldycke.github.io/repomatic
61
- Project-URL: Download, https://github.com/kdeldycke/repomatic/releases/tag/v7.3.0
62
+ Project-URL: Download, https://github.com/kdeldycke/repomatic/releases/tag/v7.4.0
62
63
  Project-URL: Funding, https://github.com/sponsors/kdeldycke
63
64
  Project-URL: Homepage, https://github.com/kdeldycke/repomatic
64
65
  Project-URL: Issues, https://github.com/kdeldycke/repomatic/issues
@@ -153,7 +154,3 @@ Check these projects to get real-life examples of usage and inspiration:
153
154
  - ![GitHub stars](https://img.shields.io/github/stars/kdeldycke/extra-platforms?label=%E2%AD%90&style=flat-square) [Extra Platforms](https://github.com/kdeldycke/extra-platforms) - Detect platforms and group them by family.
154
155
 
155
156
  Send a PR to add your project if you use repomatic.
156
-
157
- ## Development
158
-
159
- See `claude.md` for development commands, code style, testing guidelines, and design principles.
@@ -0,0 +1,337 @@
1
+ [build-system]
2
+ build-backend = "uv_build"
3
+ requires = ["uv-build>=0.12"]
4
+
5
+ [project]
6
+ name = "repomatic"
7
+ version = "7.4.0"
8
+ description = "🏭 Automate repository maintenance, releases, and CI/CD workflows"
9
+ readme = "readme.md"
10
+ keywords = [
11
+ "changelog-formatter",
12
+ "dependabot-alternative",
13
+ "github-actions",
14
+ "github-labels",
15
+ "github-workflow",
16
+ "gitignore",
17
+ "mailmap",
18
+ "mypy",
19
+ "nuitka",
20
+ "python-automation",
21
+ "release-automation",
22
+ "repository-automation",
23
+ "repository-management",
24
+ "reusable-workflows",
25
+ "software-factory",
26
+ "sphinx-doc",
27
+ "typo",
28
+ "uv",
29
+ "workflow-reusable",
30
+ ]
31
+ license = "GPL-2.0-or-later"
32
+ license-files = ["license"]
33
+ requires-python = ">=3.10"
34
+ classifiers = [
35
+ "Development Status :: 5 - Production/Stable",
36
+ "Environment :: Console",
37
+ "Framework :: Sphinx",
38
+ "Intended Audience :: Developers",
39
+ "Operating System :: MacOS :: MacOS X",
40
+ "Operating System :: Microsoft :: Windows",
41
+ "Operating System :: POSIX :: BSD :: FreeBSD",
42
+ "Operating System :: POSIX :: BSD :: NetBSD",
43
+ "Operating System :: POSIX :: BSD :: OpenBSD",
44
+ "Operating System :: POSIX :: Linux",
45
+ "Programming Language :: Python :: 3 :: Only",
46
+ "Programming Language :: Python :: 3.10",
47
+ "Programming Language :: Python :: 3.11",
48
+ "Programming Language :: Python :: 3.12",
49
+ "Programming Language :: Python :: 3.13",
50
+ "Programming Language :: Python :: 3.14",
51
+ "Programming Language :: Python :: Implementation :: CPython",
52
+ "Programming Language :: Unix Shell",
53
+ "Topic :: Documentation :: Sphinx",
54
+ "Topic :: File Formats :: JSON",
55
+ "Topic :: Security",
56
+ "Topic :: Software Development :: Build Tools",
57
+ "Topic :: Software Development :: Compilers",
58
+ "Topic :: Software Development :: Documentation",
59
+ "Topic :: Software Development :: Libraries :: Python Modules",
60
+ "Topic :: Software Development :: Quality Assurance",
61
+ "Topic :: Software Development :: Version Control :: Git",
62
+ "Topic :: System :: Archiving :: Packaging",
63
+ "Topic :: System :: Installation/Setup",
64
+ "Topic :: System :: Shells",
65
+ "Topic :: System :: Software Distribution",
66
+ "Topic :: Terminals",
67
+ "Topic :: Text Processing :: Markup :: HTML",
68
+ "Topic :: Text Processing :: Markup :: Markdown",
69
+ "Topic :: Utilities",
70
+ "Typing :: Typed",
71
+ ]
72
+ dependencies = [
73
+ "arrow>=1.3",
74
+ "backports-strenum>=1; python_version<'3.11'",
75
+ "boltons>=25",
76
+ "click-extra>=8.8",
77
+ "extra-platforms>=12.0.2",
78
+ "packaging>=17",
79
+ "py-walk>=0.3.1",
80
+ "pyelftools>=0.33",
81
+ "pyproject-metadata>=0.9",
82
+ "pyyaml>=6.0.3",
83
+ "tomlrt>=1.7.6",
84
+ "vt-py>=0.18",
85
+ "wcmatch>=10",
86
+ ]
87
+
88
+ [[project.authors]]
89
+ name = "Kevin Deldycke"
90
+ email = "kevin@deldycke.com"
91
+
92
+ [project.urls]
93
+ Changelog = "https://github.com/kdeldycke/repomatic/blob/main/changelog.md"
94
+ Documentation = "https://kdeldycke.github.io/repomatic"
95
+ Download = "https://github.com/kdeldycke/repomatic/releases/tag/v7.4.0"
96
+ Funding = "https://github.com/sponsors/kdeldycke"
97
+ Homepage = "https://github.com/kdeldycke/repomatic"
98
+ Issues = "https://github.com/kdeldycke/repomatic/issues"
99
+ Repository = "https://github.com/kdeldycke/repomatic"
100
+
101
+ [project.scripts]
102
+ repomatic = "repomatic.__main__:main"
103
+
104
+ [dependency-groups]
105
+ test = [
106
+ "coverage[toml]>=7.11",
107
+ "pytest>=9",
108
+ "pytest-cov>=4",
109
+ "pytest-github-actions-annotate-failures>=0.2",
110
+ "pytest-randomly>=3",
111
+ "pytest-xdist[psutil]>=3.7",
112
+ ]
113
+ docs = [
114
+ "click-extra[sphinx]",
115
+ "furo>=2025.9.25",
116
+ "myst-parser>=5.1",
117
+ "sphinx>=8",
118
+ "sphinx-autodoc-typehints>=2.4",
119
+ "sphinx-copybutton>=0.5.2",
120
+ "sphinx-datatables>=1",
121
+ "sphinx-design>=0.6",
122
+ "sphinxcontrib-mermaid>=1.2.3",
123
+ "sphinxext-opengraph>=0.13",
124
+ ]
125
+ typing = [
126
+ "backports-strenum>=1",
127
+ "types-boltons>=25.0.0.20250822",
128
+ "types-docutils>=0.22.3.20251115",
129
+ "types-pyyaml>=6.0.12.9",
130
+ ]
131
+
132
+ [tool.uv]
133
+ required-version = ">=0.12"
134
+ exclude-newer = "1 week"
135
+
136
+ [tool.uv.dependency-groups.docs]
137
+ requires-python = ">= 3.14"
138
+
139
+ [tool.uv.exclude-newer-package]
140
+ click-extra = "2026-08-02T00:00:00Z"
141
+ extra-platforms = "2026-07-28T00:00:00Z"
142
+ repomatic = "0 day"
143
+
144
+ [tool.uv.build-backend]
145
+ module-root = ""
146
+
147
+ [tool.nuitka]
148
+ copyright = "Kevin Deldycke <kevin@deldycke.com> and contributors. Distributed under GPL-2.0-or-later license."
149
+ file-description = "🏭 Automate repository maintenance, releases, and CI/CD workflows"
150
+ file-version = "7.4.0"
151
+ include-data-dir = ["repomatic/data/awesome_template=repomatic/data/awesome_template"]
152
+ include-data-files = ["repomatic/templates/*.md=repomatic/templates/"]
153
+ include-package-data = ["click_extra"]
154
+ linux-icon = "docs/assets/icon.png"
155
+ macos-app-icon = "docs/assets/icon.icns"
156
+ product-name = "Repomatic"
157
+ product-version = "7.4.0"
158
+ windows-icon-from-ico = "docs/assets/icon.ico"
159
+
160
+ [tool.ruff]
161
+ preview = true
162
+ fix = true
163
+ unsafe-fixes = false
164
+ show-fixes = true
165
+
166
+ [tool.ruff.format]
167
+ docstring-code-format = true
168
+
169
+ [tool.ruff.lint]
170
+ extend-select = ["PLW1514"]
171
+ ignore = [
172
+ "D400",
173
+ "ERA001",
174
+ "LOG015",
175
+ ]
176
+ future-annotations = true
177
+
178
+ [tool.ruff.lint.isort]
179
+ combine-as-imports = true
180
+
181
+ [tool.typos.default]
182
+ extend-ignore-re = [
183
+ "(?s)<!-- typos:off -->.*?<!-- typos:on -->",
184
+ '\{qeury\}',
185
+ 'base32 "[0-9a-z]{52}"',
186
+ ]
187
+ extend-ignore-identifiers-re = [
188
+ "certifi",
189
+ "nwo",
190
+ "vulnerabilit",
191
+ "WARNIN",
192
+ ]
193
+
194
+ [tool.typos.default.extend-identifiers]
195
+ Github = "GitHub"
196
+ IOS = "iOS"
197
+ Javascript = "JavaScript"
198
+ MacOS = "macOS"
199
+ PNGs = "PNGs"
200
+ PyPi = "PyPI"
201
+ Typescript = "TypeScript"
202
+
203
+ [tool.typos.default.extend-words]
204
+ astroid = "astroid"
205
+ oject = "oject"
206
+ PNGs = "PNGs"
207
+ sur = "sur"
208
+
209
+ [tool.mypy]
210
+ mypy_path = "docs"
211
+ check_untyped_defs = true
212
+ warn_redundant_casts = true
213
+ warn_unused_ignores = true
214
+ warn_return_any = true
215
+ warn_unreachable = true
216
+ pretty = true
217
+ warn_unused_configs = true
218
+
219
+ [[tool.mypy.overrides]]
220
+ module = [
221
+ "py_walk.*",
222
+ "sphinxcontrib.mermaid",
223
+ "vt",
224
+ ]
225
+ ignore_missing_imports = true
226
+
227
+ [tool.pytest]
228
+ addopts = [
229
+ "--durations=10",
230
+ "--cov",
231
+ "--cov-report=term",
232
+ "--numprocesses=auto",
233
+ "--import-mode=importlib",
234
+ ]
235
+ markers = ["once: Tests that only need to run once, not across the full CI matrix."]
236
+ testpaths = ["tests"]
237
+ xfail_strict = true
238
+
239
+ [tool.coverage.run]
240
+ branch = true
241
+ source = ["repomatic"]
242
+
243
+ [tool.coverage.report]
244
+ precision = 2
245
+
246
+ [tool.bumpversion]
247
+ current_version = "7.4.0"
248
+ parse = '(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.dev(?P<dev>\d+))?'
249
+ serialize = [
250
+ "{major}.{minor}.{patch}.dev{dev}",
251
+ "{major}.{minor}.{patch}",
252
+ ]
253
+ ignore_missing_files = true
254
+ allow_dirty = true
255
+
256
+ [tool.bumpversion.parts.dev]
257
+ optional_value = "release"
258
+ values = [
259
+ "0",
260
+ "release",
261
+ ]
262
+
263
+ [[tool.bumpversion.files]]
264
+ glob = "./**/__init__.py"
265
+ ignore_missing_version = true
266
+
267
+ [[tool.bumpversion.files]]
268
+ filename = "./pyproject.toml"
269
+ regex = true
270
+ search = '(?m)^version = "{current_version}"'
271
+ replace = 'version = "{new_version}"'
272
+
273
+ [[tool.bumpversion.files]]
274
+ filename = "./pyproject.toml"
275
+ search = "releases/tag/v{current_version}"
276
+ replace = "releases/tag/v{new_version}"
277
+
278
+ [[tool.bumpversion.files]]
279
+ filename = "./pyproject.toml"
280
+ ignore_missing_version = true
281
+ serialize = ["{major}.{minor}.{patch}"]
282
+ search = '-version = "{current_version}"'
283
+ replace = '-version = "{new_version}"'
284
+
285
+ [[tool.bumpversion.files]]
286
+ filename = "./changelog.md"
287
+ search = "## [`{current_version}` (unreleased)]("
288
+ replace = "## [`{new_version}` (unreleased)]("
289
+
290
+ [[tool.bumpversion.files]]
291
+ filename = "./citation.cff"
292
+ regex = true
293
+ search = "(?m)^version: {current_version}"
294
+ replace = "version: {new_version}"
295
+
296
+ [[tool.bumpversion.files]]
297
+ filename = "./citation.cff"
298
+ regex = true
299
+ search = 'date-released: \d{{4}}-\d{{2}}-\d{{2}}'
300
+ replace = "date-released: {utcnow:%Y-%m-%d}"
301
+
302
+ [tool.lychee]
303
+ exclude = [
304
+ "^https://github.com/.+/issues/[0-9]+#issuecomment-.*$",
305
+ "^https://github.com/.+/releases/.+/download/.*$",
306
+ "^https://doi.org/.+/zenodo.*$",
307
+ 'bitdefender\.com',
308
+ 'archive\.ph',
309
+ '^https://www\.npmjs\.com/package/.*$',
310
+ '^https://www\.virustotal\.com/gui/.*$',
311
+ '^https://star-history\.com/.*$',
312
+ 'githubstatus\.com',
313
+ '^file://.*/docs/[\w.-]+\.md#',
314
+ ]
315
+ exclude_path = ["repomatic/templates/"]
316
+
317
+ [tool.repomatic]
318
+ abandoned-versions = [
319
+ "4.1.0",
320
+ "4.6.1",
321
+ "4.7.0",
322
+ "4.8.0",
323
+ "5.0.0",
324
+ "6.0.0",
325
+ "6.18.0",
326
+ ]
327
+ exclude = ["workflows"]
328
+ pypi-package-history = [
329
+ "gha-utils",
330
+ "repokit",
331
+ ]
332
+
333
+ [tool.repomatic.changelog]
334
+ archive-location = "./docs/changelog-archive.md"
335
+
336
+ [tool.repomatic.manpages]
337
+ script = "repomatic.cli:repomatic"
@@ -1,11 +1,18 @@
1
1
  [build-system]
2
2
  build-backend = "uv_build"
3
- requires = [ "uv-build>=0.9,<0.12" ]
3
+ # uv-build is intentionally left uncapped. uv warns on build that the sdist
4
+ # could break on a future breaking uv-build release, but repomatic is pure
5
+ # Python with none of the packaging edge cases that warning guards against (no
6
+ # compiled extensions, no GPU/CUDA targets). Flexibility is preferred here:
7
+ # repomatic runs across the ecosystem, where uv versions drift between projects,
8
+ # and a hard ceiling risks a chicken-and-egg deadlock when one project's uv
9
+ # moves ahead of repomatic's next release.
10
+ requires = [ "uv-build>=0.12" ]
4
11
 
5
12
  [project]
6
13
  # Docs: https://packaging.python.org/en/latest/guides/writing-pyproject-toml/
7
14
  name = "repomatic"
8
- version = "7.3.0"
15
+ version = "7.4.0"
9
16
  description = "🏭 Automate repository maintenance, releases, and CI/CD workflows"
10
17
  readme = "readme.md"
11
18
  keywords = [
@@ -84,16 +91,21 @@ dependencies = [
84
91
  "backports-strenum>=1; python_version<'3.11'",
85
92
  # boltons 25.0.0 dropped Python 3.9, matching our requires-python >= 3.10.
86
93
  "boltons>=25",
87
- # click-extra 8.5 ships the `python:render` `:mirror:` regions and extends
88
- # `refresh-directives` to refresh them (update_mirror_blocks), with the
89
- # fence-aware scanner that stops `update-docs` phase 4 from rewriting
90
- # examples nested in code fences. 8.5 also carries the
91
- # `make_schema_callable(warn_unknown=...)` unknown-key warning
92
- # `load_repomatic_config` opts into, and the `click_extra.sphinx.
93
- # myst_docstrings` extension `docs/conf.py` loads (absorbed from
94
- # `repomatic.myst_docstrings`). (8.3 brought the `click:config` directive
95
- # and `schema_field_infos()` that `configuration.md` and `show-config` use.)
96
- "click-extra>=8.5",
94
+ # click-extra 8.8.0 is the floor: repomatic delegates to the utilities absorbed
95
+ # there — `format_size` (byte sizes in the image and cache reports), the
96
+ # `parse_duration`/`parse_friendly_duration`/`parse_iso8601_duration` family
97
+ # (uv cooldown spans in `uv.py`/`version_sync.py`), `prep_path`/`is_stdout`
98
+ # (CLI `--output` handling), and `config_table_to_flags` (tool flag
99
+ # translation). Earlier floors remain in play: `binaries_page` imports
100
+ # `click_extra.blocks` (`replace_region`, 8.7.1) to splice the binaries page
101
+ # chart region; `OperationTrail` and `resolve_jobs` (8.6.0) render the `sync-*`
102
+ # resolve trail; the `{matrix}` newest-first default (8.6.0) backs the committed
103
+ # Python-compatibility table in `docs/install.md`; the `python:render`
104
+ # `:mirror:` regions (8.5) drive the `update-docs` phase 4 refresh, and
105
+ # `click_extra.sphinx.myst_docstrings` (8.5, absorbed from
106
+ # `repomatic.myst_docstrings`) is loaded by `docs/conf.py`; `click:config`
107
+ # and `schema_field_infos()` (8.3) back `configuration.md` and `show-config`.
108
+ "click-extra>=8.8",
97
109
  # extra-platforms 12.0.2 reimplemented is_macos() with sys.platform, avoiding
98
110
  # the platform.platform() shell-out to ``cmd /c ver`` on Windows that broke
99
111
  # under patched subprocess in tests and triggered a CPython 3.10.x bug.
@@ -105,6 +117,11 @@ dependencies = [
105
117
  # XXX Replace py-walk with wcmatch once the latter supports gitignore files:
106
118
  # https://github.com/facelessuser/wcmatch/issues/226
107
119
  "py-walk>=0.3.1",
120
+ # pyelftools parses the ELF headers of compiled binaries, so verify-binary can
121
+ # check architectures and glibc floors natively, inside manylinux containers,
122
+ # without installing exiftool. 0.33 is the first release to declare
123
+ # requires-python (>= 3.10, matching ours); earlier ones carry no guard.
124
+ "pyelftools>=0.33",
108
125
  # pyproject-metadata 0.9 added PEP 639 (license expressions) and PEP 685 (extras
109
126
  # normalization); our StandardMetadata.from_pyproject() call benefits from these.
110
127
  "pyproject-metadata>=0.9",
@@ -128,7 +145,7 @@ dependencies = [
128
145
  ]
129
146
  urls.Changelog = "https://github.com/kdeldycke/repomatic/blob/main/changelog.md"
130
147
  urls.Documentation = "https://kdeldycke.github.io/repomatic"
131
- urls.Download = "https://github.com/kdeldycke/repomatic/releases/tag/v7.3.0"
148
+ urls.Download = "https://github.com/kdeldycke/repomatic/releases/tag/v7.4.0"
132
149
  urls.Funding = "https://github.com/sponsors/kdeldycke"
133
150
  urls.Homepage = "https://github.com/kdeldycke/repomatic"
134
151
  urls.Issues = "https://github.com/kdeldycke/repomatic/issues"
@@ -191,14 +208,15 @@ typing = [
191
208
  ]
192
209
 
193
210
  [tool.uv]
194
- # Pin uv to the 0.11 series so every contributor and CI runner resolves
195
- # uv.lock with the same resolver. astral-sh/setup-uv reads this automatically
196
- # (its `version` input defaults to the pyproject value), and uv enforces it on
197
- # every local invocation. Together with sync-uv-lock discarding cosmetic-only
198
- # re-locks (see repomatic.uv.sync_uv_lock), this stops uv.lock from
199
- # ping-ponging between machines that re-spell equivalent markers differently.
200
- # Bump the ceiling once a new uv minor has regenerated the lock.
201
- required-version = ">=0.11.23,<0.12"
211
+ # Floor uv at the minimum resolver repomatic relies on, with no upper bound.
212
+ # astral-sh/setup-uv reads this automatically (its `version` input defaults to
213
+ # the pyproject value) and installs the newest uv satisfying it, so CI and
214
+ # contributors move forward without a manual ceiling bump each minor (a hard
215
+ # upper cap breaks every machine the day the next uv minor lands, since uv
216
+ # self-updates). uv.lock stays stable across minors because sync-uv-lock
217
+ # discards a re-lock that only re-spells equivalent markers (see
218
+ # repomatic.uv.sync_uv_lock).
219
+ required-version = ">=0.12"
202
220
  # Docs group requires Python >= 3.14 for recent MyST-Parser and click-extra features.
203
221
  dependency-groups.docs = { requires-python = ">= 3.14" }
204
222
  # Cooldown period: 7-day buffer before using newly released packages.
@@ -212,7 +230,7 @@ exclude-newer = "1 week"
212
230
  # `exclude-newer`, returning the package to the normal cooldown. repomatic is
213
231
  # pinned to git main (no PyPI release to freeze), so it keeps a permanent
214
232
  # "0 day" span.
215
- exclude-newer-package = { click-extra = "2026-07-24T00:00:00Z", repomatic = "0 day" }
233
+ exclude-newer-package = { click-extra = "2026-08-02T00:00:00Z", extra-platforms = "2026-07-28T00:00:00Z", repomatic = "0 day" }
216
234
  # Package is at root level, not in "./src/".
217
235
  build-backend.module-root = ""
218
236
 
@@ -225,7 +243,7 @@ copyright = "Kevin Deldycke <kevin@deldycke.com> and contributors. Distributed u
225
243
  file-description = "🏭 Automate repository maintenance, releases, and CI/CD workflows"
226
244
  # Numeric only: Nuitka rejects PEP 440 .devN suffixes. Kept in sync with the
227
245
  # package version by the dedicated [tool.bumpversion] rule that strips the suffix.
228
- file-version = "7.3.0"
246
+ file-version = "7.4.0"
229
247
  include-data-dir = [
230
248
  "repomatic/data/awesome_template=repomatic/data/awesome_template",
231
249
  ]
@@ -243,7 +261,7 @@ include-package-data = [ "click_extra" ]
243
261
  linux-icon = "docs/assets/icon.png"
244
262
  macos-app-icon = "docs/assets/icon.icns"
245
263
  product-name = "Repomatic"
246
- product-version = "7.3.0"
264
+ product-version = "7.4.0"
247
265
  windows-icon-from-ico = "docs/assets/icon.ico"
248
266
 
249
267
  [tool.ruff]
@@ -281,7 +299,7 @@ lint.future-annotations = true
281
299
  [tool.typos]
282
300
  default.extend-identifiers = { Github = "GitHub", IOS = "iOS", Javascript = "JavaScript", MacOS = "macOS", PNGs = "PNGs", PyPi = "PyPI", Typescript = "TypeScript" }
283
301
  # False positives.
284
- default.extend-words = { astroid = "astroid", oject = "oject", PNGs = "PNGs" }
302
+ default.extend-words = { astroid = "astroid", oject = "oject", PNGs = "PNGs", sur = "sur" }
285
303
  # Skip content between <!-- typos:off --> and <!-- typos:on --> markers.
286
304
  default.extend-ignore-re = [
287
305
  "(?s)<!-- typos:off -->.*?<!-- typos:on -->",
@@ -343,11 +361,18 @@ addopts = [
343
361
  "--cov",
344
362
  "--cov-report=term",
345
363
  "--numprocesses=auto",
364
+ # Import test modules via importlib instead of prepending their root dir to
365
+ # sys.path. Avoids "import file mismatch" collection errors when an installed
366
+ # copy of the package coexists with the source tree, as in distro builds.
367
+ "--import-mode=importlib",
346
368
  ]
347
369
  # https://docs.pytest.org/en/latest/customize.html#pyproject-toml
348
370
  markers = [
349
371
  "once: Tests that only need to run once, not across the full CI matrix.",
350
372
  ]
373
+ # Restrict collection to the test suite, so pytest never descends into the
374
+ # package or an installed copy of it in dual-copy builds.
375
+ testpaths = [ "tests" ]
351
376
  # Make sure tests that are expected to fail do not resurrect and start working all of a sudden.
352
377
  xfail_strict = true
353
378
 
@@ -358,7 +383,7 @@ run.source = [ "repomatic" ]
358
383
  report.precision = 2
359
384
 
360
385
  [tool.bumpversion]
361
- current_version = "7.3.0"
386
+ current_version = "7.4.0"
362
387
  # Parse versions with an optional .devN suffix (PEP 440).
363
388
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)(\\.dev(?P<dev>\\d+))?"
364
389
  serialize = [
@@ -475,4 +500,9 @@ abandoned-versions = [
475
500
  ]
476
501
  changelog.archive-location = "./docs/changelog-archive.md"
477
502
  exclude = [ "workflows" ]
503
+ # Render the Click command tree as roff `.1` files and attach a
504
+ # `repomatic-manpages.tar.gz` asset to every GitHub release. The script target
505
+ # mirrors `click_extra_manpages` in `docs/conf.py`, so the release tarball and
506
+ # the HTML docs site stay in lockstep.
507
+ manpages.script = "repomatic.cli:repomatic"
478
508
  pypi-package-history = [ "gha-utils", "repokit" ]
@@ -86,7 +86,3 @@ Check these projects to get real-life examples of usage and inspiration:
86
86
  - ![GitHub stars](https://img.shields.io/github/stars/kdeldycke/extra-platforms?label=%E2%AD%90&style=flat-square) [Extra Platforms](https://github.com/kdeldycke/extra-platforms) - Detect platforms and group them by family.
87
87
 
88
88
  Send a PR to add your project if you use repomatic.
89
-
90
- ## Development
91
-
92
- See `claude.md` for development commands, code style, testing guidelines, and design principles.
@@ -17,5 +17,5 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = "7.3.0"
21
- __git_tag_sha__ = "2b89c62f0953d8ef59d0d023085a9323f6c32f1d"
20
+ __version__ = "7.4.0"
21
+ __git_tag_sha__ = "730a6caca5226f9b3c80c238504310c5dad86993"
@@ -55,6 +55,7 @@ import json
55
55
  import logging
56
56
  from pathlib import Path
57
57
 
58
+ from click_extra.blocks import replace_region
58
59
  from packaging.version import InvalidVersion, Version
59
60
 
60
61
  from .binary import NUITKA_BUILD_TARGETS
@@ -96,10 +97,34 @@ warning tint; from one engine in ten upward, the release deserves a
96
97
  false-positive submission round (see the `/av-false-positive` skill).
97
98
  """
98
99
 
99
- PAGE_END_MARKER = "<!-- binaries-end -->"
100
+ LEGACY_PAGE_END_MARKER = "<!-- binaries-end -->"
101
+ """Oldest closing marker, migrated to {data}`PAGE_END_MARKER` on first touch."""
102
+
103
+ LEGACY_PAGE_START_MARKERS = (
104
+ "<!-- binaries-start -->",
105
+ "<!-- binaries-chart-start -->",
106
+ )
107
+ """Superseded opening markers, migrated to {data}`PAGE_START_MARKER` on first touch.
108
+
109
+ Two generations precede the current bare open: the original
110
+ `<!-- binaries-start -->`, then the `<!-- binaries-chart-start -->` of the
111
+ short-lived `-start`/`-end` pair. Both collapse to {data}`PAGE_START_MARKER`, so
112
+ a page written by any past version refreshes cleanly.
113
+ """
114
+
115
+ PAGE_REGION = "binaries-chart"
116
+ """Region name spliced by {func}`click_extra.blocks.replace_region`.
117
+
118
+ The generated chart lives between the `<!-- binaries-chart -->` and
119
+ `<!-- binaries-chart-end -->` markers that {data}`PAGE_START_MARKER` and
120
+ {data}`PAGE_END_MARKER` spell out, following click-extra's
121
+ `<!-- name --> / <!-- name-end -->` marker grammar with `name` = this value.
122
+ """
123
+
124
+ PAGE_END_MARKER = f"<!-- {PAGE_REGION}-end -->"
100
125
  """Closing marker of the generated chart region in the binaries page."""
101
126
 
102
- PAGE_START_MARKER = "<!-- binaries-start -->"
127
+ PAGE_START_MARKER = f"<!-- {PAGE_REGION} -->"
103
128
  """Opening marker of the generated chart region in the binaries page."""
104
129
 
105
130
  PAGE_TEMPLATE = """\
@@ -111,15 +136,17 @@ orphan: true
111
136
 
112
137
  All standalone executables published by this repository, one row per binary, newest release first. The version links to its GitHub release, the platform to the direct binary download, and the VirusTotal cell to the file's public analysis.
113
138
 
139
+ Each target's minimum OS requirement (glibc floor on Linux, deployment target on macOS) and the distributions it opens execution to are documented in the [repomatic binaries page](https://kdeldycke.github.io/repomatic/binaries.html#minimum-os-requirements).
140
+
114
141
  Compiled Python binaries are regularly flagged by heuristic antivirus engines, so every release is submitted to [VirusTotal](https://www.virustotal.com/): this seeds vendor databases with the new signatures and keeps false positives in check. The VirusTotal cell tracks those false positives: a green check marks binaries no engine flags, and flagged binaries show the share of engine verdicts flagging them, snapshotted minutes after publication and before false-positive reports get processed. The live analysis behind the link supersedes it.
115
142
 
116
143
  ## Development builds
117
144
 
118
145
  Fresh binaries are compiled from every push to the default branch by the [release workflow]({repo_url}/actions/workflows/release.yaml). To try the latest development build: open the most recent successful run and download the artifact matching your platform (a GitHub account is required, and the binary comes wrapped in a zip). The same builds are also attached to a rolling dev pre-release, a draft only visible to repository maintainers.
119
146
 
120
- <!-- binaries-start -->
147
+ <!-- binaries-chart -->
121
148
 
122
- <!-- binaries-end -->
149
+ <!-- binaries-chart-end -->
123
150
 
124
151
  ## Catalog
125
152
 
@@ -427,8 +454,11 @@ def update_binaries_page(page_path: Path, chart_section: str, repo_slug: str) ->
427
454
 
428
455
  A missing page is created (with parent directories) from
429
456
  {data}`PAGE_TEMPLATE`. On an existing page only the region between
430
- {data}`PAGE_START_MARKER` and {data}`PAGE_END_MARKER` is replaced,
431
- leaving all surrounding prose untouched.
457
+ {data}`PAGE_START_MARKER` and {data}`PAGE_END_MARKER` is replaced by
458
+ {func}`click_extra.blocks.replace_region`, leaving all surrounding prose
459
+ untouched. Pages carrying any {data}`LEGACY_PAGE_START_MARKERS` open or the
460
+ {data}`LEGACY_PAGE_END_MARKER` close are migrated to the current markers in
461
+ the same pass.
432
462
 
433
463
  :param page_path: Path to the Markdown page.
434
464
  :param chart_section: Rendered chart from {func}`render_chart_section`,
@@ -443,20 +473,21 @@ def update_binaries_page(page_path: Path, chart_section: str, repo_slug: str) ->
443
473
  original = None
444
474
  if page_path.exists():
445
475
  original = page_path.read_text(encoding="UTF-8")
446
- if PAGE_START_MARKER not in original or PAGE_END_MARKER not in original:
476
+ # Migrate pages written before the marker grammar aligned on
477
+ # click-extra's bare `<!-- name -->` open.
478
+ text = original
479
+ for legacy_open in LEGACY_PAGE_START_MARKERS:
480
+ text = text.replace(legacy_open, PAGE_START_MARKER)
481
+ text = text.replace(LEGACY_PAGE_END_MARKER, PAGE_END_MARKER)
482
+ if PAGE_START_MARKER not in text or PAGE_END_MARKER not in text:
447
483
  raise ValueError(
448
484
  f"{page_path} lacks the {PAGE_START_MARKER} / {PAGE_END_MARKER} "
449
485
  "markers, refusing to overwrite it."
450
486
  )
451
- text = original
452
487
  else:
453
488
  text = PAGE_TEMPLATE.replace("{repo_url}", f"https://github.com/{repo_slug}")
454
489
 
455
- before, rest = text.split(PAGE_START_MARKER, 1)
456
- _, after = rest.split(PAGE_END_MARKER, 1)
457
- section = chart_section.strip()
458
- between = f"\n\n{section}\n\n" if section else "\n\n"
459
- new_text = before + PAGE_START_MARKER + between + PAGE_END_MARKER + after
490
+ new_text = replace_region(text, PAGE_REGION, chart_section.strip())
460
491
 
461
492
  if new_text == original:
462
493
  logging.info(f"Binaries page {page_path} already up to date.")