dermestes 0.1.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 (320) hide show
  1. dermestes-0.1.0/.claude/settings.json +2 -0
  2. dermestes-0.1.0/.claude/skills/rust-review/SKILL.md +155 -0
  3. dermestes-0.1.0/.github/dependabot.yml +26 -0
  4. dermestes-0.1.0/.github/workflows/audit.yml +29 -0
  5. dermestes-0.1.0/.github/workflows/cargo-deny.yml +35 -0
  6. dermestes-0.1.0/.github/workflows/codeql.yml +42 -0
  7. dermestes-0.1.0/.github/workflows/docs.yml +63 -0
  8. dermestes-0.1.0/.github/workflows/release.yml +114 -0
  9. dermestes-0.1.0/.github/workflows/review.yml +74 -0
  10. dermestes-0.1.0/.gitignore +78 -0
  11. dermestes-0.1.0/CLAUDE.md +89 -0
  12. dermestes-0.1.0/Cargo.lock +754 -0
  13. dermestes-0.1.0/Cargo.toml +95 -0
  14. dermestes-0.1.0/LICENSE +21 -0
  15. dermestes-0.1.0/Makefile +80 -0
  16. dermestes-0.1.0/PKG-INFO +79 -0
  17. dermestes-0.1.0/README.md +54 -0
  18. dermestes-0.1.0/clippy.toml +10 -0
  19. dermestes-0.1.0/deny.toml +27 -0
  20. dermestes-0.1.0/docs/adr/README.md +11 -0
  21. dermestes-0.1.0/docs/book.toml +23 -0
  22. dermestes-0.1.0/docs/custom.css +260 -0
  23. dermestes-0.1.0/docs/dev/ARCHITECTURE.md +56 -0
  24. dermestes-0.1.0/docs/gen-version.sh +34 -0
  25. dermestes-0.1.0/docs/generate-llms-txt.sh +58 -0
  26. dermestes-0.1.0/docs/inject-shared.sh +100 -0
  27. dermestes-0.1.0/docs/lint-mermaid.mjs +76 -0
  28. dermestes-0.1.0/docs/mermaid-init.js +45 -0
  29. dermestes-0.1.0/docs/mermaid.min.js +2609 -0
  30. dermestes-0.1.0/docs/package-lock.json +173 -0
  31. dermestes-0.1.0/docs/package.json +10 -0
  32. dermestes-0.1.0/docs/plans/BUILD_PROMPT_FIXES4.md +94 -0
  33. dermestes-0.1.0/docs/plans/BUILD_PROMPT_PHASE1.md +73 -0
  34. dermestes-0.1.0/docs/plans/BUILD_PROMPT_PHASE2.md +164 -0
  35. dermestes-0.1.0/docs/plans/BUILD_PROMPT_PHASE3.md +175 -0
  36. dermestes-0.1.0/docs/plans/BUILD_PROMPT_PHASE5.md +143 -0
  37. dermestes-0.1.0/docs/plans/BUILD_PROMPT_RECALL.md +97 -0
  38. dermestes-0.1.0/docs/plans/CONSTITUTION.md +290 -0
  39. dermestes-0.1.0/docs/plans/PHASE1_PLAN.md +13 -0
  40. dermestes-0.1.0/docs/shared/claude-snippet.md +6 -0
  41. dermestes-0.1.0/docs/src/SUMMARY.md +9 -0
  42. dermestes-0.1.0/docs/src/guide/setup.md +27 -0
  43. dermestes-0.1.0/docs/src/guide/triage.md +59 -0
  44. dermestes-0.1.0/docs/src/guide/tune.md +57 -0
  45. dermestes-0.1.0/docs/src/index.md +25 -0
  46. dermestes-0.1.0/docs/theme/head.hbs +3 -0
  47. dermestes-0.1.0/docs/toolchain.sh +69 -0
  48. dermestes-0.1.0/docs/version.js +24 -0
  49. dermestes-0.1.0/fixtures/const-param/flag/classmethod_call/cfg.py +8 -0
  50. dermestes-0.1.0/fixtures/const-param/flag/classmethod_call/expected.txt +4 -0
  51. dermestes-0.1.0/fixtures/const-param/flag/default_never_passed/db.py +6 -0
  52. dermestes-0.1.0/fixtures/const-param/flag/default_never_passed/expected.txt +4 -0
  53. dermestes-0.1.0/fixtures/const-param/flag/explicit_exclude_not_counted/expected.txt +5 -0
  54. dermestes-0.1.0/fixtures/const-param/flag/explicit_exclude_not_counted/pkg/app.py +5 -0
  55. dermestes-0.1.0/fixtures/const-param/flag/explicit_exclude_not_counted/pkg/core.py +2 -0
  56. dermestes-0.1.0/fixtures/const-param/flag/explicit_exclude_not_counted/pyproject.toml +2 -0
  57. dermestes-0.1.0/fixtures/const-param/flag/explicit_exclude_not_counted/vendor/use.py +3 -0
  58. dermestes-0.1.0/fixtures/const-param/flag/fstring_call/expected.txt +4 -0
  59. dermestes-0.1.0/fixtures/const-param/flag/fstring_call/state.py +6 -0
  60. dermestes-0.1.0/fixtures/const-param/flag/grouped_params/expected.txt +7 -0
  61. dermestes-0.1.0/fixtures/const-param/flag/grouped_params/images.py +12 -0
  62. dermestes-0.1.0/fixtures/const-param/flag/ignored_decorator/expected.txt +4 -0
  63. dermestes-0.1.0/fixtures/const-param/flag/ignored_decorator/m.py +10 -0
  64. dermestes-0.1.0/fixtures/const-param/flag/ignored_decorator/pyproject.toml +2 -0
  65. dermestes-0.1.0/fixtures/const-param/flag/import_alias/app.py +6 -0
  66. dermestes-0.1.0/fixtures/const-param/flag/import_alias/expected.txt +4 -0
  67. dermestes-0.1.0/fixtures/const-param/flag/import_alias/tools/__init__.py +0 -0
  68. dermestes-0.1.0/fixtures/const-param/flag/import_alias/tools/text.py +2 -0
  69. dermestes-0.1.0/fixtures/const-param/flag/init_call/expected.txt +4 -0
  70. dermestes-0.1.0/fixtures/const-param/flag/init_call/transcript.py +8 -0
  71. dermestes-0.1.0/fixtures/const-param/flag/keep_without_reason/expected.txt +5 -0
  72. dermestes-0.1.0/fixtures/const-param/flag/keep_without_reason/m.py +6 -0
  73. dermestes-0.1.0/fixtures/const-param/flag/literal_equal_to_default/expected.txt +4 -0
  74. dermestes-0.1.0/fixtures/const-param/flag/literal_equal_to_default/ui.py +6 -0
  75. dermestes-0.1.0/fixtures/const-param/flag/local_import/cli.py +4 -0
  76. dermestes-0.1.0/fixtures/const-param/flag/local_import/expected.txt +4 -0
  77. dermestes-0.1.0/fixtures/const-param/flag/local_import/tools.py +2 -0
  78. dermestes-0.1.0/fixtures/const-param/flag/module_constant/config.py +1 -0
  79. dermestes-0.1.0/fixtures/const-param/flag/module_constant/expected.txt +4 -0
  80. dermestes-0.1.0/fixtures/const-param/flag/module_constant/net.py +11 -0
  81. dermestes-0.1.0/fixtures/const-param/flag/name_default_never_passed/cache.py +11 -0
  82. dermestes-0.1.0/fixtures/const-param/flag/name_default_never_passed/expected.txt +4 -0
  83. dermestes-0.1.0/fixtures/const-param/flag/passed_explicitly/a.py +11 -0
  84. dermestes-0.1.0/fixtures/const-param/flag/passed_explicitly/expected.txt +4 -0
  85. dermestes-0.1.0/fixtures/const-param/flag/passed_explicitly/m.py +2 -0
  86. dermestes-0.1.0/fixtures/const-param/flag/passed_explicitly_mixed/expected.txt +4 -0
  87. dermestes-0.1.0/fixtures/const-param/flag/passed_explicitly_mixed/m.py +7 -0
  88. dermestes-0.1.0/fixtures/const-param/flag/same_literal_no_default/a.py +5 -0
  89. dermestes-0.1.0/fixtures/const-param/flag/same_literal_no_default/b.py +5 -0
  90. dermestes-0.1.0/fixtures/const-param/flag/same_literal_no_default/expected.txt +4 -0
  91. dermestes-0.1.0/fixtures/const-param/flag/same_literal_no_default/strips.py +2 -0
  92. dermestes-0.1.0/fixtures/const-param/flag/self_method/expected.txt +4 -0
  93. dermestes-0.1.0/fixtures/const-param/flag/self_method/log.py +9 -0
  94. dermestes-0.1.0/fixtures/const-param/flag/test_passes_same_value/expected.txt +4 -0
  95. dermestes-0.1.0/fixtures/const-param/flag/test_passes_same_value/extract.py +8 -0
  96. dermestes-0.1.0/fixtures/const-param/flag/test_passes_same_value/tests/test_extract.py +5 -0
  97. dermestes-0.1.0/fixtures/const-param/no_flag/abstract_and_protocol/m.py +17 -0
  98. dermestes-0.1.0/fixtures/const-param/no_flag/callback_value_ref/events.py +10 -0
  99. dermestes-0.1.0/fixtures/const-param/no_flag/class_passed_as_value/m.py +8 -0
  100. dermestes-0.1.0/fixtures/const-param/no_flag/cls_call/m.py +11 -0
  101. dermestes-0.1.0/fixtures/const-param/no_flag/decorated_route/web.py +12 -0
  102. dermestes-0.1.0/fixtures/const-param/no_flag/default_excludes/docs/demo.py +6 -0
  103. dermestes-0.1.0/fixtures/const-param/no_flag/default_excludes/examples/demo.py +6 -0
  104. dermestes-0.1.0/fixtures/const-param/no_flag/default_excludes/pkg/test/resources/demo.py +6 -0
  105. dermestes-0.1.0/fixtures/const-param/no_flag/dict_update_collision/cli.py +7 -0
  106. dermestes-0.1.0/fixtures/const-param/no_flag/docs_caller_varies/docs/lesson.py +3 -0
  107. dermestes-0.1.0/fixtures/const-param/no_flag/docs_caller_varies/pkg/app.py +5 -0
  108. dermestes-0.1.0/fixtures/const-param/no_flag/docs_caller_varies/pkg/core.py +2 -0
  109. dermestes-0.1.0/fixtures/const-param/no_flag/docs_only_callers/docs/run.py +3 -0
  110. dermestes-0.1.0/fixtures/const-param/no_flag/docs_only_callers/pkg/dbt.py +2 -0
  111. dermestes-0.1.0/fixtures/const-param/no_flag/example_value_ref/examples/x.py +5 -0
  112. dermestes-0.1.0/fixtures/const-param/no_flag/example_value_ref/pkg/app.py +5 -0
  113. dermestes-0.1.0/fixtures/const-param/no_flag/example_value_ref/pkg/core.py +2 -0
  114. dermestes-0.1.0/fixtures/const-param/no_flag/fstring_call/sql.py +10 -0
  115. dermestes-0.1.0/fixtures/const-param/no_flag/generated_file/_sync.py +10 -0
  116. dermestes-0.1.0/fixtures/const-param/no_flag/getattr_computed_name/detections.py +2 -0
  117. dermestes-0.1.0/fixtures/const-param/no_flag/getattr_computed_name/utils.py +9 -0
  118. dermestes-0.1.0/fixtures/const-param/no_flag/in_all/fmt.py +9 -0
  119. dermestes-0.1.0/fixtures/const-param/no_flag/keep_with_reason/m.py +6 -0
  120. dermestes-0.1.0/fixtures/const-param/no_flag/main_only/script.py +6 -0
  121. dermestes-0.1.0/fixtures/const-param/no_flag/other_value_in_second_file/m.py +6 -0
  122. dermestes-0.1.0/fixtures/const-param/no_flag/other_value_in_second_file/n.py +5 -0
  123. dermestes-0.1.0/fixtures/const-param/no_flag/override/jobs.py +24 -0
  124. dermestes-0.1.0/fixtures/const-param/no_flag/patched_constant/tests/test_tools.py +6 -0
  125. dermestes-0.1.0/fixtures/const-param/no_flag/patched_constant/tools.py +9 -0
  126. dermestes-0.1.0/fixtures/const-param/no_flag/same_variable_name/db.py +10 -0
  127. dermestes-0.1.0/fixtures/const-param/no_flag/splat_call/m.py +6 -0
  128. dermestes-0.1.0/fixtures/const-param/no_flag/star_import_call/app.py +5 -0
  129. dermestes-0.1.0/fixtures/const-param/no_flag/star_import_call/tools.py +6 -0
  130. dermestes-0.1.0/fixtures/const-param/no_flag/test_only_callers/index.py +2 -0
  131. dermestes-0.1.0/fixtures/const-param/no_flag/test_only_callers/tests/test_index.py +5 -0
  132. dermestes-0.1.0/fixtures/const-param/no_flag/test_passes_different_value/extract.py +6 -0
  133. dermestes-0.1.0/fixtures/const-param/no_flag/test_passes_different_value/tests/test_extract.py +5 -0
  134. dermestes-0.1.0/fixtures/const-param/no_flag/unresolved_attr_other_value/store.py +10 -0
  135. dermestes-0.1.0/fixtures/const-param/no_flag/zero_call_sites/m.py +2 -0
  136. dermestes-0.1.0/fixtures/dead-code/flag/recursive_private/expected.txt +3 -0
  137. dermestes-0.1.0/fixtures/dead-code/flag/recursive_private/tree.py +3 -0
  138. dermestes-0.1.0/fixtures/dead-code/flag/test_only_private_function/expected.txt +4 -0
  139. dermestes-0.1.0/fixtures/dead-code/flag/test_only_private_function/report.py +10 -0
  140. dermestes-0.1.0/fixtures/dead-code/flag/test_only_private_function/tests/test_report.py +5 -0
  141. dermestes-0.1.0/fixtures/dead-code/flag/unused_private_function/expected.txt +3 -0
  142. dermestes-0.1.0/fixtures/dead-code/flag/unused_private_function/report.py +10 -0
  143. dermestes-0.1.0/fixtures/dead-code/flag/unused_private_method/expected.txt +3 -0
  144. dermestes-0.1.0/fixtures/dead-code/flag/unused_private_method/store.py +11 -0
  145. dermestes-0.1.0/fixtures/dead-code/flag/unused_public_untyped_package/expected.txt +3 -0
  146. dermestes-0.1.0/fixtures/dead-code/flag/unused_public_untyped_package/pkg/__init__.py +0 -0
  147. dermestes-0.1.0/fixtures/dead-code/flag/unused_public_untyped_package/pkg/util.py +2 -0
  148. dermestes-0.1.0/fixtures/dead-code/no_flag/alembic_migration/migrations/versions/0001_init.py +12 -0
  149. dermestes-0.1.0/fixtures/dead-code/no_flag/callback_as_value/jobs.py +25 -0
  150. dermestes-0.1.0/fixtures/dead-code/no_flag/called_from_docs_or_examples/api.py +6 -0
  151. dermestes-0.1.0/fixtures/dead-code/no_flag/called_from_docs_or_examples/docs/snippets/debug.py +3 -0
  152. dermestes-0.1.0/fixtures/dead-code/no_flag/called_from_docs_or_examples/examples/demo.py +3 -0
  153. dermestes-0.1.0/fixtures/dead-code/no_flag/decorated_route_and_cell/app.py +15 -0
  154. dermestes-0.1.0/fixtures/dead-code/no_flag/external_base_override/queue.py +6 -0
  155. dermestes-0.1.0/fixtures/dead-code/no_flag/getattr_string_and_computed/detections.py +6 -0
  156. dermestes-0.1.0/fixtures/dead-code/no_flag/getattr_string_and_computed/plugin.py +20 -0
  157. dermestes-0.1.0/fixtures/dead-code/no_flag/project_scripts/cli.py +2 -0
  158. dermestes-0.1.0/fixtures/dead-code/no_flag/project_scripts/pyproject.toml +6 -0
  159. dermestes-0.1.0/fixtures/dead-code/no_flag/public_in_typed_package/pkg/__init__.py +0 -0
  160. dermestes-0.1.0/fixtures/dead-code/no_flag/public_in_typed_package/pkg/py.typed +0 -0
  161. dermestes-0.1.0/fixtures/dead-code/no_flag/public_in_typed_package/pkg/util.py +2 -0
  162. dermestes-0.1.0/fixtures/dead-code/no_flag/registry_and_jinja_global/web.py +14 -0
  163. dermestes-0.1.0/fixtures/dead-code/no_flag/repr_display_hook/table.py +10 -0
  164. dermestes-0.1.0/fixtures/dead-code/no_flag/template_and_markdown/NOTES.md +1 -0
  165. dermestes-0.1.0/fixtures/dead-code/no_flag/template_and_markdown/templates/page.html +1 -0
  166. dermestes-0.1.0/fixtures/dead-code/no_flag/template_and_markdown/views.py +6 -0
  167. dermestes-0.1.0/fixtures/dead-code/no_flag/unresolved_receiver/conn.py +11 -0
  168. dermestes-0.1.0/fixtures/one-impl/flag/abc_single_impl/expected.txt +3 -0
  169. dermestes-0.1.0/fixtures/one-impl/flag/abc_single_impl/pay/__init__.py +0 -0
  170. dermestes-0.1.0/fixtures/one-impl/flag/abc_single_impl/pay/gateway.py +12 -0
  171. dermestes-0.1.0/fixtures/one-impl/flag/abc_single_impl/pay/stripe.py +12 -0
  172. dermestes-0.1.0/fixtures/one-impl/flag/dotted_module_import/app.py +6 -0
  173. dermestes-0.1.0/fixtures/one-impl/flag/dotted_module_import/core/__init__.py +0 -0
  174. dermestes-0.1.0/fixtures/one-impl/flag/dotted_module_import/core/sinks.py +6 -0
  175. dermestes-0.1.0/fixtures/one-impl/flag/dotted_module_import/expected.txt +3 -0
  176. dermestes-0.1.0/fixtures/one-impl/flag/dotted_module_import/tests/test_app.py +5 -0
  177. dermestes-0.1.0/fixtures/one-impl/flag/forward_ref_annotation/base.py +28 -0
  178. dermestes-0.1.0/fixtures/one-impl/flag/forward_ref_annotation/expected.txt +3 -0
  179. dermestes-0.1.0/fixtures/one-impl/flag/keep_without_reason/expected.txt +4 -0
  180. dermestes-0.1.0/fixtures/one-impl/flag/keep_without_reason/store.py +11 -0
  181. dermestes-0.1.0/fixtures/one-impl/flag/plain_dict_key/base.py +11 -0
  182. dermestes-0.1.0/fixtures/one-impl/flag/plain_dict_key/expected.txt +3 -0
  183. dermestes-0.1.0/fixtures/one-impl/flag/plain_dict_key/settings.py +1 -0
  184. dermestes-0.1.0/fixtures/one-impl/flag/protocol_single_impl/english.py +11 -0
  185. dermestes-0.1.0/fixtures/one-impl/flag/protocol_single_impl/expected.txt +3 -0
  186. dermestes-0.1.0/fixtures/one-impl/flag/protocol_single_impl/greet.py +11 -0
  187. dermestes-0.1.0/fixtures/one-impl/flag/src_layout_relative/expected.txt +3 -0
  188. dermestes-0.1.0/fixtures/one-impl/flag/src_layout_relative/src/app/__init__.py +0 -0
  189. dermestes-0.1.0/fixtures/one-impl/flag/src_layout_relative/src/app/base.py +6 -0
  190. dermestes-0.1.0/fixtures/one-impl/flag/src_layout_relative/src/app/impl/__init__.py +0 -0
  191. dermestes-0.1.0/fixtures/one-impl/flag/src_layout_relative/src/app/impl/files.py +6 -0
  192. dermestes-0.1.0/fixtures/one-impl/flag/transitive_through_abstract/expected.txt +3 -0
  193. dermestes-0.1.0/fixtures/one-impl/flag/transitive_through_abstract/shapes.py +19 -0
  194. dermestes-0.1.0/fixtures/one-impl/flag/unrelated_unresolved_base_same_name/expected.txt +3 -0
  195. dermestes-0.1.0/fixtures/one-impl/flag/unrelated_unresolved_base_same_name/fmt/__init__.py +0 -0
  196. dermestes-0.1.0/fixtures/one-impl/flag/unrelated_unresolved_base_same_name/fmt/code.py +11 -0
  197. dermestes-0.1.0/fixtures/one-impl/flag/unrelated_unresolved_base_same_name/scripts/srv.py +6 -0
  198. dermestes-0.1.0/fixtures/one-impl/flag/uv_workspace_member/backoffice/backoffice/__init__.py +0 -0
  199. dermestes-0.1.0/fixtures/one-impl/flag/uv_workspace_member/backoffice/backoffice/cache.py +6 -0
  200. dermestes-0.1.0/fixtures/one-impl/flag/uv_workspace_member/backoffice/backoffice/disk_cache.py +6 -0
  201. dermestes-0.1.0/fixtures/one-impl/flag/uv_workspace_member/backoffice/pyproject.toml +3 -0
  202. dermestes-0.1.0/fixtures/one-impl/flag/uv_workspace_member/expected.txt +3 -0
  203. dermestes-0.1.0/fixtures/one-impl/flag/uv_workspace_member/pyproject.toml +2 -0
  204. dermestes-0.1.0/fixtures/one-impl/no_flag/abc_with_fake/svc.py +11 -0
  205. dermestes-0.1.0/fixtures/one-impl/no_flag/abc_with_fake/tests/test_svc.py +6 -0
  206. dermestes-0.1.0/fixtures/one-impl/no_flag/abc_without_abstract_methods/auth.py +17 -0
  207. dermestes-0.1.0/fixtures/one-impl/no_flag/attribute_only_protocol/proto.py +12 -0
  208. dermestes-0.1.0/fixtures/one-impl/no_flag/disabled/base.py +11 -0
  209. dermestes-0.1.0/fixtures/one-impl/no_flag/disabled/pyproject.toml +2 -0
  210. dermestes-0.1.0/fixtures/one-impl/no_flag/dunder_call_protocol/proto.py +10 -0
  211. dermestes-0.1.0/fixtures/one-impl/no_flag/getattr_mention/base.py +11 -0
  212. dermestes-0.1.0/fixtures/one-impl/no_flag/getattr_mention/settings.py +3 -0
  213. dermestes-0.1.0/fixtures/one-impl/no_flag/in_all/api.py +13 -0
  214. dermestes-0.1.0/fixtures/one-impl/no_flag/init_reexport/pkg/__init__.py +1 -0
  215. dermestes-0.1.0/fixtures/one-impl/no_flag/init_reexport/pkg/base.py +11 -0
  216. dermestes-0.1.0/fixtures/one-impl/no_flag/keep_on_decorator_line/exporters.py +11 -0
  217. dermestes-0.1.0/fixtures/one-impl/no_flag/keep_on_wrapped_header/store.py +13 -0
  218. dermestes-0.1.0/fixtures/one-impl/no_flag/keep_with_reason/store.py +11 -0
  219. dermestes-0.1.0/fixtures/one-impl/no_flag/local_import_subclass/base.py +11 -0
  220. dermestes-0.1.0/fixtures/one-impl/no_flag/local_import_subclass/factory.py +8 -0
  221. dermestes-0.1.0/fixtures/one-impl/no_flag/mixin_satisfies_abstract/base.py +20 -0
  222. dermestes-0.1.0/fixtures/one-impl/no_flag/only_subclass_abstract/base.py +14 -0
  223. dermestes-0.1.0/fixtures/one-impl/no_flag/other_metaclass/base.py +13 -0
  224. dermestes-0.1.0/fixtures/one-impl/no_flag/patch_target_mention/base.py +11 -0
  225. dermestes-0.1.0/fixtures/one-impl/no_flag/patch_target_mention/tests/test_base.py +6 -0
  226. dermestes-0.1.0/fixtures/one-impl/no_flag/plain_base_one_subclass/base.py +8 -0
  227. dermestes-0.1.0/fixtures/one-impl/no_flag/protocol_structural_two/impls.py +8 -0
  228. dermestes-0.1.0/fixtures/one-impl/no_flag/protocol_structural_two/proto.py +5 -0
  229. dermestes-0.1.0/fixtures/one-impl/no_flag/protocol_with_fake/clock.py +11 -0
  230. dermestes-0.1.0/fixtures/one-impl/no_flag/protocol_with_fake/tests/fakes.py +3 -0
  231. dermestes-0.1.0/fixtures/one-impl/no_flag/public_glob/api/base.py +11 -0
  232. dermestes-0.1.0/fixtures/one-impl/no_flag/public_glob/pyproject.toml +2 -0
  233. dermestes-0.1.0/fixtures/one-impl/no_flag/register_call/base.py +14 -0
  234. dermestes-0.1.0/fixtures/one-impl/no_flag/registry_dict_key/base.py +11 -0
  235. dermestes-0.1.0/fixtures/one-impl/no_flag/registry_dict_key/settings.py +3 -0
  236. dermestes-0.1.0/fixtures/one-impl/no_flag/star_import_subclass/base.py +11 -0
  237. dermestes-0.1.0/fixtures/one-impl/no_flag/star_import_subclass/more.py +6 -0
  238. dermestes-0.1.0/fixtures/one-impl/no_flag/third_party_base_on_abc/plugin.py +13 -0
  239. dermestes-0.1.0/fixtures/one-impl/no_flag/third_party_base_on_impl/base.py +6 -0
  240. dermestes-0.1.0/fixtures/one-impl/no_flag/third_party_base_on_impl/user.py +8 -0
  241. dermestes-0.1.0/fixtures/one-impl/no_flag/two_impls/base.py +16 -0
  242. dermestes-0.1.0/fixtures/one-impl/no_flag/zero_impls/base.py +6 -0
  243. dermestes-0.1.0/fixtures/pass-through/flag/forward_async_wrapper_sync_target/expected.txt +3 -0
  244. dermestes-0.1.0/fixtures/pass-through/flag/forward_async_wrapper_sync_target/pages.py +11 -0
  245. dermestes-0.1.0/fixtures/pass-through/flag/forward_await/expected.txt +3 -0
  246. dermestes-0.1.0/fixtures/pass-through/flag/forward_await/net.py +12 -0
  247. dermestes-0.1.0/fixtures/pass-through/flag/forward_bare/expected.txt +3 -0
  248. dermestes-0.1.0/fixtures/pass-through/flag/forward_bare/log.py +12 -0
  249. dermestes-0.1.0/fixtures/pass-through/flag/forward_binds_arguments/expected.txt +3 -0
  250. dermestes-0.1.0/fixtures/pass-through/flag/forward_binds_arguments/writer.py +15 -0
  251. dermestes-0.1.0/fixtures/pass-through/flag/forward_binds_constant/expected.txt +3 -0
  252. dermestes-0.1.0/fixtures/pass-through/flag/forward_binds_constant/tools.py +21 -0
  253. dermestes-0.1.0/fixtures/pass-through/flag/forward_return/entries.py +12 -0
  254. dermestes-0.1.0/fixtures/pass-through/flag/forward_return/expected.txt +3 -0
  255. dermestes-0.1.0/fixtures/pass-through/flag/forward_self_method/expected.txt +3 -0
  256. dermestes-0.1.0/fixtures/pass-through/flag/forward_self_method/store.py +15 -0
  257. dermestes-0.1.0/fixtures/pass-through/flag/forward_super_override/expected.txt +3 -0
  258. dermestes-0.1.0/fixtures/pass-through/flag/forward_super_override/m.py +13 -0
  259. dermestes-0.1.0/fixtures/pass-through/flag/keep_without_reason/expected.txt +4 -0
  260. dermestes-0.1.0/fixtures/pass-through/flag/keep_without_reason/m.py +12 -0
  261. dermestes-0.1.0/fixtures/pass-through/flag/rename/dates.py +13 -0
  262. dermestes-0.1.0/fixtures/pass-through/flag/rename/expected.txt +3 -0
  263. dermestes-0.1.0/fixtures/pass-through/flag/single_use/expected.txt +3 -0
  264. dermestes-0.1.0/fixtures/pass-through/flag/single_use/m.py +9 -0
  265. dermestes-0.1.0/fixtures/pass-through/no_flag/any_param_wrapper/cli.py +10 -0
  266. dermestes-0.1.0/fixtures/pass-through/no_flag/bool_predicate/m.py +8 -0
  267. dermestes-0.1.0/fixtures/pass-through/no_flag/bool_wrapper_and_chain/m.py +17 -0
  268. dermestes-0.1.0/fixtures/pass-through/no_flag/compound_body/io.py +13 -0
  269. dermestes-0.1.0/fixtures/pass-through/no_flag/dict_get_collision/jobs.py +13 -0
  270. dermestes-0.1.0/fixtures/pass-through/no_flag/dict_literal_body/view.py +11 -0
  271. dermestes-0.1.0/fixtures/pass-through/no_flag/example_calls_wrapper/examples/demo.py +3 -0
  272. dermestes-0.1.0/fixtures/pass-through/no_flag/example_calls_wrapper/pkg/log.py +10 -0
  273. dermestes-0.1.0/fixtures/pass-through/no_flag/fastapi_route_depends/app.py +24 -0
  274. dermestes-0.1.0/fixtures/pass-through/no_flag/forward_constant_and_literal/stats.py +21 -0
  275. dermestes-0.1.0/fixtures/pass-through/no_flag/forward_constant_many_callers/db.py +25 -0
  276. dermestes-0.1.0/fixtures/pass-through/no_flag/forward_constant_public/ids.py +21 -0
  277. dermestes-0.1.0/fixtures/pass-through/no_flag/forward_target_shadowed/entries.py +14 -0
  278. dermestes-0.1.0/fixtures/pass-through/no_flag/jinja_filter/site.py +18 -0
  279. dermestes-0.1.0/fixtures/pass-through/no_flag/marimo_cell/nb.py +17 -0
  280. dermestes-0.1.0/fixtures/pass-through/no_flag/nested_closure/tasks.py +24 -0
  281. dermestes-0.1.0/fixtures/pass-through/no_flag/project_scripts/cli/app.py +7 -0
  282. dermestes-0.1.0/fixtures/pass-through/no_flag/project_scripts/cli/other.py +6 -0
  283. dermestes-0.1.0/fixtures/pass-through/no_flag/project_scripts/pyproject.toml +6 -0
  284. dermestes-0.1.0/fixtures/pass-through/no_flag/public_wrapper_of_private/status.py +12 -0
  285. dermestes-0.1.0/fixtures/pass-through/no_flag/rename_any_param/cli.py +15 -0
  286. dermestes-0.1.0/fixtures/pass-through/no_flag/rename_binds_literal/views.py +10 -0
  287. dermestes-0.1.0/fixtures/pass-through/no_flag/rename_bool/cron.py +13 -0
  288. dermestes-0.1.0/fixtures/pass-through/no_flag/rename_callee_shadowed/fmt.py +13 -0
  289. dermestes-0.1.0/fixtures/pass-through/no_flag/rename_public/dates.py +13 -0
  290. dermestes-0.1.0/fixtures/pass-through/no_flag/rename_three_callers/dates.py +17 -0
  291. dermestes-0.1.0/fixtures/pass-through/no_flag/same_name_other_class/gen.py +13 -0
  292. dermestes-0.1.0/fixtures/pass-through/no_flag/string_patched_in_test/pkg/__init__.py +0 -0
  293. dermestes-0.1.0/fixtures/pass-through/no_flag/string_patched_in_test/pkg/utils.py +11 -0
  294. dermestes-0.1.0/fixtures/pass-through/no_flag/string_patched_in_test/tests/test_utils.py +13 -0
  295. dermestes-0.1.0/fixtures/pass-through/no_flag/test_callers/fmt.py +7 -0
  296. dermestes-0.1.0/fixtures/pass-through/no_flag/test_callers/tests/test_fmt.py +6 -0
  297. dermestes-0.1.0/fixtures/pass-through/no_flag/watchdog_handler/srv.py +14 -0
  298. dermestes-0.1.0/prek.toml +38 -0
  299. dermestes-0.1.0/pyproject.toml +37 -0
  300. dermestes-0.1.0/release.toml +25 -0
  301. dermestes-0.1.0/rust-toolchain.toml +3 -0
  302. dermestes-0.1.0/rustfmt.toml +3 -0
  303. dermestes-0.1.0/src/callers.rs +350 -0
  304. dermestes-0.1.0/src/calls.rs +582 -0
  305. dermestes-0.1.0/src/cli.rs +330 -0
  306. dermestes-0.1.0/src/config.rs +152 -0
  307. dermestes-0.1.0/src/const_param.rs +278 -0
  308. dermestes-0.1.0/src/dead_code.rs +133 -0
  309. dermestes-0.1.0/src/discovery.rs +194 -0
  310. dermestes-0.1.0/src/git.rs +156 -0
  311. dermestes-0.1.0/src/guide.rs +153 -0
  312. dermestes-0.1.0/src/index.rs +948 -0
  313. dermestes-0.1.0/src/lib.rs +21 -0
  314. dermestes-0.1.0/src/main.rs +34 -0
  315. dermestes-0.1.0/src/one_impl.rs +287 -0
  316. dermestes-0.1.0/src/pass_through.rs +357 -0
  317. dermestes-0.1.0/src/resolve.rs +219 -0
  318. dermestes-0.1.0/tests/cli.rs +176 -0
  319. dermestes-0.1.0/tests/diff_mode.rs +190 -0
  320. dermestes-0.1.0/tests/fixtures.rs +112 -0
@@ -0,0 +1,2 @@
1
+ {
2
+ }
@@ -0,0 +1,155 @@
1
+ ---
2
+ name: rust-review
3
+ context: fork
4
+ background: false
5
+ description: Deep Rust code quality review. Auto-invoke when finishing a task, before marking work complete, when the user asks to review code, or when preparing a PR. Covers error handling, duplicated logic, test quality, performance patterns, idiomatic Rust, docs-code alignment, and API design beyond what clippy catches.
6
+ ---
7
+
8
+ # Deep Code Review for dermestes
9
+
10
+ Perform a thorough code quality review of the changes in this project. Go beyond
11
+ what clippy and rustfmt catch. Focus on the areas below and report findings
12
+ grouped by severity: 🔴 Must Fix, 🟡 Should Fix, 🟢 Suggestion.
13
+
14
+ First, run `cargo fmt --all -- --check` and
15
+ `cargo clippy --all-targets --all-features -- -D warnings` to confirm the
16
+ automated checks pass. If they don't, report them as findings — do **not** fix
17
+ them yourself. This skill reviews; it does not edit.
18
+
19
+ ## Returning results
20
+
21
+ This skill runs in a fork, so its transcript is never shown to the user. The
22
+ complete report must be your **final message** — the full findings text, not a
23
+ summary of it, not a pointer to a file, not "see above". Anything you leave out
24
+ of that last message is lost.
25
+
26
+ Concretely:
27
+
28
+ - Emit every finding in full (severity, location, why, concrete fix) in the
29
+ final message.
30
+ - Do not write findings to a scratch file and reference the path instead.
31
+ - If the review is clean, say so explicitly and state what you checked.
32
+ - Do not end with a question — the caller cannot answer it.
33
+
34
+ ## 1. Error Handling Quality
35
+
36
+ - `.unwrap()` / `.expect()` outside tests is denied by lint config. Flag any
37
+ instance that slipped through (macros, build scripts, `#[allow]`s).
38
+ - Check that `.context("message")` is used on every `?` that crosses an I/O,
39
+ parsing or subprocess boundary — bare `?` loses which operation failed.
40
+ - Flag `Result` return types where the function never returns `Err`.
41
+ - Flag `.map_err(|_| ...)` that silently discards error information.
42
+ - The crate is `anyhow`-based end to end. Flag `String` as an error type, and
43
+ flag any place where a caller has to string-match an error message to make a
44
+ decision — that wants a typed error instead.
45
+
46
+ ## 2. Process and I/O Seams
47
+
48
+ dermestes's core invariant: `git` is the only subprocess, and it is spawned in
49
+ one place. Everything downstream of parsing takes already-parsed data.
50
+
51
+ - Flag any new `std::process::Command`, or any `std::fs` read or environment
52
+ lookup outside the file walker, config loader and git seam.
53
+ - Flag check logic that reads the filesystem itself instead of taking the
54
+ parsed index — that is what keeps checks unit-testable with no `git`.
55
+ - Check that command bodies live in `cli.rs`, not `main.rs`.
56
+ - Nothing imports or executes target code, and nothing touches the network
57
+ (constitution, principle 4).
58
+
59
+ ## 3. Duplicated Logic
60
+
61
+ - Search for functions or code blocks that do substantially the same thing with
62
+ minor variations. Flag them and suggest extraction into a shared function,
63
+ trait, or generic.
64
+ - Pay special attention to:
65
+ - Qualified-name construction and import resolution
66
+ - Path normalization against the repo root
67
+ - Test-path classification
68
+ - Error handling boilerplate that could be a helper
69
+ - Similar match arms across different functions
70
+ - But: the constitution forbids abstractions with one user (principle 8).
71
+ Suggest extraction only when there are two real call sites.
72
+ - Suggest concrete refactoring: which function to extract, what parameters it
73
+ should take.
74
+
75
+ ## 4. Test Quality
76
+
77
+ - **Tests that don't assert**: Flag any test that just calls code without
78
+ asserting on the result. Running without panicking is not a test.
79
+ - **Tests that assert too little**: `assert!(result.is_ok())` without checking
80
+ the value inside is weak. Suggest asserting on the actual content.
81
+ - **Overly verbose tests**: Tests with excessive setup that obscure what's
82
+ actually being tested. Suggest extracting test helpers or fixtures.
83
+ - **Missing edge cases**: For each public function, check if tests cover: empty
84
+ input, error paths, boundary conditions.
85
+ - **Test naming**: Test names should describe the behavior being tested, not the
86
+ implementation (`returns_error_on_missing_file`, not `test_function_xyz`).
87
+ - **Integration vs unit**: unit tests (`#[cfg(test)] mod tests`) test internal
88
+ logic; `tests/*.rs` exercise the public CLI interface.
89
+ - **Exit codes are contract.** `0` no findings, `1` findings, `2` usage or
90
+ internal error; `guide` never returns `1`. Flag any new path that could
91
+ return the wrong one, and any test that asserts on stdout without asserting
92
+ on the exit code.
93
+ - **Fixtures are the spec.** Each check has `fixtures/<id>/flag/` and
94
+ `fixtures/<id>/no_flag/` cases. Flag a fix for a false positive that lands
95
+ without a `no_flag` fixture reproducing it.
96
+ - **Quiet when fine.** No findings means empty stdout. Flag any banner, summary
97
+ line or stderr noise on a clean run.
98
+
99
+ ## 5. Performance Patterns
100
+
101
+ - Flag unnecessary `.clone()` — suggest borrowing or restructuring ownership.
102
+ - Flag `.collect::<Vec<_>>()` immediately followed by `.iter()`.
103
+ - Prefer `&str` over `String`, `&[T]` over `Vec<T>`, `&Path` over `PathBuf` in
104
+ function parameters when ownership isn't needed.
105
+ - Flag large structs passed by value instead of by reference.
106
+ - Flag repeated linear scans over a collection that is looked up by key — the
107
+ reference graph walk is the likely offender; suggest a `HashMap`/`HashSet`.
108
+
109
+ ## 6. Idiomatic Rust
110
+
111
+ - Prefer iterator chains over manual `for` loops with `push`.
112
+ - Use `if let` / `let else` instead of `match` with a single interesting arm and
113
+ a wildcard.
114
+ - Suggest `impl From<X> for Y` instead of standalone conversion functions.
115
+ - Suggest `Display` implementations instead of `to_string()` methods.
116
+ - Flag `&String`, `&Vec<T>`, `&Box<T>` in signatures — use `&str`, `&[T]`, `&T`.
117
+ - Check doc comments on all public types and functions.
118
+
119
+ ## 7. Documentation ↔ Code Alignment
120
+
121
+ - **`docs/plans/CONSTITUTION.md`** is binding. Flag any output format, flag,
122
+ config key or exit code that differs from its interface contract — the fix
123
+ is an amendment commit, not a silent divergence.
124
+ - **`docs/src/guide/*.md`** is what `dermestes guide` prints. Every command,
125
+ flag and config key it names must exist.
126
+ - **`docs/dev/ARCHITECTURE.md`** and the **Key Invariants** list in `CLAUDE.md`
127
+ must still be true of the code. An invariant that the code no longer upholds
128
+ is a 🔴 either way: either the code regressed or the doc is lying.
129
+ - **`docs/adr/`**: if the change contradicts a recorded decision, flag it — the
130
+ fix is a new ADR superseding it, not a silent divergence.
131
+ - **Shared prose**: `README.md` and `docs/src/index.md` are generated between
132
+ `<!-- BEGIN SHARED:... -->` markers. Flag any edit made inside the markers
133
+ instead of in `docs/shared/`.
134
+ - Flag any mismatch as 🔴 Must Fix — stale docs are worse than no docs.
135
+
136
+ ## 8. API and Module Design
137
+
138
+ - Is `main.rs` thin? Argument parsing and exit-code mapping only.
139
+ - Are module boundaries clean? Each module should have a clear responsibility.
140
+ - Check for any `pub` items that don't need to be public.
141
+ - Flag a trait with one implementation, or a config key or flag no real repo
142
+ needed (constitution, principle 8).
143
+ - Flag circular dependencies between modules.
144
+
145
+ ## Output Format
146
+
147
+ Group all findings by severity, then by area. For each finding:
148
+
149
+ - State **what** the issue is and **where** (`file.rs:line` or function name)
150
+ - Explain **why** it matters
151
+ - Suggest a **concrete fix** (not just "improve this")
152
+
153
+ End with a summary: X must-fix, Y should-fix, Z suggestions.
154
+
155
+ $ARGUMENTS
@@ -0,0 +1,26 @@
1
+ version: 2
2
+ updates:
3
+ # Rust (Cargo) dependencies
4
+ - package-ecosystem: "cargo"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ day: "monday"
9
+ open-pull-requests-limit: 10
10
+ labels:
11
+ - "dependencies"
12
+ - "rust"
13
+ groups:
14
+ minor-and-patch:
15
+ update-types:
16
+ - "minor"
17
+ - "patch"
18
+
19
+ # GitHub Actions
20
+ - package-ecosystem: "github-actions"
21
+ directory: "/"
22
+ schedule:
23
+ interval: "weekly"
24
+ labels:
25
+ - "dependencies"
26
+ - "ci"
@@ -0,0 +1,29 @@
1
+ name: "Cargo Audit"
2
+
3
+ on:
4
+ push:
5
+ paths:
6
+ - "Cargo.toml"
7
+ - "Cargo.lock"
8
+ pull_request:
9
+ paths:
10
+ - "Cargo.toml"
11
+ - "Cargo.lock"
12
+ schedule:
13
+ - cron: "0 0 * * *" # Daily at midnight UTC
14
+ workflow_dispatch:
15
+
16
+ permissions:
17
+ contents: read
18
+ issues: write
19
+
20
+ jobs:
21
+ audit:
22
+ name: Security Audit
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - name: Checkout repository
26
+ uses: actions/checkout@v7
27
+
28
+ - name: Run cargo-audit
29
+ uses: actions-rust-lang/audit@v1
@@ -0,0 +1,35 @@
1
+ name: "Cargo Deny"
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ paths:
7
+ - "Cargo.lock"
8
+ - "Cargo.toml"
9
+ - "deny.toml"
10
+ pull_request:
11
+ paths:
12
+ - "Cargo.lock"
13
+ - "Cargo.toml"
14
+ - "deny.toml"
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ deny:
21
+ name: ${{ matrix.check }}
22
+ runs-on: ubuntu-latest
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ check: [bans, licenses, sources]
27
+ steps:
28
+ - name: Checkout repository
29
+ uses: actions/checkout@v7
30
+
31
+ - name: Run cargo-deny (${{ matrix.check }})
32
+ uses: EmbarkStudios/cargo-deny-action@v2
33
+ with:
34
+ command: check ${{ matrix.check }}
35
+ arguments: --all-features
@@ -0,0 +1,42 @@
1
+ name: "CodeQL"
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ paths:
7
+ - "src/**"
8
+ - "Cargo.toml"
9
+ - "Cargo.lock"
10
+ pull_request:
11
+ branches: ["main"]
12
+ paths:
13
+ - "src/**"
14
+ - "Cargo.toml"
15
+ - "Cargo.lock"
16
+ schedule:
17
+ - cron: "0 6 * * 1" # Weekly on Monday at 06:00 UTC
18
+
19
+ permissions:
20
+ security-events: write
21
+ packages: read
22
+ actions: read
23
+ contents: read
24
+
25
+ jobs:
26
+ analyze:
27
+ name: Analyze Rust
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - name: Checkout repository
31
+ uses: actions/checkout@v7
32
+
33
+ - name: Initialize CodeQL
34
+ uses: github/codeql-action/init@v4
35
+ with:
36
+ languages: rust
37
+ build-mode: none
38
+
39
+ - name: Perform CodeQL Analysis
40
+ uses: github/codeql-action/analyze@v4
41
+ with:
42
+ category: "/language:rust"
@@ -0,0 +1,63 @@
1
+ name: Deploy docs
2
+ on:
3
+ push:
4
+ branches: ["main"]
5
+ paths:
6
+ - "docs/**"
7
+ - "src/**" # rebuild when CLI changes (help text may change)
8
+
9
+ permissions:
10
+ contents: read
11
+ pages: write
12
+ id-token: write
13
+
14
+ concurrency:
15
+ group: "pages"
16
+ cancel-in-progress: false
17
+
18
+ jobs:
19
+ deploy:
20
+ runs-on: ubuntu-latest
21
+ environment:
22
+ name: github-pages
23
+ url: ${{ steps.deployment.outputs.page_url }}
24
+ steps:
25
+ - uses: actions/checkout@v7
26
+
27
+ - uses: actions/setup-node@v7
28
+ with:
29
+ node-version: "22"
30
+
31
+ - name: Lint mermaid diagrams
32
+ run: |
33
+ cd docs && npm ci --silent
34
+ cd .. && node docs/lint-mermaid.mjs
35
+
36
+ # Versions come from docs/toolchain.sh so CI and `make docs` cannot
37
+ # drift onto an incompatible mdbook/mdbook-mermaid pair.
38
+ - name: Install mdBook and preprocessors
39
+ run: |
40
+ eval "$(bash docs/toolchain.sh --versions)"
41
+ mkdir -p bin
42
+ curl -sSL "https://github.com/rust-lang/mdBook/releases/download/v$MDBOOK_VERSION/mdbook-v$MDBOOK_VERSION-x86_64-unknown-linux-gnu.tar.gz" | tar -xz --directory=bin
43
+ curl -sSL "https://github.com/badboy/mdbook-mermaid/releases/download/v$MDBOOK_MERMAID_VERSION/mdbook-mermaid-v$MDBOOK_MERMAID_VERSION-x86_64-unknown-linux-gnu.tar.gz" | tar -xz --directory=bin
44
+ echo "$PWD/bin" >> $GITHUB_PATH
45
+
46
+ - name: Check the docs toolchain matches the pins
47
+ run: bash docs/toolchain.sh
48
+
49
+ - name: Sync docs version badge with Cargo.toml
50
+ run: bash docs/gen-version.sh
51
+
52
+ - name: Build book
53
+ run: mdbook build docs
54
+
55
+ - name: Generate llms.txt
56
+ run: bash docs/generate-llms-txt.sh
57
+
58
+ - uses: actions/upload-pages-artifact@v5
59
+ with:
60
+ path: docs/book/html
61
+
62
+ - uses: actions/deploy-pages@v5
63
+ id: deployment
@@ -0,0 +1,114 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: write
11
+
12
+ jobs:
13
+ build-wheels:
14
+ name: Build wheels on ${{ matrix.os }}
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ matrix:
18
+ os: [ubuntu-latest, macos-14, windows-latest]
19
+
20
+ steps:
21
+ - uses: actions/checkout@v7
22
+
23
+ - name: Build wheels
24
+ uses: PyO3/maturin-action@v1
25
+ with:
26
+ args: --release --strip
27
+ manylinux: 2_28
28
+
29
+ - name: Upload wheels
30
+ uses: actions/upload-artifact@v7
31
+ with:
32
+ name: wheels-${{ matrix.os }}
33
+ path: target/wheels/*.whl
34
+
35
+ build-sdist:
36
+ name: Build source distribution
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/checkout@v7
40
+
41
+ - name: Set up Rust
42
+ uses: dtolnay/rust-toolchain@stable
43
+
44
+ - name: Set up Python
45
+ uses: actions/setup-python@v7
46
+ with:
47
+ python-version: '3.11'
48
+
49
+ - name: Install maturin
50
+ run: pip install maturin
51
+
52
+ - name: Build sdist
53
+ run: maturin sdist
54
+
55
+ - name: Upload sdist
56
+ uses: actions/upload-artifact@v7
57
+ with:
58
+ name: sdist
59
+ path: target/wheels/*.tar.gz
60
+
61
+ create-release:
62
+ name: Create GitHub Release
63
+ needs: [build-wheels, build-sdist]
64
+ runs-on: ubuntu-latest
65
+ if: startsWith(github.ref, 'refs/tags/')
66
+ steps:
67
+ - uses: actions/checkout@v7
68
+
69
+ - name: Download all artifacts
70
+ uses: actions/download-artifact@v8
71
+ with:
72
+ path: dist
73
+
74
+ - name: Flatten artifacts
75
+ run: |
76
+ mkdir -p wheels
77
+ find dist -name '*.whl' -exec cp {} wheels/ \;
78
+ find dist -name '*.tar.gz' -exec cp {} wheels/ \;
79
+
80
+ - name: Create Release
81
+ uses: softprops/action-gh-release@v3
82
+ with:
83
+ files: wheels/*
84
+ generate_release_notes: true
85
+ draft: false
86
+ prerelease: false
87
+
88
+ publish-to-pypi:
89
+ name: Publish to PyPI
90
+ needs: [build-wheels, build-sdist, create-release]
91
+ runs-on: ubuntu-latest
92
+ if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
93
+ environment:
94
+ name: pypi
95
+ url: https://pypi.org/p/dermestes
96
+ permissions:
97
+ id-token: write
98
+ steps:
99
+ - name: Download all artifacts
100
+ uses: actions/download-artifact@v8
101
+ with:
102
+ path: dist
103
+
104
+ - name: Flatten artifacts
105
+ run: |
106
+ mkdir -p wheels
107
+ find dist -name '*.whl' -exec cp {} wheels/ \;
108
+ find dist -name '*.tar.gz' -exec cp {} wheels/ \;
109
+
110
+ - name: Publish to PyPI
111
+ uses: pypa/gh-action-pypi-publish@release/v1
112
+ with:
113
+ packages-dir: wheels/
114
+ skip-existing: true
@@ -0,0 +1,74 @@
1
+ name: Code Review
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - "src/**"
8
+ - "tests/**"
9
+ - "docs/**"
10
+ - "Makefile"
11
+ - "Cargo.toml"
12
+ - "Cargo.lock"
13
+ - "rust-toolchain.toml"
14
+ - "clippy.toml"
15
+ - "rustfmt.toml"
16
+ pull_request:
17
+ paths:
18
+ - "src/**"
19
+ - "tests/**"
20
+ - "docs/**"
21
+ - "Makefile"
22
+ - "Cargo.toml"
23
+ - "Cargo.lock"
24
+ - "rust-toolchain.toml"
25
+ - "clippy.toml"
26
+ - "rustfmt.toml"
27
+
28
+ concurrency:
29
+ group: ${{ github.workflow }}-${{ github.ref }}
30
+ cancel-in-progress: true
31
+
32
+ env:
33
+ CARGO_TERM_COLOR: always
34
+
35
+ jobs:
36
+ fmt:
37
+ name: Formatting
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - uses: actions/checkout@v7
41
+ - uses: dtolnay/rust-toolchain@stable
42
+ with:
43
+ components: rustfmt
44
+ - run: cargo fmt --all --check
45
+
46
+ clippy:
47
+ name: Clippy
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v7
51
+ - uses: dtolnay/rust-toolchain@stable
52
+ with:
53
+ components: clippy
54
+ - uses: Swatinem/rust-cache@v2
55
+ - run: cargo clippy --all-targets --all-features -- -D warnings
56
+
57
+ test:
58
+ name: Tests
59
+ runs-on: ubuntu-latest
60
+ steps:
61
+ - uses: actions/checkout@v7
62
+ - uses: dtolnay/rust-toolchain@stable
63
+ - uses: Swatinem/rust-cache@v2
64
+ - run: cargo test --all-features
65
+
66
+ docs:
67
+ name: Docs are in sync
68
+ runs-on: ubuntu-latest
69
+ steps:
70
+ - uses: actions/checkout@v7
71
+ - name: Version badge matches Cargo.toml
72
+ run: bash docs/gen-version.sh --check
73
+ - name: Shared snippets are injected
74
+ run: bash docs/inject-shared.sh --check
@@ -0,0 +1,78 @@
1
+ # Rust
2
+ /target/
3
+ **/*.rs.bk
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ *.so
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+ cf/
30
+ # Virtual environments
31
+ .env
32
+ .venv
33
+ env/
34
+ venv/
35
+ ENV/
36
+ env.bak/
37
+ venv.bak/
38
+
39
+ # Claude Code
40
+ .claude/worktrees/
41
+
42
+ # IDE
43
+ .vscode/
44
+ .idea/
45
+ *.swp
46
+ *.swo
47
+ *~
48
+
49
+ # OS
50
+ .DS_Store
51
+ .DS_Store?
52
+ ._*
53
+ .Spotlight-V100
54
+ .Trashes
55
+ ehthumbs.db
56
+ Thumbs.db
57
+
58
+ # Logs
59
+ *.log
60
+
61
+ # Temporary files
62
+ *.tmp
63
+ *.temp
64
+ .cache/
65
+
66
+ # maturin / PyO3
67
+ *.so
68
+ *.pyd
69
+ .eggs/
70
+
71
+ # Testing
72
+ .pytest_cache/
73
+ .coverage
74
+ htmlcov/
75
+
76
+
77
+ # mdBook build output (docs/book.toml build-dir)
78
+ docs/book/