prose-formatter 0.1.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.
Files changed (368) hide show
  1. prose_formatter-0.1.2/.github/actions/build-wheel/action.yml +47 -0
  2. prose_formatter-0.1.2/.github/actions/provision-uv/action.yml +11 -0
  3. prose_formatter-0.1.2/.github/release.yml +22 -0
  4. prose_formatter-0.1.2/.github/scripts/parse-version.py +31 -0
  5. prose_formatter-0.1.2/.github/scripts/summary.py +113 -0
  6. prose_formatter-0.1.2/.github/scripts/templates/ci-summary.md.j2 +3 -0
  7. prose_formatter-0.1.2/.github/scripts/templates/release-summary.md.j2 +29 -0
  8. prose_formatter-0.1.2/.github/workflows/check.yml +47 -0
  9. prose_formatter-0.1.2/.github/workflows/ci.yml +57 -0
  10. prose_formatter-0.1.2/.github/workflows/release.yml +158 -0
  11. prose_formatter-0.1.2/.gitignore +21 -0
  12. prose_formatter-0.1.2/Cargo.lock +2108 -0
  13. prose_formatter-0.1.2/Cargo.toml +41 -0
  14. prose_formatter-0.1.2/LICENSE +21 -0
  15. prose_formatter-0.1.2/PKG-INFO +316 -0
  16. prose_formatter-0.1.2/README.md +292 -0
  17. prose_formatter-0.1.2/assets/logo.png +0 -0
  18. prose_formatter-0.1.2/assets/logo.svg +1 -0
  19. prose_formatter-0.1.2/assets/social.png +0 -0
  20. prose_formatter-0.1.2/assets/title.png +0 -0
  21. prose_formatter-0.1.2/assets/title.svg +1 -0
  22. prose_formatter-0.1.2/mise.toml +54 -0
  23. prose_formatter-0.1.2/pyproject.toml +33 -0
  24. prose_formatter-0.1.2/src/cli.rs +328 -0
  25. prose_formatter-0.1.2/src/config.rs +322 -0
  26. prose_formatter-0.1.2/src/lib.rs +13 -0
  27. prose_formatter-0.1.2/src/main.rs +3 -0
  28. prose_formatter-0.1.2/src/pipeline.rs +417 -0
  29. prose_formatter-0.1.2/src/primitives/aligner.rs +716 -0
  30. prose_formatter-0.1.2/src/primitives/colon_targets.rs +307 -0
  31. prose_formatter-0.1.2/src/primitives/edit.rs +162 -0
  32. prose_formatter-0.1.2/src/primitives/mod.rs +12 -0
  33. prose_formatter-0.1.2/src/primitives/orderer.rs +417 -0
  34. prose_formatter-0.1.2/src/rules/align_colons.rs +66 -0
  35. prose_formatter-0.1.2/src/rules/align_equals.rs +118 -0
  36. prose_formatter-0.1.2/src/rules/align_imports.rs +129 -0
  37. prose_formatter-0.1.2/src/rules/alphabetize.rs +768 -0
  38. prose_formatter-0.1.2/src/rules/collection_layout.rs +500 -0
  39. prose_formatter-0.1.2/src/rules/match_case_align.rs +157 -0
  40. prose_formatter-0.1.2/src/rules/mod.rs +13 -0
  41. prose_formatter-0.1.2/src/rules/singleton_rule.rs +149 -0
  42. prose_formatter-0.1.2/src/rules/strip_trailing_commas.rs +89 -0
  43. prose_formatter-0.1.2/src/source.rs +383 -0
  44. prose_formatter-0.1.2/src/test_support.rs +15 -0
  45. prose_formatter-0.1.2/src/walker.rs +138 -0
  46. prose_formatter-0.1.2/tests/common/mod.rs +52 -0
  47. prose_formatter-0.1.2/tests/config_parsing.rs +33 -0
  48. prose_formatter-0.1.2/tests/fixtures/align_colons/dict_literal.input.py +12 -0
  49. prose_formatter-0.1.2/tests/fixtures/align_colons/dict_mixed_keys.input.py +15 -0
  50. prose_formatter-0.1.2/tests/fixtures/align_colons/dict_nested.input.py +16 -0
  51. prose_formatter-0.1.2/tests/fixtures/align_colons/dict_unpacking.input.py +15 -0
  52. prose_formatter-0.1.2/tests/fixtures/align_colons/docstring_args.input.py +22 -0
  53. prose_formatter-0.1.2/tests/fixtures/align_colons/docstring_args_bracketed_types.input.py +17 -0
  54. prose_formatter-0.1.2/tests/fixtures/align_colons/docstring_args_inline_phrase.input.py +19 -0
  55. prose_formatter-0.1.2/tests/fixtures/align_colons/docstring_args_malformed_entry.input.py +18 -0
  56. prose_formatter-0.1.2/tests/fixtures/align_colons/docstring_args_parenthesized_types.input.py +17 -0
  57. prose_formatter-0.1.2/tests/fixtures/align_colons/docstring_args_starred.input.py +17 -0
  58. prose_formatter-0.1.2/tests/fixtures/align_colons/function_signature.input.py +15 -0
  59. prose_formatter-0.1.2/tests/fixtures/align_colons/function_signature_mixed.input.py +15 -0
  60. prose_formatter-0.1.2/tests/fixtures/align_colons/function_signature_star.input.py +14 -0
  61. prose_formatter-0.1.2/tests/fixtures/align_colons/idempotent.input.py +36 -0
  62. prose_formatter-0.1.2/tests/fixtures/align_colons/pydantic_class_methods.input.py +20 -0
  63. prose_formatter-0.1.2/tests/fixtures/align_colons/pydantic_fields.input.py +13 -0
  64. prose_formatter-0.1.2/tests/fixtures/align_colons/pydantic_fields_with_defaults.input.py +13 -0
  65. prose_formatter-0.1.2/tests/fixtures/align_colons/shift_limit_drop.config.toml +2 -0
  66. prose_formatter-0.1.2/tests/fixtures/align_colons/shift_limit_drop.input.py +14 -0
  67. prose_formatter-0.1.2/tests/fixtures/align_colons/shift_limit_skip.config.toml +2 -0
  68. prose_formatter-0.1.2/tests/fixtures/align_colons/shift_limit_skip.input.py +12 -0
  69. prose_formatter-0.1.2/tests/fixtures/align_colons/shift_limit_split.input.py +14 -0
  70. prose_formatter-0.1.2/tests/fixtures/align_colons/singleton_defers.input.py +23 -0
  71. prose_formatter-0.1.2/tests/fixtures/align_equals/annotated.input.py +10 -0
  72. prose_formatter-0.1.2/tests/fixtures/align_equals/augmented.input.py +9 -0
  73. prose_formatter-0.1.2/tests/fixtures/align_equals/basic.input.py +7 -0
  74. prose_formatter-0.1.2/tests/fixtures/align_equals/blank_line.input.py +9 -0
  75. prose_formatter-0.1.2/tests/fixtures/align_equals/chained.input.py +6 -0
  76. prose_formatter-0.1.2/tests/fixtures/align_equals/continuation_before_equals.input.py +8 -0
  77. prose_formatter-0.1.2/tests/fixtures/align_equals/idempotent.input.py +7 -0
  78. prose_formatter-0.1.2/tests/fixtures/align_equals/multi_line_target.input.py +11 -0
  79. prose_formatter-0.1.2/tests/fixtures/align_equals/nested_blocks.input.py +18 -0
  80. prose_formatter-0.1.2/tests/fixtures/align_equals/shift_limit_split.input.py +13 -0
  81. prose_formatter-0.1.2/tests/fixtures/align_equals/single_assignment.input.py +6 -0
  82. prose_formatter-0.1.2/tests/fixtures/align_equals/with_comments.input.py +9 -0
  83. prose_formatter-0.1.2/tests/fixtures/align_imports/aliased_imports.input.py +10 -0
  84. prose_formatter-0.1.2/tests/fixtures/align_imports/aliased_shift_limit_drop.config.toml +2 -0
  85. prose_formatter-0.1.2/tests/fixtures/align_imports/aliased_shift_limit_drop.input.py +12 -0
  86. prose_formatter-0.1.2/tests/fixtures/align_imports/aliased_shift_limit_skip.config.toml +2 -0
  87. prose_formatter-0.1.2/tests/fixtures/align_imports/aliased_shift_limit_skip.input.py +11 -0
  88. prose_formatter-0.1.2/tests/fixtures/align_imports/aliased_shift_limit_split.input.py +13 -0
  89. prose_formatter-0.1.2/tests/fixtures/align_imports/breakers.input.py +17 -0
  90. prose_formatter-0.1.2/tests/fixtures/align_imports/comment_breaks.input.py +16 -0
  91. prose_formatter-0.1.2/tests/fixtures/align_imports/from_imports.input.py +11 -0
  92. prose_formatter-0.1.2/tests/fixtures/align_imports/idempotent.input.py +13 -0
  93. prose_formatter-0.1.2/tests/fixtures/align_imports/if_block.input.py +17 -0
  94. prose_formatter-0.1.2/tests/fixtures/align_imports/mixed_groups.input.py +16 -0
  95. prose_formatter-0.1.2/tests/fixtures/align_imports/multi_line_skips.input.py +17 -0
  96. prose_formatter-0.1.2/tests/fixtures/align_imports/multi_name.input.py +11 -0
  97. prose_formatter-0.1.2/tests/fixtures/align_imports/nested_block.input.py +17 -0
  98. prose_formatter-0.1.2/tests/fixtures/align_imports/relative_imports.input.py +11 -0
  99. prose_formatter-0.1.2/tests/fixtures/align_imports/shift_limit_drop.config.toml +2 -0
  100. prose_formatter-0.1.2/tests/fixtures/align_imports/shift_limit_drop.input.py +13 -0
  101. prose_formatter-0.1.2/tests/fixtures/align_imports/shift_limit_skip.config.toml +2 -0
  102. prose_formatter-0.1.2/tests/fixtures/align_imports/shift_limit_skip.input.py +12 -0
  103. prose_formatter-0.1.2/tests/fixtures/align_imports/shift_limit_split.input.py +13 -0
  104. prose_formatter-0.1.2/tests/fixtures/align_imports/single_import.input.py +10 -0
  105. prose_formatter-0.1.2/tests/fixtures/alphabetize/annotated_field_default.input.py +19 -0
  106. prose_formatter-0.1.2/tests/fixtures/alphabetize/async_compound.input.py +19 -0
  107. prose_formatter-0.1.2/tests/fixtures/alphabetize/bare_import_aliases.input.py +8 -0
  108. prose_formatter-0.1.2/tests/fixtures/alphabetize/bare_imports.input.py +13 -0
  109. prose_formatter-0.1.2/tests/fixtures/alphabetize/class_with_branched_body.input.py +17 -0
  110. prose_formatter-0.1.2/tests/fixtures/alphabetize/classes.input.py +17 -0
  111. prose_formatter-0.1.2/tests/fixtures/alphabetize/dataclass.input.py +17 -0
  112. prose_formatter-0.1.2/tests/fixtures/alphabetize/del_targets.input.py +11 -0
  113. prose_formatter-0.1.2/tests/fixtures/alphabetize/dict_keep_marker.input.py +24 -0
  114. prose_formatter-0.1.2/tests/fixtures/alphabetize/dict_keys.input.py +61 -0
  115. prose_formatter-0.1.2/tests/fixtures/alphabetize/dunder_all.input.py +16 -0
  116. prose_formatter-0.1.2/tests/fixtures/alphabetize/dunder_slots.input.py +13 -0
  117. prose_formatter-0.1.2/tests/fixtures/alphabetize/enum.input.py +16 -0
  118. prose_formatter-0.1.2/tests/fixtures/alphabetize/field_class_with_methods.input.py +24 -0
  119. prose_formatter-0.1.2/tests/fixtures/alphabetize/field_class_with_validator.input.py +25 -0
  120. prose_formatter-0.1.2/tests/fixtures/alphabetize/for_orelse_imports.input.py +13 -0
  121. prose_formatter-0.1.2/tests/fixtures/alphabetize/framework_decorators.input.py +28 -0
  122. prose_formatter-0.1.2/tests/fixtures/alphabetize/from_import_aliases.input.py +7 -0
  123. prose_formatter-0.1.2/tests/fixtures/alphabetize/from_imports.input.py +13 -0
  124. prose_formatter-0.1.2/tests/fixtures/alphabetize/function_local_imports.input.py +19 -0
  125. prose_formatter-0.1.2/tests/fixtures/alphabetize/global_nonlocal.input.py +16 -0
  126. prose_formatter-0.1.2/tests/fixtures/alphabetize/hand_rolled_fields.input.py +12 -0
  127. prose_formatter-0.1.2/tests/fixtures/alphabetize/idempotent.input.py +30 -0
  128. prose_formatter-0.1.2/tests/fixtures/alphabetize/if_elif_else_arms.input.py +16 -0
  129. prose_formatter-0.1.2/tests/fixtures/alphabetize/inline_kwargs.input.py +7 -0
  130. prose_formatter-0.1.2/tests/fixtures/alphabetize/inline_methods.input.py +13 -0
  131. prose_formatter-0.1.2/tests/fixtures/alphabetize/inline_params.input.py +7 -0
  132. prose_formatter-0.1.2/tests/fixtures/alphabetize/kwargs.input.py +24 -0
  133. prose_formatter-0.1.2/tests/fixtures/alphabetize/kwonly_with_decorator.input.py +14 -0
  134. prose_formatter-0.1.2/tests/fixtures/alphabetize/lambda_params.input.py +15 -0
  135. prose_formatter-0.1.2/tests/fixtures/alphabetize/match_case_imports.input.py +15 -0
  136. prose_formatter-0.1.2/tests/fixtures/alphabetize/methods_grouped.input.py +33 -0
  137. prose_formatter-0.1.2/tests/fixtures/alphabetize/mixed_class_body.input.py +19 -0
  138. prose_formatter-0.1.2/tests/fixtures/alphabetize/multi_target.input.py +32 -0
  139. prose_formatter-0.1.2/tests/fixtures/alphabetize/namedtuple.input.py +15 -0
  140. prose_formatter-0.1.2/tests/fixtures/alphabetize/nested_compound.input.py +13 -0
  141. prose_formatter-0.1.2/tests/fixtures/alphabetize/params.input.py +18 -0
  142. prose_formatter-0.1.2/tests/fixtures/alphabetize/pydantic.input.py +17 -0
  143. prose_formatter-0.1.2/tests/fixtures/alphabetize/sets.input.py +18 -0
  144. prose_formatter-0.1.2/tests/fixtures/alphabetize/single_field_with_validator.input.py +23 -0
  145. prose_formatter-0.1.2/tests/fixtures/alphabetize/top_level_functions.input.py +18 -0
  146. prose_formatter-0.1.2/tests/fixtures/alphabetize/try_block_imports.input.py +14 -0
  147. prose_formatter-0.1.2/tests/fixtures/alphabetize/try_full_arms.input.py +22 -0
  148. prose_formatter-0.1.2/tests/fixtures/alphabetize/type_checking_block.input.py +15 -0
  149. prose_formatter-0.1.2/tests/fixtures/alphabetize/type_checking_in_function.input.py +17 -0
  150. prose_formatter-0.1.2/tests/fixtures/alphabetize/typeddict.input.py +15 -0
  151. prose_formatter-0.1.2/tests/fixtures/alphabetize/with_block_imports.input.py +10 -0
  152. prose_formatter-0.1.2/tests/fixtures/alphabetize/with_comments.input.py +20 -0
  153. prose_formatter-0.1.2/tests/fixtures/collection_layout/atomic_kinds.input.py +10 -0
  154. prose_formatter-0.1.2/tests/fixtures/collection_layout/comprehensions.input.py +11 -0
  155. prose_formatter-0.1.2/tests/fixtures/collection_layout/dict_literal.input.py +11 -0
  156. prose_formatter-0.1.2/tests/fixtures/collection_layout/idempotent.input.py +12 -0
  157. prose_formatter-0.1.2/tests/fixtures/collection_layout/list_literal.input.py +10 -0
  158. prose_formatter-0.1.2/tests/fixtures/collection_layout/matrix.input.py +11 -0
  159. prose_formatter-0.1.2/tests/fixtures/collection_layout/nested.input.py +14 -0
  160. prose_formatter-0.1.2/tests/fixtures/collection_layout/nested_blocks.input.py +19 -0
  161. prose_formatter-0.1.2/tests/fixtures/collection_layout/parenthesized_children.input.py +9 -0
  162. prose_formatter-0.1.2/tests/fixtures/collection_layout/set_literal.input.py +10 -0
  163. prose_formatter-0.1.2/tests/fixtures/collection_layout/single_item.input.py +12 -0
  164. prose_formatter-0.1.2/tests/fixtures/collection_layout/tuples.input.py +11 -0
  165. prose_formatter-0.1.2/tests/fixtures/collection_layout/unpacking.input.py +14 -0
  166. prose_formatter-0.1.2/tests/fixtures/collection_layout/with_comments.input.py +14 -0
  167. prose_formatter-0.1.2/tests/fixtures/composition/class_essentials.input.py +37 -0
  168. prose_formatter-0.1.2/tests/fixtures/composition/expanded_collection.input.py +12 -0
  169. prose_formatter-0.1.2/tests/fixtures/composition/match_dispatch.input.py +24 -0
  170. prose_formatter-0.1.2/tests/fixtures/composition/recursive_partition.input.py +16 -0
  171. prose_formatter-0.1.2/tests/fixtures/config/full_override.toml +26 -0
  172. prose_formatter-0.1.2/tests/fixtures/identity/basic.input.py +5 -0
  173. prose_formatter-0.1.2/tests/fixtures/match_case_align/comment_between_cases.input.py +14 -0
  174. prose_formatter-0.1.2/tests/fixtures/match_case_align/expr_bodies.input.py +22 -0
  175. prose_formatter-0.1.2/tests/fixtures/match_case_align/idempotent.input.py +9 -0
  176. prose_formatter-0.1.2/tests/fixtures/match_case_align/mixed_arms.input.py +19 -0
  177. prose_formatter-0.1.2/tests/fixtures/match_case_align/multiline_body.input.py +15 -0
  178. prose_formatter-0.1.2/tests/fixtures/match_case_align/nested_match.input.py +20 -0
  179. prose_formatter-0.1.2/tests/fixtures/match_case_align/or_pattern.input.py +14 -0
  180. prose_formatter-0.1.2/tests/fixtures/match_case_align/shift_limit_skip.config.toml +2 -0
  181. prose_formatter-0.1.2/tests/fixtures/match_case_align/shift_limit_skip.input.py +15 -0
  182. prose_formatter-0.1.2/tests/fixtures/match_case_align/simple.input.py +13 -0
  183. prose_formatter-0.1.2/tests/fixtures/match_case_align/single_arm.input.py +8 -0
  184. prose_formatter-0.1.2/tests/fixtures/match_case_align/with_guards.input.py +16 -0
  185. prose_formatter-0.1.2/tests/fixtures/match_case_align/with_inline_comment.input.py +14 -0
  186. prose_formatter-0.1.2/tests/fixtures/singleton_rule/dict_literal.input.py +19 -0
  187. prose_formatter-0.1.2/tests/fixtures/singleton_rule/docstring_args.input.py +21 -0
  188. prose_formatter-0.1.2/tests/fixtures/singleton_rule/function_signature.input.py +19 -0
  189. prose_formatter-0.1.2/tests/fixtures/singleton_rule/idempotent.input.py +24 -0
  190. prose_formatter-0.1.2/tests/fixtures/singleton_rule/match_case.input.py +8 -0
  191. prose_formatter-0.1.2/tests/fixtures/singleton_rule/method_self_and_kwarg.input.py +19 -0
  192. prose_formatter-0.1.2/tests/fixtures/singleton_rule/mixed_singleton_and_group.input.py +32 -0
  193. prose_formatter-0.1.2/tests/fixtures/singleton_rule/multiline_signature.input.py +19 -0
  194. prose_formatter-0.1.2/tests/fixtures/singleton_rule/pydantic_field.input.py +26 -0
  195. prose_formatter-0.1.2/tests/fixtures/singleton_rule/same_line_dict.input.py +13 -0
  196. prose_formatter-0.1.2/tests/fixtures/singleton_rule/with_comments.input.py +17 -0
  197. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/class_bases.input.py +13 -0
  198. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/dict_literal.input.py +12 -0
  199. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/function_call.input.py +11 -0
  200. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/function_signature.input.py +13 -0
  201. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/idempotent.input.py +10 -0
  202. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/list_literal.input.py +11 -0
  203. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/nested.input.py +19 -0
  204. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/parenthesized_args.input.py +11 -0
  205. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/pos_only_separator.input.py +20 -0
  206. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/set_literal.input.py +11 -0
  207. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/single_line.input.py +15 -0
  208. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/tuple_in_call.input.py +10 -0
  209. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/type_params.input.py +27 -0
  210. prose_formatter-0.1.2/tests/fixtures/strip_trailing_commas/with_comments.input.py +18 -0
  211. prose_formatter-0.1.2/tests/integration.rs +198 -0
  212. prose_formatter-0.1.2/tests/snapshots/align_colons/dict_literal.input.py.snap +17 -0
  213. prose_formatter-0.1.2/tests/snapshots/align_colons/dict_mixed_keys.input.py.snap +20 -0
  214. prose_formatter-0.1.2/tests/snapshots/align_colons/dict_nested.input.py.snap +21 -0
  215. prose_formatter-0.1.2/tests/snapshots/align_colons/dict_unpacking.input.py.snap +20 -0
  216. prose_formatter-0.1.2/tests/snapshots/align_colons/docstring_args.input.py.snap +27 -0
  217. prose_formatter-0.1.2/tests/snapshots/align_colons/docstring_args_bracketed_types.input.py.snap +22 -0
  218. prose_formatter-0.1.2/tests/snapshots/align_colons/docstring_args_inline_phrase.input.py.snap +24 -0
  219. prose_formatter-0.1.2/tests/snapshots/align_colons/docstring_args_malformed_entry.input.py.snap +23 -0
  220. prose_formatter-0.1.2/tests/snapshots/align_colons/docstring_args_parenthesized_types.input.py.snap +22 -0
  221. prose_formatter-0.1.2/tests/snapshots/align_colons/docstring_args_starred.input.py.snap +22 -0
  222. prose_formatter-0.1.2/tests/snapshots/align_colons/function_signature.input.py.snap +20 -0
  223. prose_formatter-0.1.2/tests/snapshots/align_colons/function_signature_mixed.input.py.snap +20 -0
  224. prose_formatter-0.1.2/tests/snapshots/align_colons/function_signature_star.input.py.snap +19 -0
  225. prose_formatter-0.1.2/tests/snapshots/align_colons/idempotent.input.py.snap +41 -0
  226. prose_formatter-0.1.2/tests/snapshots/align_colons/pydantic_class_methods.input.py.snap +25 -0
  227. prose_formatter-0.1.2/tests/snapshots/align_colons/pydantic_fields.input.py.snap +18 -0
  228. prose_formatter-0.1.2/tests/snapshots/align_colons/pydantic_fields_with_defaults.input.py.snap +18 -0
  229. prose_formatter-0.1.2/tests/snapshots/align_colons/shift_limit_drop.input.py.snap +19 -0
  230. prose_formatter-0.1.2/tests/snapshots/align_colons/shift_limit_skip.input.py.snap +17 -0
  231. prose_formatter-0.1.2/tests/snapshots/align_colons/shift_limit_split.input.py.snap +19 -0
  232. prose_formatter-0.1.2/tests/snapshots/align_colons/singleton_defers.input.py.snap +28 -0
  233. prose_formatter-0.1.2/tests/snapshots/align_equals/annotated.input.py.snap +15 -0
  234. prose_formatter-0.1.2/tests/snapshots/align_equals/augmented.input.py.snap +14 -0
  235. prose_formatter-0.1.2/tests/snapshots/align_equals/basic.input.py.snap +12 -0
  236. prose_formatter-0.1.2/tests/snapshots/align_equals/blank_line.input.py.snap +14 -0
  237. prose_formatter-0.1.2/tests/snapshots/align_equals/chained.input.py.snap +11 -0
  238. prose_formatter-0.1.2/tests/snapshots/align_equals/continuation_before_equals.input.py.snap +13 -0
  239. prose_formatter-0.1.2/tests/snapshots/align_equals/idempotent.input.py.snap +12 -0
  240. prose_formatter-0.1.2/tests/snapshots/align_equals/multi_line_target.input.py.snap +16 -0
  241. prose_formatter-0.1.2/tests/snapshots/align_equals/nested_blocks.input.py.snap +23 -0
  242. prose_formatter-0.1.2/tests/snapshots/align_equals/shift_limit_split.input.py.snap +18 -0
  243. prose_formatter-0.1.2/tests/snapshots/align_equals/single_assignment.input.py.snap +11 -0
  244. prose_formatter-0.1.2/tests/snapshots/align_equals/with_comments.input.py.snap +14 -0
  245. prose_formatter-0.1.2/tests/snapshots/align_imports/aliased_imports.input.py.snap +15 -0
  246. prose_formatter-0.1.2/tests/snapshots/align_imports/aliased_shift_limit_drop.input.py.snap +17 -0
  247. prose_formatter-0.1.2/tests/snapshots/align_imports/aliased_shift_limit_skip.input.py.snap +16 -0
  248. prose_formatter-0.1.2/tests/snapshots/align_imports/aliased_shift_limit_split.input.py.snap +18 -0
  249. prose_formatter-0.1.2/tests/snapshots/align_imports/breakers.input.py.snap +22 -0
  250. prose_formatter-0.1.2/tests/snapshots/align_imports/comment_breaks.input.py.snap +21 -0
  251. prose_formatter-0.1.2/tests/snapshots/align_imports/from_imports.input.py.snap +16 -0
  252. prose_formatter-0.1.2/tests/snapshots/align_imports/idempotent.input.py.snap +18 -0
  253. prose_formatter-0.1.2/tests/snapshots/align_imports/if_block.input.py.snap +22 -0
  254. prose_formatter-0.1.2/tests/snapshots/align_imports/mixed_groups.input.py.snap +21 -0
  255. prose_formatter-0.1.2/tests/snapshots/align_imports/multi_line_skips.input.py.snap +22 -0
  256. prose_formatter-0.1.2/tests/snapshots/align_imports/multi_name.input.py.snap +16 -0
  257. prose_formatter-0.1.2/tests/snapshots/align_imports/nested_block.input.py.snap +22 -0
  258. prose_formatter-0.1.2/tests/snapshots/align_imports/relative_imports.input.py.snap +16 -0
  259. prose_formatter-0.1.2/tests/snapshots/align_imports/shift_limit_drop.input.py.snap +18 -0
  260. prose_formatter-0.1.2/tests/snapshots/align_imports/shift_limit_skip.input.py.snap +17 -0
  261. prose_formatter-0.1.2/tests/snapshots/align_imports/shift_limit_split.input.py.snap +18 -0
  262. prose_formatter-0.1.2/tests/snapshots/align_imports/single_import.input.py.snap +15 -0
  263. prose_formatter-0.1.2/tests/snapshots/alphabetize/annotated_field_default.input.py.snap +23 -0
  264. prose_formatter-0.1.2/tests/snapshots/alphabetize/async_compound.input.py.snap +24 -0
  265. prose_formatter-0.1.2/tests/snapshots/alphabetize/bare_import_aliases.input.py.snap +13 -0
  266. prose_formatter-0.1.2/tests/snapshots/alphabetize/bare_imports.input.py.snap +17 -0
  267. prose_formatter-0.1.2/tests/snapshots/alphabetize/class_with_branched_body.input.py.snap +22 -0
  268. prose_formatter-0.1.2/tests/snapshots/alphabetize/classes.input.py.snap +22 -0
  269. prose_formatter-0.1.2/tests/snapshots/alphabetize/dataclass.input.py.snap +22 -0
  270. prose_formatter-0.1.2/tests/snapshots/alphabetize/del_targets.input.py.snap +16 -0
  271. prose_formatter-0.1.2/tests/snapshots/alphabetize/dict_keep_marker.input.py.snap +30 -0
  272. prose_formatter-0.1.2/tests/snapshots/alphabetize/dict_keys.input.py.snap +71 -0
  273. prose_formatter-0.1.2/tests/snapshots/alphabetize/dunder_all.input.py.snap +21 -0
  274. prose_formatter-0.1.2/tests/snapshots/alphabetize/dunder_slots.input.py.snap +18 -0
  275. prose_formatter-0.1.2/tests/snapshots/alphabetize/enum.input.py.snap +21 -0
  276. prose_formatter-0.1.2/tests/snapshots/alphabetize/field_class_with_methods.input.py.snap +29 -0
  277. prose_formatter-0.1.2/tests/snapshots/alphabetize/field_class_with_validator.input.py.snap +30 -0
  278. prose_formatter-0.1.2/tests/snapshots/alphabetize/for_orelse_imports.input.py.snap +18 -0
  279. prose_formatter-0.1.2/tests/snapshots/alphabetize/framework_decorators.input.py.snap +33 -0
  280. prose_formatter-0.1.2/tests/snapshots/alphabetize/from_import_aliases.input.py.snap +12 -0
  281. prose_formatter-0.1.2/tests/snapshots/alphabetize/from_imports.input.py.snap +17 -0
  282. prose_formatter-0.1.2/tests/snapshots/alphabetize/function_local_imports.input.py.snap +24 -0
  283. prose_formatter-0.1.2/tests/snapshots/alphabetize/global_nonlocal.input.py.snap +21 -0
  284. prose_formatter-0.1.2/tests/snapshots/alphabetize/hand_rolled_fields.input.py.snap +17 -0
  285. prose_formatter-0.1.2/tests/snapshots/alphabetize/idempotent.input.py.snap +35 -0
  286. prose_formatter-0.1.2/tests/snapshots/alphabetize/if_elif_else_arms.input.py.snap +21 -0
  287. prose_formatter-0.1.2/tests/snapshots/alphabetize/inline_kwargs.input.py.snap +12 -0
  288. prose_formatter-0.1.2/tests/snapshots/alphabetize/inline_methods.input.py.snap +18 -0
  289. prose_formatter-0.1.2/tests/snapshots/alphabetize/inline_params.input.py.snap +12 -0
  290. prose_formatter-0.1.2/tests/snapshots/alphabetize/kwargs.input.py.snap +29 -0
  291. prose_formatter-0.1.2/tests/snapshots/alphabetize/kwonly_with_decorator.input.py.snap +19 -0
  292. prose_formatter-0.1.2/tests/snapshots/alphabetize/lambda_params.input.py.snap +20 -0
  293. prose_formatter-0.1.2/tests/snapshots/alphabetize/match_case_imports.input.py.snap +20 -0
  294. prose_formatter-0.1.2/tests/snapshots/alphabetize/methods_grouped.input.py.snap +38 -0
  295. prose_formatter-0.1.2/tests/snapshots/alphabetize/mixed_class_body.input.py.snap +24 -0
  296. prose_formatter-0.1.2/tests/snapshots/alphabetize/multi_target.input.py.snap +37 -0
  297. prose_formatter-0.1.2/tests/snapshots/alphabetize/namedtuple.input.py.snap +20 -0
  298. prose_formatter-0.1.2/tests/snapshots/alphabetize/nested_compound.input.py.snap +18 -0
  299. prose_formatter-0.1.2/tests/snapshots/alphabetize/params.input.py.snap +23 -0
  300. prose_formatter-0.1.2/tests/snapshots/alphabetize/pydantic.input.py.snap +22 -0
  301. prose_formatter-0.1.2/tests/snapshots/alphabetize/sets.input.py.snap +23 -0
  302. prose_formatter-0.1.2/tests/snapshots/alphabetize/single_field_with_validator.input.py.snap +28 -0
  303. prose_formatter-0.1.2/tests/snapshots/alphabetize/top_level_functions.input.py.snap +23 -0
  304. prose_formatter-0.1.2/tests/snapshots/alphabetize/try_block_imports.input.py.snap +19 -0
  305. prose_formatter-0.1.2/tests/snapshots/alphabetize/try_full_arms.input.py.snap +27 -0
  306. prose_formatter-0.1.2/tests/snapshots/alphabetize/type_checking_block.input.py.snap +20 -0
  307. prose_formatter-0.1.2/tests/snapshots/alphabetize/type_checking_in_function.input.py.snap +22 -0
  308. prose_formatter-0.1.2/tests/snapshots/alphabetize/typeddict.input.py.snap +20 -0
  309. prose_formatter-0.1.2/tests/snapshots/alphabetize/with_block_imports.input.py.snap +15 -0
  310. prose_formatter-0.1.2/tests/snapshots/alphabetize/with_comments.input.py.snap +25 -0
  311. prose_formatter-0.1.2/tests/snapshots/collection_layout/atomic_kinds.input.py.snap +22 -0
  312. prose_formatter-0.1.2/tests/snapshots/collection_layout/comprehensions.input.py.snap +16 -0
  313. prose_formatter-0.1.2/tests/snapshots/collection_layout/dict_literal.input.py.snap +24 -0
  314. prose_formatter-0.1.2/tests/snapshots/collection_layout/idempotent.input.py.snap +17 -0
  315. prose_formatter-0.1.2/tests/snapshots/collection_layout/list_literal.input.py.snap +17 -0
  316. prose_formatter-0.1.2/tests/snapshots/collection_layout/matrix.input.py.snap +22 -0
  317. prose_formatter-0.1.2/tests/snapshots/collection_layout/nested.input.py.snap +44 -0
  318. prose_formatter-0.1.2/tests/snapshots/collection_layout/nested_blocks.input.py.snap +35 -0
  319. prose_formatter-0.1.2/tests/snapshots/collection_layout/parenthesized_children.input.py.snap +22 -0
  320. prose_formatter-0.1.2/tests/snapshots/collection_layout/set_literal.input.py.snap +18 -0
  321. prose_formatter-0.1.2/tests/snapshots/collection_layout/single_item.input.py.snap +17 -0
  322. prose_formatter-0.1.2/tests/snapshots/collection_layout/tuples.input.py.snap +22 -0
  323. prose_formatter-0.1.2/tests/snapshots/collection_layout/unpacking.input.py.snap +40 -0
  324. prose_formatter-0.1.2/tests/snapshots/collection_layout/with_comments.input.py.snap +21 -0
  325. prose_formatter-0.1.2/tests/snapshots/composition/class_essentials.input.py.snap +42 -0
  326. prose_formatter-0.1.2/tests/snapshots/composition/expanded_collection.input.py.snap +31 -0
  327. prose_formatter-0.1.2/tests/snapshots/composition/match_dispatch.input.py.snap +29 -0
  328. prose_formatter-0.1.2/tests/snapshots/composition/recursive_partition.input.py.snap +72 -0
  329. prose_formatter-0.1.2/tests/snapshots/config/full_override.snap +45 -0
  330. prose_formatter-0.1.2/tests/snapshots/identity/basic.input.py.snap +10 -0
  331. prose_formatter-0.1.2/tests/snapshots/match_case_align/comment_between_cases.input.py.snap +16 -0
  332. prose_formatter-0.1.2/tests/snapshots/match_case_align/expr_bodies.input.py.snap +21 -0
  333. prose_formatter-0.1.2/tests/snapshots/match_case_align/idempotent.input.py.snap +14 -0
  334. prose_formatter-0.1.2/tests/snapshots/match_case_align/mixed_arms.input.py.snap +21 -0
  335. prose_formatter-0.1.2/tests/snapshots/match_case_align/multiline_body.input.py.snap +19 -0
  336. prose_formatter-0.1.2/tests/snapshots/match_case_align/nested_match.input.py.snap +21 -0
  337. prose_formatter-0.1.2/tests/snapshots/match_case_align/or_pattern.input.py.snap +16 -0
  338. prose_formatter-0.1.2/tests/snapshots/match_case_align/shift_limit_skip.input.py.snap +17 -0
  339. prose_formatter-0.1.2/tests/snapshots/match_case_align/simple.input.py.snap +15 -0
  340. prose_formatter-0.1.2/tests/snapshots/match_case_align/single_arm.input.py.snap +12 -0
  341. prose_formatter-0.1.2/tests/snapshots/match_case_align/with_guards.input.py.snap +17 -0
  342. prose_formatter-0.1.2/tests/snapshots/match_case_align/with_inline_comment.input.py.snap +17 -0
  343. prose_formatter-0.1.2/tests/snapshots/singleton_rule/dict_literal.input.py.snap +24 -0
  344. prose_formatter-0.1.2/tests/snapshots/singleton_rule/docstring_args.input.py.snap +26 -0
  345. prose_formatter-0.1.2/tests/snapshots/singleton_rule/function_signature.input.py.snap +24 -0
  346. prose_formatter-0.1.2/tests/snapshots/singleton_rule/idempotent.input.py.snap +29 -0
  347. prose_formatter-0.1.2/tests/snapshots/singleton_rule/match_case.input.py.snap +13 -0
  348. prose_formatter-0.1.2/tests/snapshots/singleton_rule/method_self_and_kwarg.input.py.snap +24 -0
  349. prose_formatter-0.1.2/tests/snapshots/singleton_rule/mixed_singleton_and_group.input.py.snap +37 -0
  350. prose_formatter-0.1.2/tests/snapshots/singleton_rule/multiline_signature.input.py.snap +24 -0
  351. prose_formatter-0.1.2/tests/snapshots/singleton_rule/pydantic_field.input.py.snap +31 -0
  352. prose_formatter-0.1.2/tests/snapshots/singleton_rule/same_line_dict.input.py.snap +18 -0
  353. prose_formatter-0.1.2/tests/snapshots/singleton_rule/with_comments.input.py.snap +22 -0
  354. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/class_bases.input.py.snap +18 -0
  355. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/dict_literal.input.py.snap +17 -0
  356. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/function_call.input.py.snap +16 -0
  357. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/function_signature.input.py.snap +18 -0
  358. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/idempotent.input.py.snap +15 -0
  359. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/list_literal.input.py.snap +16 -0
  360. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/nested.input.py.snap +24 -0
  361. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/parenthesized_args.input.py.snap +16 -0
  362. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/pos_only_separator.input.py.snap +25 -0
  363. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/set_literal.input.py.snap +16 -0
  364. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/single_line.input.py.snap +20 -0
  365. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/tuple_in_call.input.py.snap +15 -0
  366. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/type_params.input.py.snap +32 -0
  367. prose_formatter-0.1.2/tests/snapshots/strip_trailing_commas/with_comments.input.py.snap +23 -0
  368. prose_formatter-0.1.2/uv.lock +8 -0
@@ -0,0 +1,47 @@
1
+ name : Build wheel
2
+ description : Runs `maturin-action` and uploads the resulting artifact. Caller must check out the repo before invoking this composite.
3
+
4
+ inputs:
5
+ command:
6
+ description : maturin subcommand (`build` or `sdist`)
7
+ required : true
8
+ target:
9
+ description : Cargo target triple (Linux/macOS/Windows wheel rows). Empty for sdist.
10
+ required : false
11
+ default : ''
12
+ manylinux:
13
+ description : Manylinux compatibility tag (`auto` on Linux, empty elsewhere)
14
+ required : false
15
+ default : ''
16
+ args:
17
+ description : Additional flags passed to maturin
18
+ required : false
19
+ default : ''
20
+ name:
21
+ description : Tag suffix in the uploaded `wheels-{name}` artifact.
22
+ default : sdist
23
+
24
+ runs:
25
+ using: composite
26
+ steps:
27
+ - name: Restore Cargo cache
28
+ uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
29
+ with:
30
+ cache-on-failure : 'true'
31
+
32
+ - name: Run maturin
33
+ uses: PyO3/maturin-action@3e2bdf6ba6453a61e649744019b8a2d906c7eb38
34
+ with:
35
+ command : ${{ inputs.command }}
36
+ target : ${{ inputs.target }}
37
+ manylinux : ${{ inputs.manylinux }}
38
+ args : ${{ inputs.args }}
39
+ sccache : ${{ github.ref_type != 'tag' }}
40
+
41
+ - name: Upload artifact
42
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
43
+ with:
44
+ name : wheels-${{ inputs.name }}
45
+ path : target/wheels/*
46
+ if-no-files-found : error
47
+ retention-days : 7
@@ -0,0 +1,11 @@
1
+ name : Provision uv with a warm wheel cache
2
+ description : Install the uv binary and restore `~/.cache/uv` keyed off the PEP 723 scripts so subsequent `uv run --script` invocations skip the PyPI fetch.
3
+
4
+ runs:
5
+ using: composite
6
+ steps:
7
+ - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b
8
+ with:
9
+ version : latest
10
+ enable-cache : true
11
+ cache-dependency-glob : .github/scripts/*.py
@@ -0,0 +1,22 @@
1
+ changelog:
2
+ categories:
3
+ - title: ✨ Features
4
+ labels:
5
+ - πŸ¦‰ engine
6
+ - πŸͺœ alignment
7
+ - πŸͺ‰ ordering
8
+ - πŸͺΆ formatting
9
+ - πŸͺ„ cli
10
+ - title: πŸ“° Docs
11
+ labels:
12
+ - πŸ“° docs
13
+ - title: πŸ—œοΈ Build
14
+ labels:
15
+ - πŸ—œοΈ build
16
+ - title: 🧱 Internals
17
+ labels:
18
+ - βš–οΈ tests
19
+ - πŸ—ΊοΈ architecture
20
+ - title: Other
21
+ labels:
22
+ - "*"
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env -S uv run --script
2
+ # /// script
3
+ # requires-python = ">=3.11"
4
+ # ///
5
+ """
6
+ Validate that pyproject.toml and Cargo.toml agree with the pushed tag.
7
+
8
+ Reads from the environment:
9
+ GITHUB_REF_TYPE e.g. tag, branch
10
+ GITHUB_REF_NAME e.g. 0.1.0, main
11
+
12
+ Exits 0 on a non-tag run, or on a tag whose declared pyproject.toml and
13
+ Cargo.toml versions match. Exits 1 when either file disagrees with the tag.
14
+ """
15
+
16
+ from os import environ
17
+ from re import sub
18
+ from tomllib import load
19
+
20
+
21
+ if environ.get("GITHUB_REF_TYPE") != "tag":
22
+ raise SystemExit
23
+
24
+ version = environ["GITHUB_REF_NAME"]
25
+ for file, table, expected in [
26
+ ("pyproject.toml", "project", version),
27
+ ("Cargo.toml", "package", sub(r"\.?(a|b|rc|dev|post)(\d+)", r"-\1.\2", version)),
28
+ ]:
29
+ with open(file, "rb") as f:
30
+ if (actual := load(f)[table]["version"]) != expected:
31
+ raise SystemExit(f"::error::{file} version mismatch: expected {expected}, got {actual}")
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env -S uv run --script
2
+ # /// script
3
+ # requires-python = ">=3.11"
4
+ # dependencies = ["jinja2"]
5
+ # ///
6
+ """
7
+ Render a πŸͺ» Prose step summary and gate the workflow's exit code.
8
+
9
+ Subcommands:
10
+ ci Render the CI gate summary (reads `RESULT` plus the GitHub
11
+ defaults). Exits 0 on `success`, 1 otherwise.
12
+ release Render the Release gate summary (reads `BUILD`, `SDIST`,
13
+ `PUBLISH` plus the GitHub defaults). Exits 0 when every
14
+ required job succeeded, 1 otherwise.
15
+
16
+ Both subcommands append to `$GITHUB_STEP_SUMMARY`.
17
+ """
18
+
19
+ from jinja2 import Environment, FileSystemLoader
20
+ from os import environ
21
+ from pathlib import Path
22
+ from sys import argv
23
+
24
+ ENV = Environment(
25
+ keep_trailing_newline = True,
26
+ loader = FileSystemLoader(Path(__file__).with_name("templates")),
27
+ lstrip_blocks = True,
28
+ trim_blocks = True
29
+ )
30
+ PLATFORMS = [
31
+ ("🐧 Linux x86_64", "*manylinux*x86_64.whl", "x86_64-unknown-linux-gnu"),
32
+ ("🐧 Linux aarch64", "*manylinux*aarch64.whl", "aarch64-unknown-linux-gnu"),
33
+ ("🍎 macOS x86_64", "*macosx*x86_64.whl", "x86_64-apple-darwin"),
34
+ ("🍎 macOS aarch64", "*macosx*arm64.whl", "aarch64-apple-darwin"),
35
+ ("πŸͺŸ Windows x86_64", "*win_amd64.whl", "x86_64-pc-windows-msvc"),
36
+ ("🚒 sdist", "*.tar.gz", None)
37
+ ]
38
+ REPO_URL = f"{environ['GITHUB_SERVER_URL']}/{environ['GITHUB_REPOSITORY']}"
39
+ SHA = environ["GITHUB_SHA"]
40
+
41
+
42
+ def ci():
43
+ """
44
+ Render the CI gate summary and exit with the matrix verdict.
45
+
46
+ Reads `RESULT` plus the GitHub-runner defaults, renders
47
+ `ci-summary.md.j2`, and exits 0 when `RESULT == "success"`,
48
+ 1 otherwise.
49
+ """
50
+ REF = environ.get("GITHUB_HEAD_REF") or environ["GITHUB_REF_NAME"]
51
+ RESULT = environ["RESULT"]
52
+ emit(
53
+ "ci-summary.md.j2",
54
+ commit_url = f"{REPO_URL}/commit/{SHA}",
55
+ msg = f"Result `{RESULT}`",
56
+ ref = REF,
57
+ short = SHA[:7],
58
+ tree_url = f"{REPO_URL}/tree/{REF}"
59
+ )
60
+ raise SystemExit(RESULT != "success")
61
+
62
+
63
+ def emit(template: str, **vars):
64
+ """
65
+ Render `template` with `vars` and append to `$GITHUB_STEP_SUMMARY`.
66
+
67
+ Args:
68
+ template : Filename of a `.md.j2` template under `templates/`.
69
+ vars : Substitution context passed to `Template.render`.
70
+ """
71
+ with open(environ["GITHUB_STEP_SUMMARY"], "a", encoding="utf-8") as f:
72
+ f.write(ENV.get_template(template).render(**vars))
73
+
74
+
75
+ def release():
76
+ """
77
+ Render the Release gate summary and exit with the pipeline verdict.
78
+
79
+ Reads `BUILD`, `SDIST`, `PUBLISH` plus the GitHub-runner defaults,
80
+ renders `release-summary.md.j2`, and exits 0 when every required
81
+ job (build, sdist, plus publish on tag runs) succeeded.
82
+ """
83
+ BUILD = environ["BUILD"]
84
+ IS_TAG = environ.get("GITHUB_REF_TYPE") == "tag"
85
+ PUBLISH = environ["PUBLISH"]
86
+ REF_NAME = environ["GITHUB_REF_NAME"]
87
+ SDIST = environ["SDIST"]
88
+ VERSION = REF_NAME.removeprefix("v")
89
+ platforms = [
90
+ (label, target, next(Path("dist").glob(pattern), None))
91
+ for label, pattern, target in PLATFORMS
92
+ ]
93
+ emit(
94
+ "release-summary.md.j2",
95
+ build = BUILD,
96
+ commit_link = f"[`{SHA[:7]}`]({REPO_URL}/commit/{SHA})",
97
+ is_tag = IS_TAG,
98
+ platforms = platforms,
99
+ publish = PUBLISH,
100
+ pypi_url = f"https://pypi.org/project/prose-formatter/{VERSION}/",
101
+ sdist = SDIST,
102
+ tag_link = f"[`{REF_NAME}`]({REPO_URL}/releases/tag/{REF_NAME})",
103
+ tree_link = f"[`{REF_NAME}`]({REPO_URL}/tree/{REF_NAME})",
104
+ version = VERSION
105
+ )
106
+ raise SystemExit(
107
+ BUILD != "success"
108
+ or SDIST != "success"
109
+ or (IS_TAG and PUBLISH != "success")
110
+ )
111
+
112
+
113
+ {"ci": ci, "release": release}[argv[1]]()
@@ -0,0 +1,3 @@
1
+ ## πŸͺ» Prose CI
2
+
3
+ {{ msg }} for [`{{ short }}`]({{ commit_url }}) on [`{{ ref }}`]({{ tree_url }}).
@@ -0,0 +1,29 @@
1
+ ## πŸͺ» Prose Release
2
+
3
+ {% if not is_tag -%}
4
+ Build dry-run for {{ commit_link }} on {{ tree_link }}.
5
+ {% elif publish == "success" -%}
6
+ Published [*Prose* {{ version }}]({{ pypi_url }}) from {{ commit_link }} on tag {{ tag_link }}.
7
+ {% elif build != "success" or sdist != "success" -%}
8
+ Build matrix failed for tag {{ tag_link }} at {{ commit_link }}. Publish skipped.
9
+ {% else -%}
10
+ Publish failed for tag {{ tag_link }} at {{ commit_link }}.
11
+ {% endif %}
12
+
13
+ ### Builds
14
+
15
+ | Platform | Target | Status | Artifact |
16
+ |---|---|---|---|
17
+ {% for label, target, path in platforms %}
18
+ | {{ label }} | {{ ('`' ~ target ~ '`') if target else 'β€”' }} | {{ 'βœ…' if path else '❌' }} | {{ ('`' ~ path.name ~ '`') if path else 'β€”' }} |
19
+ {% endfor %}
20
+ {% if is_tag and publish == "success" %}
21
+
22
+ ### Install
23
+
24
+ ```bash
25
+ pip install prose-formatter=={{ version }}
26
+ ```
27
+
28
+ Each artifact ships a [SLSA build-provenance attestation](https://slsa.dev/spec/v1.0/provenance) verifiable on the [PyPI project page]({{ pypi_url }}).
29
+ {% endif %}
@@ -0,0 +1,47 @@
1
+ name : πŸͺ» Check
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ command:
7
+ description : The cargo command to run, passed straight to bash inside the runner.
8
+ required : true
9
+ type : string
10
+ save-cache:
11
+ default : false
12
+ description : When true the mise and Cargo caches write back to GHA. Set true only on main-branch runs.
13
+ type : boolean
14
+ shared-key:
15
+ default : prose
16
+ description : Swatinem cache scope. Distinct keys allow per-profile cache isolation.
17
+ type : string
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ env:
23
+ CARGO_PROFILE_DEV_DEBUG : line-tables-only
24
+ CARGO_TERM_COLOR : always
25
+
26
+ jobs:
27
+ cargo:
28
+ name : ${{ inputs.command }}
29
+ runs-on : ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
32
+
33
+ - name: Install mise tools
34
+ uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151
35
+ with:
36
+ cache : true
37
+ cache_save : ${{ inputs.save-cache }}
38
+
39
+ - name: Restore Cargo cache
40
+ uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
41
+ with:
42
+ cache-on-failure : 'true'
43
+ save-if : ${{ inputs.save-cache }}
44
+ shared-key : ${{ inputs.shared-key }}
45
+
46
+ - name : Run ${{ inputs.command }}
47
+ run : ${{ inputs.command }}
@@ -0,0 +1,57 @@
1
+ name : πŸͺ» CI
2
+ run-name : πŸͺ» CI Β· ${{ github.head_ref || github.ref_name }}
3
+
4
+ on:
5
+ pull_request:
6
+ push:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ concurrency:
11
+ cancel-in-progress : ${{ github.event_name == 'pull_request' }}
12
+ group : ${{ github.workflow }}-${{ github.head_ref || github.ref }}
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ check:
19
+ name : ${{ matrix.name }}
20
+ uses : ./.github/workflows/check.yml
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ include:
25
+ - command : cargo fmt --all --check
26
+ name : πŸͺΆ Format
27
+ shared-key : prose-fmt
28
+ - command : cargo machete
29
+ name : πŸͺ“ Unused
30
+ shared-key : prose-audit
31
+ - command : cargo clippy --all-targets --locked -- -D warnings
32
+ name : πŸ“Ž Clippy
33
+ shared-key : prose-build
34
+ - command : cargo build --all-targets --locked
35
+ name : πŸ—œοΈ Build
36
+ shared-key : prose-build
37
+ - command : cargo test --locked
38
+ name : βš–οΈ Test
39
+ shared-key : prose-build
40
+ with:
41
+ command : ${{ matrix.command }}
42
+ save-cache : ${{ github.event_name == 'push' }}
43
+ shared-key : ${{ matrix.shared-key }}
44
+
45
+ gate:
46
+ name : πŸ—žοΈ Brief
47
+ needs : check
48
+ if : always()
49
+ runs-on : ubuntu-latest
50
+ steps:
51
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
52
+ - uses: ./.github/actions/provision-uv
53
+
54
+ - name: Summarize and gate
55
+ env:
56
+ RESULT : ${{ needs.check.result }}
57
+ run: ./.github/scripts/summary.py ci
@@ -0,0 +1,158 @@
1
+ # Prose release pipeline Β· tag-driven publish to PyPI via OIDC.
2
+ #
3
+ # Triggers on bare-semver tag push (build + publish) and packaging-relevant PRs
4
+ # (build dry-run only). Builds wheels for Linux x86_64/aarch64, macOS
5
+ # x86_64/aarch64, Windows x86_64, plus an sdist. Trusted publishing means
6
+ # no API tokens are stored in repo or org secrets.
7
+ #
8
+ # The PyPI trusted-publisher contract must exist before the first tag push.
9
+ # Field values, set under Account β†’ Publishing on pypi.org, must match:
10
+ #
11
+ # PyPI Project Name prose-formatter
12
+ # Owner Jybbs
13
+ # Repository name prose
14
+ # Workflow filename release.yml
15
+ # Environment name release
16
+ #
17
+ # Renaming this file, the `release` environment, the repo, or the owner
18
+ # breaks the trust relationship. Update PyPI before the next tag.
19
+ #
20
+ # https://docs.pypi.org/trusted-publishers/adding-a-publisher/
21
+
22
+ name : πŸͺ» Release
23
+ run-name : πŸͺ» Release Β· ${{ github.head_ref || github.ref_name }}
24
+
25
+ on:
26
+ push:
27
+ tags: ['[0-9]*']
28
+ pull_request:
29
+ paths:
30
+ - pyproject.toml
31
+ - Cargo.toml
32
+ - .github/workflows/release.yml
33
+
34
+ concurrency:
35
+ cancel-in-progress : ${{ github.event_name == 'pull_request' }}
36
+ group : ${{ github.workflow }}-${{ github.head_ref || github.ref }}
37
+
38
+ permissions:
39
+ contents: read
40
+
41
+ jobs:
42
+ plan:
43
+ name : πŸ—ΊοΈ Plan
44
+ runs-on : ubuntu-latest
45
+ timeout-minutes : 5
46
+ steps:
47
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
48
+ - uses: ./.github/actions/provision-uv
49
+
50
+ - name : Parse tag and validate versions
51
+ run : ./.github/scripts/parse-version.py
52
+
53
+ build:
54
+ name : 🎻 ${{ matrix.name }}
55
+ needs : plan
56
+ runs-on : ${{ matrix.runner }}
57
+ timeout-minutes : 30
58
+ strategy:
59
+ fail-fast: false
60
+ matrix:
61
+ include:
62
+ - name : linux-x86_64
63
+ runner : ubuntu-latest
64
+ target : x86_64-unknown-linux-gnu
65
+ manylinux : auto
66
+ - name : linux-aarch64
67
+ runner : ubuntu-24.04-arm
68
+ target : aarch64-unknown-linux-gnu
69
+ manylinux : auto
70
+ - name : macos-x86_64
71
+ runner : macos-15-intel
72
+ target : x86_64-apple-darwin
73
+ - name : macos-aarch64
74
+ runner : macos-latest
75
+ target : aarch64-apple-darwin
76
+ - name : windows-x86_64
77
+ runner : windows-latest
78
+ target : x86_64-pc-windows-msvc
79
+ steps:
80
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
81
+ - uses: ./.github/actions/build-wheel
82
+ with:
83
+ command : build
84
+ target : ${{ matrix.target }}
85
+ manylinux : ${{ matrix.manylinux }}
86
+ args : --release --locked
87
+ name : ${{ matrix.name }}
88
+
89
+ sdist:
90
+ name : 🚒 sdist
91
+ needs : plan
92
+ runs-on : ubuntu-latest
93
+ timeout-minutes : 10
94
+ steps:
95
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
96
+ - uses: ./.github/actions/build-wheel
97
+ with:
98
+ command : sdist
99
+
100
+ publish:
101
+ name : ${{ github.ref_type == 'tag' && 'πŸ“― Publish to PyPI' || 'πŸ•―οΈ Publish dry-run' }}
102
+ needs : [build, sdist]
103
+ runs-on : ubuntu-latest
104
+ timeout-minutes : 15
105
+ environment:
106
+ name : release
107
+ url : https://pypi.org/p/prose-formatter
108
+ permissions:
109
+ id-token: write
110
+ steps:
111
+ - name: Download all artifacts
112
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
113
+ with:
114
+ path : dist
115
+ pattern : wheels-*
116
+ merge-multiple : true
117
+
118
+ - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b
119
+ with:
120
+ cache-dependency-glob: ""
121
+
122
+ - name: Smoke-install built wheel
123
+ run: |
124
+ uv tool install --no-index --find-links=dist prose-formatter
125
+ prose --version
126
+
127
+ - name: Generate PEP 740 attestations
128
+ uses: astral-sh/attest-action@f589a42a7efb6fe400b4f400de60b4bc90390027
129
+ if: github.ref_type == 'tag'
130
+
131
+ - name: Publish to PyPI
132
+ if: github.ref_type == 'tag'
133
+ run: uv publish --trusted-publishing=always dist/*
134
+
135
+ gate:
136
+ name : πŸ—žοΈ Brief
137
+ needs : [build, sdist, publish]
138
+ if : always()
139
+ runs-on : ubuntu-latest
140
+ timeout-minutes : 5
141
+ steps:
142
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
143
+ - uses: ./.github/actions/provision-uv
144
+
145
+ - name: Download all artifacts
146
+ if: needs.build.result != 'cancelled' && needs.sdist.result != 'cancelled'
147
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
148
+ with:
149
+ path : dist
150
+ pattern : wheels-*
151
+ merge-multiple : true
152
+
153
+ - name: Write release summary
154
+ env:
155
+ BUILD : ${{ needs.build.result }}
156
+ SDIST : ${{ needs.sdist.result }}
157
+ PUBLISH : ${{ needs.publish.result }}
158
+ run: ./.github/scripts/summary.py release
@@ -0,0 +1,21 @@
1
+ /target/
2
+ /dist/
3
+ /wheels/
4
+
5
+ *.pyc
6
+ __pycache__/
7
+ *.so
8
+ *.dylib
9
+ *.dll
10
+
11
+ .venv/
12
+ .env
13
+ .envrc
14
+
15
+ .DS_Store
16
+ *.swp
17
+ *.swo
18
+
19
+ .vscode/
20
+ .idea/
21
+ .claude/settings.local.json