dycw-pre-commit-hooks 0.12.4__py3-none-any.whl → 0.12.5__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.

Potentially problematic release.


This version of dycw-pre-commit-hooks might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-pre-commit-hooks
3
- Version: 0.12.4
3
+ Version: 0.12.5
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: click<8.3,>=8.2.1
@@ -31,6 +31,7 @@ My [`pre-commit`](https://pre-commit.com/) hooks.
31
31
  - repo: https://github.com/dycw/pre-commit-hooks
32
32
  rev: master
33
33
  hooks:
34
+ - id: check-submodules
34
35
  - id: format-requirements
35
36
  - id: replace-sequence-str
36
37
  - id: run-bump-my-version
@@ -0,0 +1,17 @@
1
+ pre_commit_hooks/__init__.py,sha256=F3qvvaYWO9UbSdbCiBLQFrc_LvSR0D1M5LVTfyR9LV8,59
2
+ pre_commit_hooks/common.py,sha256=Ovg0kK5CBSBEalGdVxLKjvRX3gbjpzTFRNRopB8tEiw,4247
3
+ pre_commit_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ pre_commit_hooks/check_submodules/__init__.py,sha256=8aJ6sbDclOML5uahK4TNf80Sxf6gCx1kIOYwkv37g9s,1092
5
+ pre_commit_hooks/check_submodules/__main__.py,sha256=foSVebwCfSkKcAc3cD5YTzkmrWd7Wso9_mR9-zuyG-o,153
6
+ pre_commit_hooks/format_requirements/__init__.py,sha256=dORQ5sNZaOWYY6cw0X1YIic4OHZeTt9EhI21D1uQFyE,3322
7
+ pre_commit_hooks/format_requirements/__main__.py,sha256=15JSp_rhjI_Ddoj4MRkHFShfnYxs6GggUhLRlGtrQ0E,156
8
+ pre_commit_hooks/replace_sequence_str/__init__.py,sha256=nDjiKV14th2uWbnte1rSvXckysl7ooaLgWo6IP4HI2s,1618
9
+ pre_commit_hooks/replace_sequence_str/__main__.py,sha256=B1dxOxngV4vUVnDVrXSywiySOs1P_zF30_4ZMRsOSaY,157
10
+ pre_commit_hooks/run_bump_my_version/__init__.py,sha256=OsMY0boz3VTqAtgLCHtC8AvCXx6OYvOXA5H-VAwBFoY,1444
11
+ pre_commit_hooks/run_bump_my_version/__main__.py,sha256=w2V3y61jrSau-zxjl8ciHtWPlJQwXbYxNJ2tGYVyI4s,156
12
+ pre_commit_hooks/tag_commits/__init__.py,sha256=097p0gfZcykpOPUgGYsrLePe8Nar04eKlCMn_mqPepg,2945
13
+ pre_commit_hooks/tag_commits/__main__.py,sha256=qefgYw7LWbvmzZS45-ym6olS4cHqw1Emw2wlqZBXN_o,148
14
+ dycw_pre_commit_hooks-0.12.5.dist-info/METADATA,sha256=d0hMyN0LUeu1JKiAOrSzd91hc-iWSAqD5KnUKrdi1Xk,1061
15
+ dycw_pre_commit_hooks-0.12.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ dycw_pre_commit_hooks-0.12.5.dist-info/entry_points.txt,sha256=LqAiEwyqmkYt_sdzcFYgmDZ1Y6exFIwoVWWl8a0vVjU,318
17
+ dycw_pre_commit_hooks-0.12.5.dist-info/RECORD,,
@@ -1,4 +1,5 @@
1
1
  [console_scripts]
2
+ check-submodules = pre_commit_hooks.check_submodules:main
2
3
  format-requirements = pre_commit_hooks.format_requirements:main
3
4
  replace-sequence-str = pre_commit_hooks.replace_sequence_str:main
4
5
  run-bump-my-version = pre_commit_hooks.run_bump_my_version:main
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.12.4"
3
+ __version__ = "0.12.5"
@@ -0,0 +1,50 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from click import command
6
+ from git import Repo, Submodule
7
+
8
+ from pre_commit_hooks.common import (
9
+ DEFAULT_MODE,
10
+ Mode,
11
+ get_toml_path,
12
+ get_version,
13
+ mode_option,
14
+ run_every_option,
15
+ throttled_run,
16
+ )
17
+
18
+ if TYPE_CHECKING:
19
+ from whenever import DateTimeDelta
20
+
21
+
22
+ @command()
23
+ @run_every_option
24
+ def main(*, run_every: DateTimeDelta | None = None) -> bool:
25
+ """CLI for the `check-submodules` hook."""
26
+ return throttled_run("check-submodules", run_every, _process)
27
+
28
+
29
+ def _process() -> bool:
30
+ repo = Repo(".", search_parent_directories=True)
31
+ results = [_process_submodule(s) for s in repo.submodules] # run all
32
+ return all(results)
33
+
34
+
35
+ def _process_submodule(submodule: Submodule, /) -> bool:
36
+ repo = submodule.module()
37
+ _ = repo.remotes.origin.fetch()
38
+ local = repo.commit("master")
39
+ remote = repo.commit("origin/master")
40
+ return local.hexsha == remote.hexsha
41
+
42
+
43
+ __all__ = [
44
+ "DEFAULT_MODE",
45
+ "Mode",
46
+ "get_toml_path",
47
+ "get_version",
48
+ "main",
49
+ "mode_option",
50
+ ]
@@ -0,0 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+ from pre_commit_hooks.check_submodules import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(int(not main()))
@@ -1,14 +1,25 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
- from typing import Literal, assert_never
4
+ from typing import TYPE_CHECKING, Literal, assert_never
5
5
 
6
+ import utilities.click
6
7
  from click import Choice, option
7
8
  from loguru import logger
8
9
  from tomlkit import TOMLDocument, parse
9
10
  from tomlkit.items import Table
11
+ from utilities.atomicwrites import writer
12
+ from utilities.hashlib import md5_hash
13
+ from utilities.pathlib import get_repo_root
10
14
  from utilities.typing import get_literal_elements
11
15
  from utilities.version import Version, parse_version
16
+ from utilities.whenever import get_now_local, to_zoned_date_time
17
+ from xdg_base_dirs import xdg_cache_home
18
+
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Callable
21
+
22
+ from whenever import DateTimeDelta
12
23
 
13
24
  type Mode = Literal["pyproject", "bumpversion"]
14
25
  DEFAULT_MODE: Mode = "pyproject"
@@ -18,6 +29,9 @@ mode_option = option(
18
29
  default=DEFAULT_MODE,
19
30
  show_default=True,
20
31
  )
32
+ run_every_option = option(
33
+ "--run-every", type=utilities.click.DateTimeDelta(), default=None, show_default=True
34
+ )
21
35
 
22
36
 
23
37
  def get_version(source: Mode | Path | str | bytes | TOMLDocument, /) -> Version:
@@ -64,6 +78,7 @@ def get_version(source: Mode | Path | str | bytes | TOMLDocument, /) -> Version:
64
78
 
65
79
 
66
80
  def get_toml_path(mode: Mode = DEFAULT_MODE, /) -> Path:
81
+ """Get the path of the TOML file with the version."""
67
82
  match mode:
68
83
  case "pyproject":
69
84
  return Path("pyproject.toml")
@@ -73,4 +88,44 @@ def get_toml_path(mode: Mode = DEFAULT_MODE, /) -> Path:
73
88
  assert_never(never)
74
89
 
75
90
 
76
- __all__ = ["DEFAULT_MODE", "Mode", "get_toml_path", "get_version", "mode_option"]
91
+ def throttled_run[**P](
92
+ name: str,
93
+ run_every: DateTimeDelta | None,
94
+ func: Callable[P, bool],
95
+ /,
96
+ *args: P.args,
97
+ **kwargs: P.kwargs,
98
+ ) -> bool:
99
+ """Throttled run."""
100
+ hash_ = md5_hash(get_repo_root())
101
+ path = xdg_cache_home().joinpath(name, hash_)
102
+ if run_every is not None:
103
+ min_date_time = get_now_local() - run_every
104
+ try:
105
+ text = path.read_text()
106
+ except FileNotFoundError:
107
+ pass
108
+ else:
109
+ try:
110
+ last_run = to_zoned_date_time(text.strip("\n"))
111
+ except ValueError:
112
+ pass
113
+ else:
114
+ if min_date_time <= last_run:
115
+ return True
116
+ try:
117
+ return func(*args, **kwargs)
118
+ finally:
119
+ with writer(path, overwrite=True) as temp:
120
+ _ = temp.write_text(str(get_now_local()))
121
+
122
+
123
+ __all__ = [
124
+ "DEFAULT_MODE",
125
+ "Mode",
126
+ "get_toml_path",
127
+ "get_version",
128
+ "mode_option",
129
+ "run_every_option",
130
+ "throttled_run",
131
+ ]
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
25
25
  @command()
26
26
  @argument("paths", nargs=-1, type=utilities.click.Path())
27
27
  def main(*, paths: tuple[Path, ...]) -> bool:
28
- """CLI for the `format_requirements` hook."""
28
+ """CLI for the `format-requirements` hook."""
29
29
  results = list(map(_process, paths)) # run all
30
30
  return all(results)
31
31
 
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
19
19
  @command()
20
20
  @argument("paths", nargs=-1, type=utilities.click.Path())
21
21
  def main(*, paths: tuple[Path, ...]) -> bool:
22
- """CLI for the `replace_sequence_str` hook."""
22
+ """CLI for the `replace-sequence-str` hook."""
23
23
  results = list(map(_process, paths)) # run all
24
24
  return all(results)
25
25
 
@@ -17,7 +17,7 @@ from pre_commit_hooks.common import (
17
17
  @command()
18
18
  @mode_option
19
19
  def main(*, mode: Mode = DEFAULT_MODE) -> bool:
20
- """CLI for the `run_bump_my_version` hook."""
20
+ """CLI for the `run-bump-my-version` hook."""
21
21
  return _process(mode=mode)
22
22
 
23
23
 
@@ -6,12 +6,8 @@ import utilities.click
6
6
  from click import command, option
7
7
  from git import Commit, GitCommandError, Repo
8
8
  from loguru import logger
9
- from utilities.hashlib import md5_hash
10
- from utilities.pathlib import get_repo_root
11
9
  from utilities.tzlocal import LOCAL_TIME_ZONE_NAME
12
10
  from utilities.whenever import from_timestamp, get_now_local
13
- from whenever import DateTimeDelta, ZonedDateTime
14
- from xdg_base_dirs import xdg_cache_home
15
11
 
16
12
  from pre_commit_hooks.common import (
17
13
  DEFAULT_MODE,
@@ -19,67 +15,33 @@ from pre_commit_hooks.common import (
19
15
  get_toml_path,
20
16
  get_version,
21
17
  mode_option,
18
+ run_every_option,
19
+ throttled_run,
22
20
  )
23
21
 
24
22
  if TYPE_CHECKING:
25
23
  from collections.abc import Set as AbstractSet
26
24
 
27
- _RUN_EVERY: DateTimeDelta | None = None
28
- _MAX_AGE: DateTimeDelta | None = None
25
+ from whenever import DateTimeDelta, ZonedDateTime
29
26
 
30
27
 
31
28
  @command()
29
+ @run_every_option
32
30
  @option(
33
- "--run-every",
34
- type=utilities.click.DateTimeDelta(),
35
- default=_RUN_EVERY,
36
- show_default=True,
37
- )
38
- @option(
39
- "--max-age",
40
- type=utilities.click.DateTimeDelta(),
41
- default=_MAX_AGE,
42
- show_default=True,
31
+ "--max-age", type=utilities.click.DateTimeDelta(), default=None, show_default=True
43
32
  )
44
33
  @mode_option
45
34
  def main(
46
35
  *,
47
- run_every: DateTimeDelta | None = _RUN_EVERY,
48
- max_age: DateTimeDelta | None = _MAX_AGE,
36
+ run_every: DateTimeDelta | None = None,
37
+ max_age: DateTimeDelta | None = None,
49
38
  mode: Mode = DEFAULT_MODE,
50
39
  ) -> bool:
51
- """CLI for the `tag_commits` hook."""
52
- return _process(run_every=run_every, max_age=max_age, mode=mode)
40
+ """CLI for the `tag-commits` hook."""
41
+ return throttled_run("tag-commits", run_every, _process, max_age=max_age, mode=mode)
53
42
 
54
43
 
55
44
  def _process(
56
- *,
57
- run_every: DateTimeDelta | None = _RUN_EVERY,
58
- max_age: DateTimeDelta | None = _MAX_AGE,
59
- mode: Mode = DEFAULT_MODE,
60
- ) -> bool:
61
- if run_every is not None:
62
- last = _get_last_run()
63
- min_date_time = get_now_local() - run_every
64
- if (last is not None) and (min_date_time <= last):
65
- return True
66
- return _process_commits(max_age=max_age, mode=mode)
67
-
68
-
69
- def _get_last_run() -> ZonedDateTime | None:
70
- hash_ = md5_hash(get_repo_root())
71
- path = xdg_cache_home().joinpath("tag-commits", hash_)
72
- try:
73
- text = path.read_text()
74
- except FileNotFoundError:
75
- return None
76
- try:
77
- return ZonedDateTime.parse_common_iso(text.strip("\n"))
78
- except ValueError:
79
- return None
80
-
81
-
82
- def _process_commits(
83
45
  *, max_age: DateTimeDelta | None = None, mode: Mode = DEFAULT_MODE
84
46
  ) -> bool:
85
47
  repo = Repo(".", search_parent_directories=True)
@@ -1,15 +0,0 @@
1
- pre_commit_hooks/__init__.py,sha256=Ul915aXNCIEUqkW77kaJBYxPvo2kTfIB8Fya_1sVCTM,59
2
- pre_commit_hooks/common.py,sha256=LW6OatA5KzfhqnITJq9s1MzNw5t-0zFPqoPW-2VyRm8,2764
3
- pre_commit_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- pre_commit_hooks/format_requirements/__init__.py,sha256=zcvOH839MHGxVNvbBt4KZKDW2MXdtnu6OuxP6P0IqL4,3322
5
- pre_commit_hooks/format_requirements/__main__.py,sha256=15JSp_rhjI_Ddoj4MRkHFShfnYxs6GggUhLRlGtrQ0E,156
6
- pre_commit_hooks/replace_sequence_str/__init__.py,sha256=a-pCAcBaa7FDsGDNLzMiD-xG20wKl-SRmhWSbm9hrvo,1618
7
- pre_commit_hooks/replace_sequence_str/__main__.py,sha256=B1dxOxngV4vUVnDVrXSywiySOs1P_zF30_4ZMRsOSaY,157
8
- pre_commit_hooks/run_bump_my_version/__init__.py,sha256=alaQx34H_pUfJypv9f0UmXIb3Ht3YS29pxcfodVtaTM,1444
9
- pre_commit_hooks/run_bump_my_version/__main__.py,sha256=w2V3y61jrSau-zxjl8ciHtWPlJQwXbYxNJ2tGYVyI4s,156
10
- pre_commit_hooks/tag_commits/__init__.py,sha256=E9aOurHbD_K3zr8YgBQkiIJo05d2BMUZdecqzz92iJo,3982
11
- pre_commit_hooks/tag_commits/__main__.py,sha256=qefgYw7LWbvmzZS45-ym6olS4cHqw1Emw2wlqZBXN_o,148
12
- dycw_pre_commit_hooks-0.12.4.dist-info/METADATA,sha256=u20WYX8Q-rs4RXZ1JugnG7rfxYovjpfRpGhn4nhPCAs,1029
13
- dycw_pre_commit_hooks-0.12.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
- dycw_pre_commit_hooks-0.12.4.dist-info/entry_points.txt,sha256=r1tnPzaGvOrSdX-ZRriidf8AhZgUtXfjdTpwpkTBA8U,260
15
- dycw_pre_commit_hooks-0.12.4.dist-info/RECORD,,