djlintr 0.5.9__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 (212) hide show
  1. djlintr-0.5.9/.envrc +1 -0
  2. djlintr-0.5.9/.github/dependabot.yml +16 -0
  3. djlintr-0.5.9/.github/workflows/ci.yml +137 -0
  4. djlintr-0.5.9/.github/workflows/pypi.yml +80 -0
  5. djlintr-0.5.9/.gitignore +6 -0
  6. djlintr-0.5.9/AGENTS.md +132 -0
  7. djlintr-0.5.9/CHANGELOG.md +100 -0
  8. djlintr-0.5.9/Cargo.lock +999 -0
  9. djlintr-0.5.9/Cargo.toml +38 -0
  10. djlintr-0.5.9/GEMINI.md +132 -0
  11. djlintr-0.5.9/LICENSE +27 -0
  12. djlintr-0.5.9/Makefile +47 -0
  13. djlintr-0.5.9/PKG-INFO +89 -0
  14. djlintr-0.5.9/README.md +74 -0
  15. djlintr-0.5.9/bench_files/file_0.html +98 -0
  16. djlintr-0.5.9/bench_files/file_1.html +98 -0
  17. djlintr-0.5.9/bench_files/file_10.html +98 -0
  18. djlintr-0.5.9/bench_files/file_11.html +98 -0
  19. djlintr-0.5.9/bench_files/file_12.html +98 -0
  20. djlintr-0.5.9/bench_files/file_13.html +98 -0
  21. djlintr-0.5.9/bench_files/file_14.html +98 -0
  22. djlintr-0.5.9/bench_files/file_15.html +98 -0
  23. djlintr-0.5.9/bench_files/file_16.html +98 -0
  24. djlintr-0.5.9/bench_files/file_17.html +98 -0
  25. djlintr-0.5.9/bench_files/file_18.html +98 -0
  26. djlintr-0.5.9/bench_files/file_19.html +98 -0
  27. djlintr-0.5.9/bench_files/file_2.html +98 -0
  28. djlintr-0.5.9/bench_files/file_20.html +98 -0
  29. djlintr-0.5.9/bench_files/file_21.html +98 -0
  30. djlintr-0.5.9/bench_files/file_22.html +98 -0
  31. djlintr-0.5.9/bench_files/file_23.html +98 -0
  32. djlintr-0.5.9/bench_files/file_24.html +98 -0
  33. djlintr-0.5.9/bench_files/file_25.html +98 -0
  34. djlintr-0.5.9/bench_files/file_26.html +98 -0
  35. djlintr-0.5.9/bench_files/file_27.html +98 -0
  36. djlintr-0.5.9/bench_files/file_28.html +98 -0
  37. djlintr-0.5.9/bench_files/file_29.html +98 -0
  38. djlintr-0.5.9/bench_files/file_3.html +98 -0
  39. djlintr-0.5.9/bench_files/file_30.html +98 -0
  40. djlintr-0.5.9/bench_files/file_31.html +98 -0
  41. djlintr-0.5.9/bench_files/file_32.html +98 -0
  42. djlintr-0.5.9/bench_files/file_33.html +98 -0
  43. djlintr-0.5.9/bench_files/file_34.html +98 -0
  44. djlintr-0.5.9/bench_files/file_35.html +98 -0
  45. djlintr-0.5.9/bench_files/file_36.html +98 -0
  46. djlintr-0.5.9/bench_files/file_37.html +98 -0
  47. djlintr-0.5.9/bench_files/file_38.html +98 -0
  48. djlintr-0.5.9/bench_files/file_39.html +98 -0
  49. djlintr-0.5.9/bench_files/file_4.html +98 -0
  50. djlintr-0.5.9/bench_files/file_40.html +98 -0
  51. djlintr-0.5.9/bench_files/file_41.html +98 -0
  52. djlintr-0.5.9/bench_files/file_42.html +98 -0
  53. djlintr-0.5.9/bench_files/file_43.html +98 -0
  54. djlintr-0.5.9/bench_files/file_44.html +98 -0
  55. djlintr-0.5.9/bench_files/file_45.html +98 -0
  56. djlintr-0.5.9/bench_files/file_46.html +98 -0
  57. djlintr-0.5.9/bench_files/file_47.html +98 -0
  58. djlintr-0.5.9/bench_files/file_48.html +98 -0
  59. djlintr-0.5.9/bench_files/file_49.html +98 -0
  60. djlintr-0.5.9/bench_files/file_5.html +98 -0
  61. djlintr-0.5.9/bench_files/file_6.html +98 -0
  62. djlintr-0.5.9/bench_files/file_7.html +98 -0
  63. djlintr-0.5.9/bench_files/file_8.html +98 -0
  64. djlintr-0.5.9/bench_files/file_9.html +98 -0
  65. djlintr-0.5.9/benches/linter_bench.rs +43 -0
  66. djlintr-0.5.9/flake.lock +96 -0
  67. djlintr-0.5.9/flake.nix +38 -0
  68. djlintr-0.5.9/plan.md +124 -0
  69. djlintr-0.5.9/pyproject.toml +26 -0
  70. djlintr-0.5.9/scripts/compare_lint.py +128 -0
  71. djlintr-0.5.9/scripts/compare_reformat.py +101 -0
  72. djlintr-0.5.9/scripts/fetch_test_data.sh +25 -0
  73. djlintr-0.5.9/src/config.rs +182 -0
  74. djlintr-0.5.9/src/formatter/mod.rs +1970 -0
  75. djlintr-0.5.9/src/formatter/tokenizer.rs +263 -0
  76. djlintr-0.5.9/src/lib.rs +26 -0
  77. djlintr-0.5.9/src/linter/mod.rs +1113 -0
  78. djlintr-0.5.9/src/main.rs +225 -0
  79. djlintr-0.5.9/test_djlint_collapse.py +21 -0
  80. djlintr-0.5.9/tests/attribute_rules.rs +26 -0
  81. djlintr-0.5.9/tests/attribute_wrapping.rs +23 -0
  82. djlintr-0.5.9/tests/batch_1_rules.rs +134 -0
  83. djlintr-0.5.9/tests/batch_2_rules.rs +170 -0
  84. djlintr-0.5.9/tests/batch_3_rules.rs +111 -0
  85. djlintr-0.5.9/tests/case_rules.rs +48 -0
  86. djlintr-0.5.9/tests/custom_blocks.rs +39 -0
  87. djlintr-0.5.9/tests/debug_tokens.rs +12 -0
  88. djlintr-0.5.9/tests/django_linter.rs +145 -0
  89. djlintr-0.5.9/tests/djlint_off.rs +85 -0
  90. djlintr-0.5.9/tests/formatter_basics.rs +88 -0
  91. djlintr-0.5.9/tests/image_rules.rs +42 -0
  92. djlintr-0.5.9/tests/linter_h005.rs +30 -0
  93. djlintr-0.5.9/tests/minimal_parity.rs +120 -0
  94. djlintr-0.5.9/tests/parity_data/djlint_off.html +6 -0
  95. djlintr-0.5.9/tests/parity_data/extra/duplicate.html +1 -0
  96. djlintr-0.5.9/tests/parity_data/extra/h012.html +1 -0
  97. djlintr-0.5.9/tests/parity_data/extra/test_colon.html +2 -0
  98. djlintr-0.5.9/tests/parity_data/extra/test_digit.html +1 -0
  99. djlintr-0.5.9/tests/parity_data/extra/test_gt.html +1 -0
  100. djlintr-0.5.9/tests/parity_data/extra/test_html.html +1 -0
  101. djlintr-0.5.9/tests/parity_data/extra/test_jump.html +1 -0
  102. djlintr-0.5.9/tests/parity_data/extra/test_multi.html +1 -0
  103. djlintr-0.5.9/tests/parity_data/extra/test_rev.html +1 -0
  104. djlintr-0.5.9/tests/parity_data/extra/test_second.html +1 -0
  105. djlintr-0.5.9/tests/parity_data/extra/test_spaces.html +4 -0
  106. djlintr-0.5.9/tests/parity_data/extra/test_tagname.html +1 -0
  107. djlintr-0.5.9/tests/parity_data/extra/test_template.html +1 -0
  108. djlintr-0.5.9/tests/parity_data/extra/test_triple.html +1 -0
  109. djlintr-0.5.9/tests/parity_data/extra/test_twotags.html +1 -0
  110. djlintr-0.5.9/tests/parity_data/extra/test_underscore.html +1 -0
  111. djlintr-0.5.9/tests/parity_data/gearspotting/404.html +27 -0
  112. djlintr-0.5.9/tests/parity_data/gearspotting/500.html +21 -0
  113. djlintr-0.5.9/tests/parity_data/gearspotting/admin/login.html +47 -0
  114. djlintr-0.5.9/tests/parity_data/gearspotting/base.html +99 -0
  115. djlintr-0.5.9/tests/parity_data/gearspotting/blog/add_post.html +19 -0
  116. djlintr-0.5.9/tests/parity_data/gearspotting/blog/index.html +31 -0
  117. djlintr-0.5.9/tests/parity_data/gearspotting/blog/post.html +21 -0
  118. djlintr-0.5.9/tests/parity_data/gearspotting/flatpages/default.html +73 -0
  119. djlintr-0.5.9/tests/parity_data/gearspotting/gear/add_link.html +7 -0
  120. djlintr-0.5.9/tests/parity_data/gearspotting/gear/add_photo.html +7 -0
  121. djlintr-0.5.9/tests/parity_data/gearspotting/gear/gear_confirm_delete.html +9 -0
  122. djlintr-0.5.9/tests/parity_data/gearspotting/gear/gear_detail.html +102 -0
  123. djlintr-0.5.9/tests/parity_data/gearspotting/gear/gear_form.html +62 -0
  124. djlintr-0.5.9/tests/parity_data/gearspotting/gear/gear_list.html +20 -0
  125. djlintr-0.5.9/tests/parity_data/gearspotting/gear/gear_tag_list.html +19 -0
  126. djlintr-0.5.9/tests/parity_data/gearspotting/gear/index.html +35 -0
  127. djlintr-0.5.9/tests/parity_data/gearspotting/gear/tags.html +14 -0
  128. djlintr-0.5.9/tests/parity_data/gearspotting/homepage.html +49 -0
  129. djlintr-0.5.9/tests/parity_data/gearspotting/index.html +46 -0
  130. djlintr-0.5.9/tests/parity_data/gearspotting/main/search.html +33 -0
  131. djlintr-0.5.9/tests/parity_data/gearspotting/main/tags.html +15 -0
  132. djlintr-0.5.9/tests/parity_data/gearspotting/manufacturer/add_gear.html +7 -0
  133. djlintr-0.5.9/tests/parity_data/gearspotting/manufacturer/add_link.html +7 -0
  134. djlintr-0.5.9/tests/parity_data/gearspotting/manufacturer/index.html +23 -0
  135. djlintr-0.5.9/tests/parity_data/gearspotting/manufacturer/manufacturer_detail.html +62 -0
  136. djlintr-0.5.9/tests/parity_data/gearspotting/manufacturer/manufacturer_form.html +52 -0
  137. djlintr-0.5.9/tests/parity_data/gearspotting/manufacturer/manufacturer_list.html +23 -0
  138. djlintr-0.5.9/tests/parity_data/gearspotting/musician/add_gear.html +7 -0
  139. djlintr-0.5.9/tests/parity_data/gearspotting/musician/add_link.html +7 -0
  140. djlintr-0.5.9/tests/parity_data/gearspotting/musician/add_photo.html +7 -0
  141. djlintr-0.5.9/tests/parity_data/gearspotting/musician/index.html +23 -0
  142. djlintr-0.5.9/tests/parity_data/gearspotting/musician/musician_detail.html +113 -0
  143. djlintr-0.5.9/tests/parity_data/gearspotting/musician/musician_form.html +83 -0
  144. djlintr-0.5.9/tests/parity_data/gearspotting/musician/musician_list.html +23 -0
  145. djlintr-0.5.9/tests/parity_data/gearspotting/musician/musician_tag_list.html +19 -0
  146. djlintr-0.5.9/tests/parity_data/gearspotting/musician/tags.html +14 -0
  147. djlintr-0.5.9/tests/parity_data/gearspotting/musiciangear/add_link.html +7 -0
  148. djlintr-0.5.9/tests/parity_data/gearspotting/musiciangear/add_photo.html +7 -0
  149. djlintr-0.5.9/tests/parity_data/gearspotting/musiciangear/musiciangear_detail.html +74 -0
  150. djlintr-0.5.9/tests/parity_data/gearspotting/musiciangear/musiciangear_form.html +62 -0
  151. djlintr-0.5.9/tests/parity_data/gearspotting/musiciangear/musiciangear_list.html +23 -0
  152. djlintr-0.5.9/tests/parity_data/gearspotting/photo/import_photo.html +28 -0
  153. djlintr-0.5.9/tests/parity_data/gearspotting/photo/photo_detail.html +74 -0
  154. djlintr-0.5.9/tests/parity_data/gearspotting/registration/activate.html +10 -0
  155. djlintr-0.5.9/tests/parity_data/gearspotting/registration/activation_complete.html +7 -0
  156. djlintr-0.5.9/tests/parity_data/gearspotting/registration/activation_email.txt +11 -0
  157. djlintr-0.5.9/tests/parity_data/gearspotting/registration/activation_email_subject.txt +1 -0
  158. djlintr-0.5.9/tests/parity_data/gearspotting/registration/login.html +26 -0
  159. djlintr-0.5.9/tests/parity_data/gearspotting/registration/logout.html +5 -0
  160. djlintr-0.5.9/tests/parity_data/gearspotting/registration/password_change_done.html +6 -0
  161. djlintr-0.5.9/tests/parity_data/gearspotting/registration/password_change_form.html +10 -0
  162. djlintr-0.5.9/tests/parity_data/gearspotting/registration/password_reset_complete.html +5 -0
  163. djlintr-0.5.9/tests/parity_data/gearspotting/registration/password_reset_confirm.html +11 -0
  164. djlintr-0.5.9/tests/parity_data/gearspotting/registration/password_reset_done.html +8 -0
  165. djlintr-0.5.9/tests/parity_data/gearspotting/registration/password_reset_email.html +13 -0
  166. djlintr-0.5.9/tests/parity_data/gearspotting/registration/password_reset_form.html +12 -0
  167. djlintr-0.5.9/tests/parity_data/gearspotting/registration/profile.html +4 -0
  168. djlintr-0.5.9/tests/parity_data/gearspotting/registration/registration_base.html +1 -0
  169. djlintr-0.5.9/tests/parity_data/gearspotting/registration/registration_complete.html +6 -0
  170. djlintr-0.5.9/tests/parity_data/gearspotting/registration/registration_form.html +10 -0
  171. djlintr-0.5.9/tests/parity_data/minimal/attr_wrap.html +15 -0
  172. djlintr-0.5.9/tests/parity_data/minimal/blocks.html +22 -0
  173. djlintr-0.5.9/tests/parity_data/minimal/consolidated.html +37 -0
  174. djlintr-0.5.9/tests/parity_data/minimal/email.html +9 -0
  175. djlintr-0.5.9/tests/parity_data/minimal/indent.html +16 -0
  176. djlintr-0.5.9/tests/parity_data/minimal/inline.html +6 -0
  177. djlintr-0.5.9/tests/parity_data/minimal/script.html +7 -0
  178. djlintr-0.5.9/tests/parity_data/sebastian/404.html +1 -0
  179. djlintr-0.5.9/tests/parity_data/sebastian/add_card.html +101 -0
  180. djlintr-0.5.9/tests/parity_data/sebastian/base.html +37 -0
  181. djlintr-0.5.9/tests/parity_data/sebastian/card.html +72 -0
  182. djlintr-0.5.9/tests/parity_data/sebastian/deck.html +51 -0
  183. djlintr-0.5.9/tests/parity_data/sebastian/decks.html +19 -0
  184. djlintr-0.5.9/tests/parity_data/sebastian/index.html +7 -0
  185. djlintr-0.5.9/tests/parity_data/sebastian/registration/login.html +22 -0
  186. djlintr-0.5.9/tests/parity_data/sebastian/stats.html +78 -0
  187. djlintr-0.5.9/tests/parity_data/sebastian/test.html +112 -0
  188. djlintr-0.5.9/tests/parity_data/svg/icon.html +12 -0
  189. djlintr-0.5.9/tests/parity_regressions.rs +164 -0
  190. djlintr-0.5.9/tests/reformat_parity.rs +37 -0
  191. djlintr-0.5.9/tests/reproduce_attr_wrap_boundary.rs +52 -0
  192. djlintr-0.5.9/tests/reproduce_closing_inline_chain_indent.rs +24 -0
  193. djlintr-0.5.9/tests/reproduce_django_collapse.rs +25 -0
  194. djlintr-0.5.9/tests/reproduce_django_var_space.rs +19 -0
  195. djlintr-0.5.9/tests/reproduce_email_newlines.rs +29 -0
  196. djlintr-0.5.9/tests/reproduce_for_collapse_line_length.rs +48 -0
  197. djlintr-0.5.9/tests/reproduce_h014.rs +34 -0
  198. djlintr-0.5.9/tests/reproduce_h025.rs +48 -0
  199. djlintr-0.5.9/tests/reproduce_indent_tracking.rs +63 -0
  200. djlintr-0.5.9/tests/reproduce_inline_closing_newline.rs +34 -0
  201. djlintr-0.5.9/tests/reproduce_multiline_inline_content.rs +28 -0
  202. djlintr-0.5.9/tests/reproduce_script_close_indent.rs +25 -0
  203. djlintr-0.5.9/tests/reproduce_script_issue.rs +49 -0
  204. djlintr-0.5.9/tests/reproduce_space_stripping.rs +10 -0
  205. djlintr-0.5.9/tests/reproduce_style_semicolon.rs +43 -0
  206. djlintr-0.5.9/tests/reproduce_svg_indent.rs +35 -0
  207. djlintr-0.5.9/tests/reproduce_unclosed_inline_condense.rs +37 -0
  208. djlintr-0.5.9/tests/reproduce_unclosed_tag_indent_leak.rs +25 -0
  209. djlintr-0.5.9/tests/reproduce_verbatim_close_indent.rs +28 -0
  210. djlintr-0.5.9/tests/svg_parity.rs +83 -0
  211. djlintr-0.5.9/tests/test_attr_spacing.rs +35 -0
  212. djlintr-0.5.9/tests/utf8_safety.rs +13 -0
djlintr-0.5.9/.envrc ADDED
@@ -0,0 +1 @@
1
+ use flake
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+
8
+ - package-ecosystem: "cargo"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
12
+
13
+ - package-ecosystem: "nix"
14
+ directory: "/"
15
+ schedule:
16
+ interval: "weekly"
@@ -0,0 +1,137 @@
1
+ name: CI & Release
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ tags: [ 'v*' ]
7
+ pull_request:
8
+ branches: [ main ]
9
+
10
+ env:
11
+ CARGO_TERM_COLOR: always
12
+
13
+ jobs:
14
+ lint:
15
+ name: Lint
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+ - name: Install Rust
20
+ uses: dtolnay/rust-toolchain@stable
21
+ with:
22
+ components: clippy, rustfmt
23
+ - name: Rust Cache
24
+ uses: Swatinem/rust-cache@v2
25
+ - name: Run lint
26
+ run: make lint
27
+
28
+ test:
29
+ name: Test
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v6
33
+ - name: Install Rust
34
+ uses: dtolnay/rust-toolchain@stable
35
+ - name: Rust Cache
36
+ uses: Swatinem/rust-cache@v2
37
+ - name: Run tests
38
+ run: cargo test
39
+
40
+ parity:
41
+ name: Linter Parity
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/checkout@v6
45
+ - name: Install Rust
46
+ uses: dtolnay/rust-toolchain@stable
47
+ - name: Rust Cache
48
+ uses: Swatinem/rust-cache@v2
49
+ - name: Set up Python
50
+ uses: actions/setup-python@v6
51
+ with:
52
+ python-version: '3.12'
53
+ - name: Install djlint
54
+ run: make install-djlint
55
+ - name: Fetch test data
56
+ run: make fetch-test-data
57
+ - name: Run parity comparison
58
+ run: make compare-lint
59
+ - name: Run format parity comparison
60
+ run: make compare-reformat
61
+
62
+ build:
63
+ name: Build (${{ matrix.target }})
64
+ needs: [lint, test, parity]
65
+ if: startsWith(github.ref, 'refs/tags/v')
66
+ runs-on: ${{ matrix.os }}
67
+ strategy:
68
+ fail-fast: false
69
+ matrix:
70
+ include:
71
+ - os: ubuntu-latest
72
+ target: x86_64-unknown-linux-musl
73
+ artifact_name: djlintr-linux-amd64
74
+ - os: macos-latest
75
+ target: x86_64-apple-darwin
76
+ artifact_name: djlintr-macos-amd64
77
+ - os: macos-latest
78
+ target: aarch64-apple-darwin
79
+ artifact_name: djlintr-macos-arm64
80
+ - os: windows-latest
81
+ target: x86_64-pc-windows-msvc
82
+ artifact_name: djlintr-windows-amd64.exe
83
+
84
+ steps:
85
+ - uses: actions/checkout@v6
86
+ - name: Install Rust
87
+ uses: dtolnay/rust-toolchain@stable
88
+ with:
89
+ targets: ${{ matrix.target }}
90
+
91
+ - name: Install musl-tools
92
+ if: matrix.target == 'x86_64-unknown-linux-musl'
93
+ run: sudo apt-get install -y musl-tools
94
+
95
+ - name: Rust Cache
96
+ uses: Swatinem/rust-cache@v2
97
+ with:
98
+ key: ${{ matrix.target }}
99
+
100
+ - name: Build
101
+ run: cargo build --release --target ${{ matrix.target }}
102
+
103
+ - name: Rename binary
104
+ shell: bash
105
+ run: |
106
+ if [ "${{ matrix.os }}" = "windows-latest" ]; then
107
+ mv target/${{ matrix.target }}/release/djlintr.exe ${{ matrix.artifact_name }}
108
+ else
109
+ mv target/${{ matrix.target }}/release/djlintr ${{ matrix.artifact_name }}
110
+ fi
111
+
112
+ - name: Upload Artifact
113
+ uses: actions/upload-artifact@v7
114
+ with:
115
+ name: ${{ matrix.artifact_name }}
116
+ path: ${{ matrix.artifact_name }}
117
+
118
+ release:
119
+ name: Create Release
120
+ needs: build
121
+ if: startsWith(github.ref, 'refs/tags/v')
122
+ runs-on: ubuntu-latest
123
+ permissions:
124
+ contents: write
125
+ steps:
126
+ - uses: actions/download-artifact@v8
127
+ with:
128
+ path: artifacts
129
+ merge-multiple: true
130
+
131
+ - name: Create Release
132
+ uses: softprops/action-gh-release@v3
133
+ with:
134
+ files: artifacts/*
135
+ generate_release_notes: true
136
+ draft: false
137
+ prerelease: false
@@ -0,0 +1,80 @@
1
+ name: Build and Publish Python Wheels
2
+
3
+ on:
4
+ push:
5
+ tags: [ 'v*' ]
6
+
7
+ jobs:
8
+ build-wheels:
9
+ name: Build Wheels (${{ matrix.target }})
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ include:
15
+ - os: ubuntu-latest
16
+ target: x86_64
17
+ - os: ubuntu-latest
18
+ target: aarch64
19
+ - os: macos-latest
20
+ target: x86_64
21
+ - os: macos-latest
22
+ target: aarch64
23
+ - os: windows-latest
24
+ target: x86_64
25
+
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+
29
+ - name: Set up QEMU
30
+ if: matrix.os == 'ubuntu-latest' && matrix.target == 'aarch64'
31
+ uses: docker/setup-qemu-action@v3
32
+
33
+ - name: Build wheels
34
+ uses: PyO3/maturin-action@v1
35
+ with:
36
+ target: ${{ matrix.target }}
37
+ args: --release --out dist
38
+ sccache: 'true'
39
+
40
+ - name: Upload wheels
41
+ uses: actions/upload-artifact@v4
42
+ with:
43
+ name: wheels-${{ matrix.os }}-${{ matrix.target }}
44
+ path: dist
45
+
46
+ build-sdist:
47
+ name: Build sdist
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - name: Build sdist
53
+ uses: PyO3/maturin-action@v1
54
+ with:
55
+ command: sdist
56
+ args: --out dist
57
+
58
+ - name: Upload sdist
59
+ uses: actions/upload-artifact@v4
60
+ with:
61
+ name: wheels-sdist
62
+ path: dist
63
+
64
+ pypi-publish:
65
+ name: Publish to PyPI
66
+ needs: [build-wheels, build-sdist]
67
+ runs-on: ubuntu-latest
68
+ permissions:
69
+ id-token: write
70
+ steps:
71
+ - uses: actions/download-artifact@v4
72
+ with:
73
+ pattern: wheels-*
74
+ merge-multiple: true
75
+ path: dist
76
+
77
+ - name: Publish to PyPI
78
+ uses: pypa/gh-action-pypi-publish@release/v1
79
+ with:
80
+ skip-existing: true
@@ -0,0 +1,6 @@
1
+ /target
2
+ venv
3
+ .direnv
4
+ djlint-python
5
+ venv
6
+ temp_reformat
@@ -0,0 +1,132 @@
1
+ # Agent Guide: djlintr
2
+
3
+ This document provides guidance for AI agents on how to develop, test, and release `djlintr`.
4
+
5
+ ## Project Overview
6
+
7
+ `djlintr` is a fast HTML template linter and formatter, ported from the Python tool `djlint` to Rust. It aims for high performance and compatibility with the original tool.
8
+
9
+ ## Development Workflow
10
+
11
+ ### Building the Project
12
+
13
+ You can build the project using standard Cargo commands or the provided `Makefile`.
14
+
15
+ ```bash
16
+ # Debug build
17
+ make build
18
+ # or
19
+ cargo build
20
+
21
+ # Release build
22
+ make release
23
+ # or
24
+ cargo build --release
25
+ ```
26
+
27
+ ### Running the CLI
28
+
29
+ ```bash
30
+ cargo run -- [OPTIONS] <PATHS>...
31
+ ```
32
+
33
+ ### Testing
34
+
35
+ Always run tests before submitting changes.
36
+
37
+ ```bash
38
+ # Run all tests
39
+ make test
40
+ # or
41
+ cargo test
42
+
43
+ # Run a specific test file
44
+ cargo test --test <test_name>
45
+ ```
46
+
47
+ ### Linting and Formatting
48
+
49
+ Ensure the code adheres to Rust standards. **You MUST NOT consider a task finished until `make lint` passes.**
50
+
51
+ ```bash
52
+ # Run clippy and check formatting (used in CI)
53
+ make lint
54
+
55
+ # Apply formatting
56
+ make fmt
57
+ ```
58
+
59
+ ## Parity Testing
60
+
61
+ A key goal is parity with the original Python `djlint`. There is a specialized setup for comparing lint results.
62
+
63
+ 1. **Install djlint in a venv:**
64
+ ```bash
65
+ make install-djlint
66
+ ```
67
+ 2. **Fetch test data:**
68
+ ```bash
69
+ make fetch-test-data
70
+ ```
71
+ 3. **Run parity comparison:**
72
+ ```bash
73
+ make compare-lint
74
+ ```
75
+ This script compares the output of `djlintr` against `djlint` on a set of templates.
76
+
77
+ ## Release Process
78
+
79
+ We use `cargo-release` for managing versions and tags.
80
+
81
+ 1. **Preparation:**
82
+ - Ensure you are on the `main` branch.
83
+ - Ensure all tests, lint, and parity checks pass.
84
+ - Check that `CHANGELOG.md` is updated.
85
+
86
+ 2. **Execute Release:**
87
+ Run `cargo release` to bump the version, create a git tag, and push to the repository.
88
+ **Note:** `consolidate-commits` must be set to `false` in `Cargo.toml` for `{{version}}` placeholders to render correctly in commit messages.
89
+ ```bash
90
+ # Dry run
91
+ cargo release <patch|minor|major> --execute --dry-run
92
+
93
+ # Real release
94
+ cargo release <patch|minor|major> --execute
95
+ ```
96
+
97
+ 3. **CI Automation:**
98
+ Once a tag (e.g., `v0.5.2`) is pushed, the GitHub Actions workflow (`.github/workflows/ci.yml`) will:
99
+ - Run the full test suite.
100
+ - Build release binaries for Linux (x64), macOS (x64, ARM64), and Windows (x64).
101
+ - Create a new GitHub Release and upload the binaries.
102
+
103
+ ## Architectural Notes
104
+
105
+ - **Linter Rules:** Located in `src/linter/mod.rs`.
106
+ - **Formatter Logic:** Located in `src/formatter/`.
107
+ - **Configuration:** Handled in `src/config.rs`, supporting `.djlintrc` and `pyproject.toml`.
108
+ - **Parallelism:** Uses `rayon` for fast file processing.
109
+
110
+
111
+ ## TDD
112
+
113
+ When implementing new features or fixing bugs in the rust code, always
114
+ use strict red/green TDD. This means:
115
+
116
+ - start by adding a simple test case for the new feature or bugfix. pick
117
+ one aspect, happy path, edge case, etc. and focus on that.
118
+ - (red) run the tests to verify that the new test fails (but other existing
119
+ tests should continue to pass)
120
+ - implement a simple solution to get the new test passing
121
+ - (green) run tests again to check that the test now passes (and that all
122
+ other existing tests continue to pass)
123
+ - refactor the new code to make it cleaner
124
+ - verify that the tests pass again
125
+ - repeat this process until you are confident that the entire new
126
+ feature is implemented, the bug is fixed, etc.
127
+
128
+ IMPORTANT: DO NOT delete tests after finishing the process. If a test
129
+ is outdated or misleading, you must explain this to the user and get
130
+ explicit permission to remove or update it. You MAY run
131
+ individual tests instead of the entire suite to speed up the process,
132
+ but the entire suite must pass before you are done.
@@ -0,0 +1,100 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - **Python Packaging**: Added `maturin` configuration and a PyPI release GitHub action. `djlintr` can now be installed as a Python package via `pip install djlintr` or `uv pip install djlintr`.
13
+
14
+ ## [0.5.8] - 2026-05-16
15
+
16
+ ### Fixed
17
+
18
+ - **Tokenizer**: Improved tag identification to correctly handle quoted attribute values containing `>` characters (e.g. Alpine.js arrow functions), ensuring parity with `djlint` and preventing false-positive `H012` errors.
19
+
20
+ ## [0.5.7] - 2026-05-16
21
+
22
+ ### Fixed
23
+
24
+ - **H037 (Duplicate Attribute)**: Refined duplicate attribute detection to achieve full parity with `djlint`.
25
+
26
+ ## [0.5.3] - 2026-05-16
27
+
28
+ ### Fixed
29
+
30
+ - **H014 (Blank Lines)**: Strip newlines from reported match string to prevent extra blank lines in CLI output.
31
+
32
+ ## [0.5.1] - 2026-05-16
33
+
34
+ ### Fixed
35
+ - **100% Parity Reached**: Reproduced a specific `djlint` regex quirk for `H037` (duplicate attributes) that allowed it to jump across tags when nested quotes are present in template tags.
36
+ - **H014 (Blank Lines)**: Refined regex and ignored-block logic to match `djlint` exactly.
37
+ - **H030/H031 (Document Rules)**: Implemented a "commented out html" parity hack to match `djlint`'s document-level rule suppression.
38
+
39
+ ## [0.5.0] - 2026-05-16
40
+
41
+ ### Added
42
+ - **Ignored Blocks Logic**: Implemented `ignored_ranges` to skip linting inside `<script>`, `<style>`, `<pre>`, and `<textarea>` tags, as well as HTML comments, matching `djlint`'s behavior.
43
+ - **CLI & Config Alignment**: Added support for `--include` and `--ignore` flags.
44
+ - **New Regression Test Suite**: Added `tests/parity_regressions.rs` covering major fixes and behavioral changes.
45
+
46
+ ### Changed
47
+ - **Tokenizer & Offsets**: Updated the `Tokenizer` to include the byte `offset` for each token, improving lint error location accuracy.
48
+ - **H008 (Double Quotes)**: Restricted to specific attributes (`class`, `id`, `src`, etc.) to match `djlint`.
49
+ - **H010 (Lowercase Attributes)**: Now only checks actual attribute names, ignoring uppercase content within values.
50
+ - **H020 (Empty Tag Pairs)**: Skips whitespace between tags and requires the opening tag to have no attributes.
51
+ - **H025 (Orphan Tags)**: Replaced simple counter with a robust stack-based check for nested orphans.
52
+ - **H014 (Blank Lines)**: Improved masking of template tags before regex matching for better parity.
53
+ - **Default Rules**: Aligned rules disabled by default with `djlint` (`H017`, `H035`, `H036`, `H030`, `H031`).
54
+
55
+ ## [0.4.1] - 2026-05-12
56
+
57
+ ### Fixed
58
+ - Internal lint error (clippy manual-pattern-char-comparison) in `src/linter/mod.rs`.
59
+
60
+ ## [0.4.0] - 2026-05-10
61
+
62
+ ### Added
63
+ - Profile support (`--profile`) to match Python djlint's rule exclusion logic. Supported profiles: `html`, `django`, `jinja`, `nunjucks`, `handlebars`, `golang`, `angular`, and `all`.
64
+ - Default profile is `html`, which correctly excludes template-specific rules (`T`, `D`, `J`, etc.) by default, achieving parity with Python djlint.
65
+
66
+ ### Changed
67
+ - Simplified `T003` (named endblocks) implementation to match Python's regex exactly, removing the incorrect one-liner exception.
68
+
69
+ ## [0.3.0] - 2026-05-10
70
+
71
+ ### Added
72
+ - Support for `max-attribute-length` configuration option and CLI flag to control attribute wrapping.
73
+
74
+ ## [0.2.0] - 2026-05-10
75
+
76
+ ### Added
77
+ - Support for `custom_blocks` configuration option and CLI flag.
78
+ - Support for re-indenting Django/Jinja tags: `{% else %}`, `{% elif %}`, and `{% empty %}`.
79
+ - New `LICENSE` file (BSD 3-Clause).
80
+ - New `README.md` with installation and usage instructions.
81
+ - New `CHANGELOG.md` to track project changes.
82
+
83
+ ### Changed
84
+ - Improved Django/Jinja tag indentation logic to only indent known block tags or user-defined custom blocks, preventing incorrect indentation for self-closing tags like `{% url %}`.
85
+ - Updated project version to v0.2.0.
86
+
87
+ ## [0.1.1] - 2026-05-10
88
+
89
+ ### Added
90
+ - Basic HTML/Template tokenizer.
91
+ - Basic indentation logic.
92
+ - Initial linter rule engine with several HTML and Template rules.
93
+ - Parallel file processing support using `rayon`.
94
+ - CLI implementation using `clap`.
95
+ - Configuration support for `.djlintrc` and `pyproject.toml`.
96
+
97
+ ## [0.1.0] - 2026-05-09
98
+
99
+ ### Added
100
+ - Initial project setup and infrastructure.