dycw-pre-commit-hooks 0.14.39__py3-none-any.whl → 0.14.53__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dycw-pre-commit-hooks
3
- Version: 0.14.39
3
+ Version: 0.14.53
4
4
  Summary: Pre-commit hooks
5
5
  Author: Derek Wan
6
6
  Author-email: Derek Wan <d.wan@icloud.com>
@@ -24,34 +24,6 @@ Requires-Python: >=3.12
24
24
  Provides-Extra: cli
25
25
  Description-Content-Type: text/markdown
26
26
 
27
- # pre-commit-hooks
27
+ # `pre-commit-hooks`
28
28
 
29
- ## Overview
30
-
31
- My [`pre-commit`](https://pre-commit.com/) hooks.
32
-
33
- ## Installation
34
-
35
- 1. Install `pre-commit`.
36
-
37
- 1. Add the following to your `.pre-commit-config.yaml`:
38
-
39
- ```yaml
40
- repos:
41
- - repo: https://github.com/dycw/pre-commit-hooks
42
- rev: master
43
- hooks:
44
- - id: check-submodules-updated
45
- - id: check-version-bumped
46
- - id: format-requirements
47
- - id: mirror-files
48
- - id: replace-sequence-str
49
- - id: run-version-bump
50
- - id: tag-commits
51
- ```
52
-
53
- 1. Update your `.pre-commit-config.yaml`:
54
-
55
- ```bash
56
- pre-commit autoupdate
57
- ```
29
+ Pre-commit hooks
@@ -0,0 +1,33 @@
1
+ pre_commit_hooks/__init__.py,sha256=JuIXVFcc-7fpVd8XeieLl--VJpk5Yh5uoPICiimvE8g,60
2
+ pre_commit_hooks/configs/gitignore,sha256=pIcfamKg40Tg2aWiMyY4pxHkSGNITRFD-ByA2wWGHQI,5062
3
+ pre_commit_hooks/constants.py,sha256=fBF2677VZ0JrOrJ3et0gSqlOVY1-ZE9vHi6d5Sa0Rvo,5059
4
+ pre_commit_hooks/hooks/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
5
+ pre_commit_hooks/hooks/add_future_import_annotations.py,sha256=vUVaQIMrfPssrP0keiau-o8Jel2rpaXLi6pyT_d-QsU,1701
6
+ pre_commit_hooks/hooks/add_hooks.py,sha256=20xyvfRQQ8n7YajWA0pxCMl5KiZJc0S7qFPHaZf5nLo,29177
7
+ pre_commit_hooks/hooks/check_version_bumped.py,sha256=EIFQcACjM2_D4O4Yu01p-SzicAah1xklb_4KeU93V68,818
8
+ pre_commit_hooks/hooks/check_versions_consistent.py,sha256=grfvgVJKBKMxYk2K3Jbr7uM26cXmDRTjyXrTN_Wb2Bk,980
9
+ pre_commit_hooks/hooks/format_pre_commit_config.py,sha256=qPkPvRiocSXGEjO-QE0FfwM8T8XaBYevSXZB9KL5gr0,2142
10
+ pre_commit_hooks/hooks/format_requirements.py,sha256=R_FnEUx7jU3W5rWshLBKO2bX-cReHteF4iqm_mCnyCk,1474
11
+ pre_commit_hooks/hooks/replace_sequence_str.py,sha256=G7JQ4n-hSjW5asM4C77ps8JYv5eV31rvFmmcxQYty1o,1816
12
+ pre_commit_hooks/hooks/run_prek_autoupdate.py,sha256=SItY4GPTde7HXOaNy3zXsfFQFFZsc4hZzGzf380F0aI,1556
13
+ pre_commit_hooks/hooks/run_version_bump.py,sha256=8jIqEGD0UzRQ7LGgGmL05wB3p1NaWIrgOMXDe1DDmh4,1222
14
+ pre_commit_hooks/hooks/setup_bump_my_version.py,sha256=d9b7j7AjGwv0GnyNC10J1HbEu8tniNexZGbPEZvmpVE,3004
15
+ pre_commit_hooks/hooks/setup_ci_pull_request.py,sha256=B-P7bY49Q2_KWmJqnt7qfa_ajZvOYooV0fiNDRjBaUs,8932
16
+ pre_commit_hooks/hooks/setup_ci_push.py,sha256=wlGNRaG2U6YDRy6H5OTVpkYLAFZaxg2h_wiRFy4sFHU,3925
17
+ pre_commit_hooks/hooks/setup_coverage.py,sha256=tZlgOCqSbSRcPe_b4nkyo8k7QGLWqmRgnq7Qt_V6jy0,1653
18
+ pre_commit_hooks/hooks/setup_direnv.py,sha256=6B3n9k_Pxzu3hCapwqzHPytIYsxeyDPLVJoPl0FrkBQ,4180
19
+ pre_commit_hooks/hooks/setup_git.py,sha256=nB87iKOuCPpc52RvLMRKzP-HZO53NluaX12k1JgxjfE,1193
20
+ pre_commit_hooks/hooks/setup_pyproject.py,sha256=CviZAo8KCyFcTJ2EPAkbYQpqF3r2ocCEISMlvIt7ktk,5479
21
+ pre_commit_hooks/hooks/setup_pyright.py,sha256=N2LJBOlMtM7wmxdy8k0jM592185s2d2OHpMx7Oby3_k,2594
22
+ pre_commit_hooks/hooks/setup_readme.py,sha256=02gAjeKBp27P9Nw4gLx9xJeO9Z2ypPW7h64uXW-l4SM,1914
23
+ pre_commit_hooks/hooks/setup_ruff.py,sha256=aXbG7BEdqYG38TSFRo7t0JH9m3_npIId-qZxFrnuxKA,4710
24
+ pre_commit_hooks/hooks/update_ci_action_versions.py,sha256=hOS0QB_Hfyq__cVY5cMqtOqB-SnA4t-PE34DZkTm6Qk,1274
25
+ pre_commit_hooks/hooks/update_ci_extensions.py,sha256=RqANNdSmroum6I3mLa91qbNcFjUPv5sc17XTxdWD1Gg,793
26
+ pre_commit_hooks/hooks/update_requirements.py,sha256=bthf45CRsXgMsbcHVZ36zE0k9oWB_fWBZW8jkHPmHhc,5362
27
+ pre_commit_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ pre_commit_hooks/types.py,sha256=ObWi-OEEyZHlSYZA3iiJHGMDJ3jADntS_OpR0jXpkDk,515
29
+ pre_commit_hooks/utilities.py,sha256=5rm-8VLx2QX0XsDYhuCfveJIlau___fuF8QiHaD-9GY,15897
30
+ dycw_pre_commit_hooks-0.14.53.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
31
+ dycw_pre_commit_hooks-0.14.53.dist-info/entry_points.txt,sha256=Y4x0VObVGxlHcC2YTapOPviNkkStzzNzzU2XxBlLY3s,1515
32
+ dycw_pre_commit_hooks-0.14.53.dist-info/METADATA,sha256=fJ8tS3B9yfd5bWZTrUOQt_VR7eVEuPGjcccw-Jq-k8g,920
33
+ dycw_pre_commit_hooks-0.14.53.dist-info/RECORD,,
@@ -9,9 +9,14 @@ replace-sequence-str = pre_commit_hooks.hooks.replace_sequence_str:_main
9
9
  run-prek-autoupdate = pre_commit_hooks.hooks.run_prek_autoupdate:_main
10
10
  run-version-bump = pre_commit_hooks.hooks.run_version_bump:_main
11
11
  setup-bump-my-version = pre_commit_hooks.hooks.setup_bump_my_version:_main
12
+ setup-ci-pull-request = pre_commit_hooks.hooks.setup_ci_pull_request:_main
13
+ setup-ci-push = pre_commit_hooks.hooks.setup_ci_push:_main
14
+ setup-coverage = pre_commit_hooks.hooks.setup_coverage:_main
12
15
  setup-direnv = pre_commit_hooks.hooks.setup_direnv:_main
13
16
  setup-git = pre_commit_hooks.hooks.setup_git:_main
17
+ setup-pyproject = pre_commit_hooks.hooks.setup_pyproject:_main
14
18
  setup-pyright = pre_commit_hooks.hooks.setup_pyright:_main
19
+ setup-readme = pre_commit_hooks.hooks.setup_readme:_main
15
20
  setup-ruff = pre_commit_hooks.hooks.setup_ruff:_main
16
21
  update-ci-action-versions = pre_commit_hooks.hooks.update_ci_action_versions:_main
17
22
  update-ci-extensions = pre_commit_hooks.hooks.update_ci_extensions:_main
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.14.39"
3
+ __version__ = "0.14.53"
@@ -103,9 +103,21 @@ PRE_COMMIT_HOOKS_HOOK_KEYS = [
103
103
  THROTTLE_DURATION = 12 * HOUR
104
104
 
105
105
 
106
+ ci_pytest_os_option = option("--ci-pytest-os", type=ListStrs(), default=None)
107
+ ci_pytest_python_version_option = option(
108
+ "--ci-pytest-python-version", type=ListStrs(), default=None
109
+ )
110
+ ci_pytest_runs_on_option = option("--ci-pytest-runs-on", type=ListStrs(), default=None)
111
+ description_option = option("--description", type=str, default=None)
112
+ gitea_option = option("--gitea", is_flag=True, default=False)
106
113
  paths_argument = argument("paths", nargs=-1, type=utilities.click.Path())
107
114
  python_option = option("--python", is_flag=True, default=False)
108
- python_package_name_option = option("--python-package-name", type=str, default=None)
115
+ python_package_name_external_option = option(
116
+ "--python-package-name-external", type=str, default=None
117
+ )
118
+ python_package_name_internal_option = option(
119
+ "--python-package-name-internal", type=str, default=None
120
+ )
109
121
  python_uv_index_option = option("--python-uv-index", type=ListStrs(), default=None)
110
122
  python_uv_native_tls_option = option(
111
123
  "--python-uv-native-tls", is_flag=True, default=False
@@ -113,6 +125,7 @@ python_uv_native_tls_option = option(
113
125
  python_version_option = option(
114
126
  "--python-version", type=str, default=DEFAULT_PYTHON_VERSION
115
127
  )
128
+ repo_name_option = option("--repo-name", type=str, default=None)
116
129
  throttle_option = option("--throttle", is_flag=True, default=True)
117
130
 
118
131
 
@@ -156,11 +169,18 @@ __all__ = [
156
169
  "THROTTLE_DURATION",
157
170
  "UV_URL",
158
171
  "XMLFORMATTER_URL",
172
+ "ci_pytest_os_option",
173
+ "ci_pytest_python_version_option",
174
+ "ci_pytest_runs_on_option",
175
+ "description_option",
176
+ "gitea_option",
159
177
  "paths_argument",
160
178
  "python_option",
161
- "python_package_name_option",
179
+ "python_package_name_external_option",
180
+ "python_package_name_internal_option",
162
181
  "python_uv_index_option",
163
182
  "python_uv_native_tls_option",
164
183
  "python_version_option",
184
+ "repo_name_option",
165
185
  "throttle_option",
166
186
  ]
@@ -30,12 +30,18 @@ from pre_commit_hooks.constants import (
30
30
  TAPLO_URL,
31
31
  UV_URL,
32
32
  XMLFORMATTER_URL,
33
+ ci_pytest_os_option,
34
+ ci_pytest_python_version_option,
35
+ ci_pytest_runs_on_option,
36
+ description_option,
33
37
  paths_argument,
34
38
  python_option,
35
- python_package_name_option,
39
+ python_package_name_external_option,
40
+ python_package_name_internal_option,
36
41
  python_uv_index_option,
37
42
  python_uv_native_tls_option,
38
43
  python_version_option,
44
+ repo_name_option,
39
45
  )
40
46
  from pre_commit_hooks.utilities import (
41
47
  apply,
@@ -55,16 +61,24 @@ if TYPE_CHECKING:
55
61
  @command(**CONTEXT_SETTINGS)
56
62
  @paths_argument
57
63
  @option("--ci", is_flag=True, default=False)
64
+ @option("--ci-github", is_flag=True, default=False)
65
+ @option("--ci-gitea", is_flag=True, default=False)
66
+ @ci_pytest_os_option
67
+ @ci_pytest_python_version_option
68
+ @ci_pytest_runs_on_option
69
+ @description_option
58
70
  @option("--direnv", is_flag=True, default=False)
59
71
  @option("--docker", is_flag=True, default=False)
60
72
  @option("--fish", is_flag=True, default=False)
61
73
  @option("--lua", is_flag=True, default=False)
62
74
  @option("--prettier", is_flag=True, default=False)
63
75
  @python_option
64
- @python_package_name_option
76
+ @python_package_name_external_option
77
+ @python_package_name_internal_option
65
78
  @python_uv_index_option
66
79
  @python_uv_native_tls_option
67
80
  @python_version_option
81
+ @repo_name_option
68
82
  @option("--shell", is_flag=True, default=False)
69
83
  @option("--toml", is_flag=True, default=False)
70
84
  @option("--xml", is_flag=True, default=False)
@@ -73,16 +87,24 @@ def _main(
73
87
  *,
74
88
  paths: tuple[Path, ...],
75
89
  ci: bool = False,
90
+ ci_github: bool = False,
91
+ ci_gitea: bool = False,
92
+ ci_pytest_os: MaybeSequenceStr | None = None,
93
+ ci_pytest_python_version: MaybeSequenceStr | None = None,
94
+ ci_pytest_runs_on: MaybeSequenceStr | None = None,
95
+ description: str | None = None,
76
96
  direnv: bool = False,
77
97
  docker: bool = False,
78
98
  fish: bool = False,
79
99
  lua: bool = False,
80
100
  prettier: bool = False,
81
101
  python: bool = False,
82
- python_package_name: str | None = None,
102
+ python_package_name_external: str | None = None,
103
+ python_package_name_internal: str | None = None,
83
104
  python_uv_index: MaybeSequenceStr | None = None,
84
105
  python_uv_native_tls: bool = False,
85
106
  python_version: str = DEFAULT_PYTHON_VERSION,
107
+ repo_name: str | None = None,
86
108
  shell: bool = False,
87
109
  toml: bool = False,
88
110
  xml: bool = False,
@@ -90,46 +112,61 @@ def _main(
90
112
  ) -> None:
91
113
  if is_pytest():
92
114
  return
93
- run_all_maybe_raise(
94
- *(
95
- partial(
96
- _run,
97
- path=p,
98
- ci=ci,
99
- direnv=direnv,
100
- docker=docker,
101
- fish=fish,
102
- lua=lua,
103
- prettier=prettier,
104
- python=python,
105
- python_package_name=python_package_name,
106
- python_uv_index=python_uv_index,
107
- python_uv_native_tls=python_uv_native_tls,
108
- python_version=python_version,
109
- shell=shell,
110
- toml=toml,
111
- xml=xml,
112
- max_workers="all" if max_workers is None else max_workers,
113
- )
114
- for p in paths
115
+ funcs: list[Callable[[], bool]] = [
116
+ partial(
117
+ _run,
118
+ path=p,
119
+ ci=ci,
120
+ ci_github=ci_github,
121
+ ci_gitea=ci_gitea,
122
+ ci_pytest_os=ci_pytest_os,
123
+ ci_pytest_python_version=ci_pytest_python_version,
124
+ ci_pytest_runs_on=ci_pytest_runs_on,
125
+ description=description,
126
+ direnv=direnv,
127
+ docker=docker,
128
+ fish=fish,
129
+ lua=lua,
130
+ prettier=prettier,
131
+ python=python,
132
+ python_package_name_external=python_package_name_external,
133
+ python_package_name_internal=python_package_name_internal,
134
+ python_uv_index=python_uv_index,
135
+ python_uv_native_tls=python_uv_native_tls,
136
+ python_version=python_version,
137
+ repo_name=repo_name,
138
+ shell=shell,
139
+ toml=toml,
140
+ xml=xml,
141
+ max_workers="all" if max_workers is None else max_workers,
115
142
  )
116
- )
143
+ for p in paths
144
+ ]
145
+ run_all_maybe_raise(*funcs)
117
146
 
118
147
 
119
148
  def _run(
120
149
  *,
121
150
  path: PathLike = PRE_COMMIT_CONFIG_YAML,
122
151
  ci: bool = False,
152
+ ci_github: bool = False,
153
+ ci_gitea: bool = False,
154
+ ci_pytest_os: MaybeSequenceStr | None = None,
155
+ ci_pytest_python_version: MaybeSequenceStr | None = None,
156
+ ci_pytest_runs_on: MaybeSequenceStr | None = None,
157
+ description: str | None = None,
123
158
  direnv: bool = False,
124
159
  docker: bool = False,
125
160
  fish: bool = False,
126
161
  lua: bool = False,
127
162
  prettier: bool = False,
128
163
  python: bool = False,
129
- python_package_name: str | None = None,
164
+ python_package_name_external: str | None = None,
165
+ python_package_name_internal: str | None = None,
130
166
  python_uv_index: MaybeSequenceStr | None = None,
131
167
  python_uv_native_tls: bool = False,
132
168
  python_version: str = DEFAULT_PYTHON_VERSION,
169
+ repo_name: str | None = None,
133
170
  shell: bool = False,
134
171
  toml: bool = False,
135
172
  xml: bool = False,
@@ -142,11 +179,54 @@ def _run(
142
179
  partial(_add_run_prek_autoupdate, path=path),
143
180
  partial(_add_run_version_bump, path=path),
144
181
  partial(_add_setup_bump_my_version, path=path),
182
+ partial(
183
+ _add_setup_readme, path=path, repo_name=repo_name, description=description
184
+ ),
145
185
  partial(_add_standard_hooks, path=path),
146
186
  ]
147
- if ci:
187
+ if ci or ci_github or ci_gitea:
148
188
  funcs.append(partial(_add_update_ci_action_versions, path=path))
149
189
  funcs.append(partial(_add_update_ci_extensions, path=path))
190
+ if ci_github:
191
+ funcs.append(
192
+ partial(
193
+ _add_setup_ci_pull_request,
194
+ path=path,
195
+ ci_pytest_os=ci_pytest_os,
196
+ ci_pytest_runs_on=ci_pytest_runs_on,
197
+ ci_pytest_python_version=ci_pytest_python_version,
198
+ python_uv_native_tls=python_uv_native_tls,
199
+ python_version=python_version,
200
+ repo_name=repo_name,
201
+ )
202
+ )
203
+ funcs.append(
204
+ partial(
205
+ _add_setup_ci_push, path=path, python_uv_native_tls=python_uv_native_tls
206
+ )
207
+ )
208
+ if ci_gitea:
209
+ funcs.append(
210
+ partial(
211
+ _add_setup_ci_pull_request,
212
+ path=path,
213
+ gitea=True,
214
+ ci_pytest_os=ci_pytest_os,
215
+ ci_pytest_runs_on=ci_pytest_runs_on,
216
+ ci_pytest_python_version=ci_pytest_python_version,
217
+ python_uv_native_tls=python_uv_native_tls,
218
+ python_version=python_version,
219
+ repo_name=repo_name,
220
+ )
221
+ )
222
+ funcs.append(
223
+ partial(
224
+ _add_setup_ci_push,
225
+ path=path,
226
+ gitea=True,
227
+ python_uv_native_tls=python_uv_native_tls,
228
+ )
229
+ )
150
230
  if direnv:
151
231
  funcs.append(partial(_add_setup_direnv, path=path))
152
232
  if docker:
@@ -167,9 +247,10 @@ def _run(
167
247
  partial(
168
248
  _add_setup_bump_my_version,
169
249
  path=path,
170
- python_package_name=python_package_name,
250
+ python_package_name_internal=python_package_name_internal,
171
251
  )
172
252
  )
253
+ funcs.append(partial(_add_setup_coverage, path=path))
173
254
  funcs.append(
174
255
  partial(
175
256
  _add_setup_direnv,
@@ -181,6 +262,17 @@ def _run(
181
262
  )
182
263
  )
183
264
  funcs.append(partial(_add_setup_git, path=path))
265
+ funcs.append(
266
+ partial(
267
+ _add_setup_pyproject,
268
+ path=path,
269
+ python_version=python_version,
270
+ description=description,
271
+ python_package_name_external=python_package_name_external,
272
+ python_package_name_internal=python_package_name_internal,
273
+ python_uv_index=python_uv_index,
274
+ )
275
+ )
184
276
  funcs.append(
185
277
  partial(_add_setup_pyright, path=path, python_version=python_version)
186
278
  )
@@ -265,12 +357,14 @@ def _add_run_version_bump(*, path: PathLike = PRE_COMMIT_CONFIG_YAML) -> bool:
265
357
 
266
358
 
267
359
  def _add_setup_bump_my_version(
268
- *, path: PathLike = PRE_COMMIT_CONFIG_YAML, python_package_name: str | None = None
360
+ *,
361
+ path: PathLike = PRE_COMMIT_CONFIG_YAML,
362
+ python_package_name_internal: str | None = None,
269
363
  ) -> bool:
270
364
  modifications: set[Path] = set()
271
365
  args: list[str] = []
272
- if python_package_name is not None:
273
- args.append(f"--python-package-name={python_package_name}")
366
+ if python_package_name_internal is not None:
367
+ args.append(f"--python-package-name-internal={python_package_name_internal}")
274
368
  _add_hook(
275
369
  DYCW_PRE_COMMIT_HOOKS_URL,
276
370
  "setup-bump-my-version",
@@ -283,6 +377,43 @@ def _add_setup_bump_my_version(
283
377
  return len(modifications) == 0
284
378
 
285
379
 
380
+ def _add_setup_coverage(*, path: PathLike = PRE_COMMIT_CONFIG_YAML) -> bool:
381
+ modifications: set[Path] = set()
382
+ _add_hook(
383
+ DYCW_PRE_COMMIT_HOOKS_URL,
384
+ "setup-coverage",
385
+ path=path,
386
+ modifications=modifications,
387
+ rev=True,
388
+ type_="formatter",
389
+ )
390
+ return len(modifications) == 0
391
+
392
+
393
+ def _add_setup_readme(
394
+ *,
395
+ path: PathLike = PRE_COMMIT_CONFIG_YAML,
396
+ repo_name: str | None = None,
397
+ description: str | None = None,
398
+ ) -> bool:
399
+ modifications: set[Path] = set()
400
+ args: list[str] = []
401
+ if repo_name is not None:
402
+ args.append(f"--repo-name={repo_name}")
403
+ if description is not None:
404
+ args.append(f"--description={description}")
405
+ _add_hook(
406
+ DYCW_PRE_COMMIT_HOOKS_URL,
407
+ "setup-readme",
408
+ path=path,
409
+ modifications=modifications,
410
+ rev=True,
411
+ args=args if len(args) >= 1 else None,
412
+ type_="formatter",
413
+ )
414
+ return len(modifications) == 0
415
+
416
+
286
417
  def _add_standard_hooks(*, path: PathLike = PRE_COMMIT_CONFIG_YAML) -> bool:
287
418
  modifications: set[Path] = set()
288
419
  _add_hook(
@@ -432,6 +563,73 @@ def _add_update_ci_extensions(*, path: PathLike = PRE_COMMIT_CONFIG_YAML) -> boo
432
563
  return len(modifications) == 0
433
564
 
434
565
 
566
+ def _add_setup_ci_pull_request(
567
+ *,
568
+ path: PathLike = PRE_COMMIT_CONFIG_YAML,
569
+ gitea: bool = False,
570
+ ci_pytest_os: MaybeSequenceStr | None = None,
571
+ ci_pytest_runs_on: MaybeSequenceStr | None = None,
572
+ ci_pytest_python_version: MaybeSequenceStr | None = None,
573
+ python_uv_native_tls: bool = False,
574
+ python_version: str = DEFAULT_PYTHON_VERSION,
575
+ repo_name: str | None = None,
576
+ ) -> bool:
577
+ modifications: set[Path] = set()
578
+ args: list[str] = []
579
+ if gitea:
580
+ args.append("--gitea")
581
+ if ci_pytest_os is not None:
582
+ args.append(f"--ci-pytest-os={','.join(always_iterable(ci_pytest_os))}")
583
+ if ci_pytest_runs_on is not None:
584
+ args.append(
585
+ f"--ci-pytest-runs-on={','.join(always_iterable(ci_pytest_runs_on))}"
586
+ )
587
+ if ci_pytest_python_version is not None:
588
+ args.append(
589
+ f"--ci-pytest-pythonnversion={','.join(always_iterable(ci_pytest_python_version))}"
590
+ )
591
+ if python_uv_native_tls:
592
+ args.append("--python-uv-native-tls")
593
+ if python_version is not None:
594
+ args.append(f"--python-version={python_version}")
595
+ if repo_name is not None:
596
+ args.append(f"--repo-name={repo_name}")
597
+ _add_hook(
598
+ DYCW_PRE_COMMIT_HOOKS_URL,
599
+ "setup-ci-pull-request",
600
+ path=path,
601
+ modifications=modifications,
602
+ args=args if len(args) >= 1 else None,
603
+ rev=True,
604
+ type_="formatter",
605
+ )
606
+ return len(modifications) == 0
607
+
608
+
609
+ def _add_setup_ci_push(
610
+ *,
611
+ path: PathLike = PRE_COMMIT_CONFIG_YAML,
612
+ gitea: bool = False,
613
+ python_uv_native_tls: bool = False,
614
+ ) -> bool:
615
+ modifications: set[Path] = set()
616
+ args: list[str] = []
617
+ if gitea:
618
+ args.append("--gitea")
619
+ if python_uv_native_tls:
620
+ args.append("--python-uv-native-tls")
621
+ _add_hook(
622
+ DYCW_PRE_COMMIT_HOOKS_URL,
623
+ "setup-ci-push",
624
+ path=path,
625
+ modifications=modifications,
626
+ args=args if len(args) >= 1 else None,
627
+ rev=True,
628
+ type_="formatter",
629
+ )
630
+ return len(modifications) == 0
631
+
632
+
435
633
  def _add_setup_direnv(
436
634
  *,
437
635
  path: PathLike = PRE_COMMIT_CONFIG_YAML,
@@ -603,6 +801,37 @@ def _add_setup_git(*, path: PathLike = PRE_COMMIT_CONFIG_YAML) -> bool:
603
801
  return len(modifications) == 0
604
802
 
605
803
 
804
+ def _add_setup_pyproject(
805
+ *,
806
+ path: PathLike = PRE_COMMIT_CONFIG_YAML,
807
+ python_version: str = DEFAULT_PYTHON_VERSION,
808
+ description: str | None = None,
809
+ python_package_name_external: str | None = None,
810
+ python_package_name_internal: str | None = None,
811
+ python_uv_index: MaybeSequenceStr | None = None,
812
+ ) -> bool:
813
+ modifications: set[Path] = set()
814
+ args: list[str] = [f"--python-version={python_version}"]
815
+ if description is not None:
816
+ args.append(f"--description={description}")
817
+ if python_package_name_external is not None:
818
+ args.append(f"--python-package-name-external={python_package_name_external}")
819
+ if python_package_name_internal is not None:
820
+ args.append(f"--python-package-name-internal={python_package_name_internal}")
821
+ if python_uv_index is not None:
822
+ args.append(f"--python-uv-index={','.join(always_iterable(python_uv_index))}")
823
+ _add_hook(
824
+ DYCW_PRE_COMMIT_HOOKS_URL,
825
+ "setup-pyproject",
826
+ path=path,
827
+ modifications=modifications,
828
+ rev=True,
829
+ args=args,
830
+ type_="formatter",
831
+ )
832
+ return len(modifications) == 0
833
+
834
+
606
835
  def _add_setup_pyright(
607
836
  *,
608
837
  path: PathLike = PRE_COMMIT_CONFIG_YAML,
@@ -750,31 +979,31 @@ def _add_hook(
750
979
  type_: Literal["formatter", "linter"] | None = None,
751
980
  ) -> None:
752
981
  with yield_yaml_dict(path, modifications=modifications) as dict_:
753
- repos_list = get_set_list_dicts(dict_, "repos")
754
- repo_dict = ensure_contains_partial_dict(
755
- repos_list, {"repo": url}, extra={"rev": "master"} if rev else {}
756
- )
757
- hooks_list = get_set_list_dicts(repo_dict, "hooks")
758
- hook_dict = ensure_contains_partial_dict(hooks_list, {"id": id_})
982
+ repos = get_set_list_dicts(dict_, "repos")
983
+ repo = ensure_contains_partial_dict(repos, {"repo": url})
984
+ if rev:
985
+ repo.setdefault("rev", "master")
986
+ hooks = get_set_list_dicts(repo, "hooks")
987
+ hook = ensure_contains_partial_dict(hooks, {"id": id_})
759
988
  if name is not None:
760
- hook_dict["name"] = name
989
+ hook["name"] = name
761
990
  if entry is not None:
762
- hook_dict["entry"] = entry
991
+ hook["entry"] = entry
763
992
  if language is not None:
764
- hook_dict["language"] = language
993
+ hook["language"] = language
765
994
  if files is not None:
766
- hook_dict["files"] = files
995
+ hook["files"] = files
767
996
  if types is not None:
768
- hook_dict["types"] = types
997
+ hook["types"] = types
769
998
  if types_or is not None:
770
- hook_dict["types_or"] = types_or
999
+ hook["types_or"] = types_or
771
1000
  if args is not None:
772
- hook_dict["args"] = args
1001
+ hook["args"] = args
773
1002
  match type_:
774
1003
  case "formatter":
775
- hook_dict["priority"] = FORMATTER_PRIORITY
1004
+ hook["priority"] = FORMATTER_PRIORITY
776
1005
  case "linter":
777
- hook_dict["priority"] = LINTER_PRIORITY
1006
+ hook["priority"] = LINTER_PRIORITY
778
1007
  case None:
779
1008
  ...
780
1009
  case never:
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
7
7
 
8
8
  from click import command
9
9
  from utilities.click import CONTEXT_SETTINGS
10
+ from utilities.constants import sentinel
10
11
  from utilities.os import is_pytest
11
12
  from utilities.types import PathLike
12
13
 
@@ -39,18 +40,22 @@ def _run(*, path: PathLike = PRE_COMMIT_CONFIG_YAML) -> bool:
39
40
  path = Path(path)
40
41
  current = path.read_text()
41
42
  with yield_yaml_dict(path, sort_keys=False) as dict_:
42
- repos_list = get_list_dicts(dict_, "repos")
43
- repos_list.sort(key=_sort_key)
44
- for repo_dict in repos_list:
45
- _re_insert(repo_dict, PRE_COMMIT_CONFIG_REPO_KEYS)
46
- hooks_list = get_list_dicts(repo_dict, "hooks")
47
- hooks_list.sort(key=lambda x: x["id"])
48
- if repo_dict["repo"] == "local":
43
+ repos = get_list_dicts(dict_, "repos")
44
+ repos.sort(key=_sort_key)
45
+ for repo in repos:
46
+ _re_insert(repo, PRE_COMMIT_CONFIG_REPO_KEYS)
47
+ hooks = get_list_dicts(repo, "hooks")
48
+ hooks.sort(key=lambda x: x["id"])
49
+ if repo["repo"] == "local":
49
50
  keys = PRE_COMMIT_HOOKS_HOOK_KEYS
50
51
  else:
51
52
  keys = PRE_COMMIT_CONFIG_HOOK_KEYS
52
- for hook_dict in hooks_list:
53
- _re_insert(hook_dict, keys)
53
+ for hook in hooks:
54
+ _re_insert(hook, keys)
55
+ repos.append({"repo": str(sentinel)})
56
+ with yield_yaml_dict(path, sort_keys=False) as dict_:
57
+ repos = get_list_dicts(dict_, "repos")
58
+ _ = repos.pop(-1)
54
59
  return path.read_text() == current
55
60
 
56
61