dycw-pre-commit-hooks 0.14.26__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.
@@ -0,0 +1,58 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from pathlib import Path
5
+ from typing import TYPE_CHECKING
6
+
7
+ from click import command
8
+ from utilities.click import CONTEXT_SETTINGS
9
+ from utilities.os import is_pytest
10
+ from utilities.types import PathLike
11
+
12
+ from pre_commit_hooks.constants import COVERAGERC_TOML, paths_argument
13
+ from pre_commit_hooks.utilities import (
14
+ ensure_contains,
15
+ get_set_array,
16
+ get_set_table,
17
+ run_all_maybe_raise,
18
+ yield_toml_doc,
19
+ )
20
+
21
+ if TYPE_CHECKING:
22
+ from collections.abc import Callable
23
+ from pathlib import Path
24
+
25
+ from utilities.types import PathLike
26
+
27
+
28
+ @command(**CONTEXT_SETTINGS)
29
+ @paths_argument
30
+ def _main(*, paths: tuple[Path, ...]) -> None:
31
+ if is_pytest():
32
+ return
33
+ funcs: list[Callable[[], bool]] = [
34
+ partial(_run, path=p.parent / COVERAGERC_TOML) for p in paths
35
+ ]
36
+ run_all_maybe_raise(*funcs)
37
+
38
+
39
+ def _run(*, path: PathLike = COVERAGERC_TOML) -> bool:
40
+ modifications: set[Path] = set()
41
+ with yield_toml_doc(path, modifications=modifications) as doc:
42
+ html = get_set_table(doc, "html")
43
+ html["directory"] = ".coverage/html"
44
+ report = get_set_table(doc, "report")
45
+ exclude_also = get_set_array(report, "exclude_also")
46
+ ensure_contains(exclude_also, "@overload", "if TYPE_CHECKING:")
47
+ report["fail_under"] = 100.0
48
+ report["skip_covered"] = True
49
+ report["skip_empty"] = True
50
+ run = get_set_table(doc, "run")
51
+ run["branch"] = True
52
+ run["data_file"] = ".coverage/data"
53
+ run["parallel"] = True
54
+ return len(modifications) == 0
55
+
56
+
57
+ if __name__ == "__main__":
58
+ _main()
@@ -0,0 +1,144 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from pathlib import Path
5
+ from re import MULTILINE, escape, search
6
+ from typing import TYPE_CHECKING
7
+
8
+ from click import command
9
+ from utilities.click import CONTEXT_SETTINGS
10
+ from utilities.iterables import always_iterable
11
+ from utilities.os import is_pytest
12
+ from utilities.text import strip_and_dedent
13
+ from utilities.types import PathLike
14
+
15
+ from pre_commit_hooks.constants import (
16
+ DEFAULT_PYTHON_VERSION,
17
+ ENVRC,
18
+ paths_argument,
19
+ python_option,
20
+ python_uv_index_option,
21
+ python_uv_native_tls_option,
22
+ python_version_option,
23
+ )
24
+ from pre_commit_hooks.utilities import run_all_maybe_raise, yield_text_file
25
+
26
+ if TYPE_CHECKING:
27
+ from collections.abc import Callable, MutableSet
28
+ from pathlib import Path
29
+
30
+ from utilities.types import MaybeSequenceStr, PathLike
31
+
32
+
33
+ @command(**CONTEXT_SETTINGS)
34
+ @paths_argument
35
+ @python_option
36
+ @python_uv_index_option
37
+ @python_uv_native_tls_option
38
+ @python_version_option
39
+ def _main(
40
+ *,
41
+ paths: tuple[Path, ...],
42
+ python: bool = False,
43
+ python_uv_index: MaybeSequenceStr | None = None,
44
+ python_uv_native_tls: bool = False,
45
+ python_version: str = DEFAULT_PYTHON_VERSION,
46
+ ) -> None:
47
+ if is_pytest():
48
+ return
49
+ funcs: list[Callable[[], bool]] = [
50
+ partial(
51
+ _run,
52
+ path=p.parent / ENVRC,
53
+ python=python,
54
+ python_uv_index=python_uv_index,
55
+ python_uv_native_tls=python_uv_native_tls,
56
+ python_version=python_version,
57
+ )
58
+ for p in paths
59
+ ]
60
+ run_all_maybe_raise(*funcs)
61
+
62
+
63
+ def _run(
64
+ *,
65
+ path: PathLike = ENVRC,
66
+ python: bool = False,
67
+ python_uv_index: MaybeSequenceStr | None = None,
68
+ python_uv_native_tls: bool = False,
69
+ python_version: str = DEFAULT_PYTHON_VERSION,
70
+ ) -> bool:
71
+ modifications: set[Path] = set()
72
+ with yield_text_file(path, modifications=modifications) as context:
73
+ text = strip_and_dedent("""
74
+ #!/usr/bin/env sh
75
+ # shellcheck source=/dev/null
76
+
77
+ # echo
78
+ echo_date() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2; }
79
+ """)
80
+ if search(escape(text), context.output, flags=MULTILINE) is None:
81
+ context.output += f"\n\n{text}"
82
+ if python:
83
+ _add_python(
84
+ path=path,
85
+ modifications=modifications,
86
+ uv_index=python_uv_index,
87
+ uv_native_tls=python_uv_native_tls,
88
+ version=python_version,
89
+ )
90
+ return len(modifications) == 0
91
+
92
+
93
+ def _add_python(
94
+ *,
95
+ path: PathLike = ENVRC,
96
+ modifications: MutableSet[Path] | None = None,
97
+ uv_index: MaybeSequenceStr | None = None,
98
+ uv_native_tls: bool = False,
99
+ version: str = DEFAULT_PYTHON_VERSION,
100
+ ) -> None:
101
+ with yield_text_file(path, modifications=modifications) as context:
102
+ text = _get_text(
103
+ uv_index=uv_index, uv_native_tls=uv_native_tls, version=version
104
+ )
105
+ if search(escape(text), context.output, flags=MULTILINE) is None:
106
+ context.output += f"\n\n{text}"
107
+
108
+
109
+ def _get_text(
110
+ *,
111
+ uv_index: MaybeSequenceStr | None = None,
112
+ uv_native_tls: bool = False,
113
+ version: str = DEFAULT_PYTHON_VERSION,
114
+ ) -> str:
115
+ lines: list[str] = ["# uv", "export UV_MANAGED_PYTHON='true'"]
116
+ if uv_index is not None:
117
+ lines.append(f"export UV_INDEX='{','.join(always_iterable(uv_index))}'")
118
+ if uv_native_tls:
119
+ lines.append("export UV_NATIVE_TLS='true'")
120
+ lines.extend([
121
+ "export UV_PRERELEASE='disallow'",
122
+ f"export UV_PYTHON='{version}'",
123
+ "export UV_RESOLUTION='highest'",
124
+ "export UV_VENV_CLEAR=1",
125
+ strip_and_dedent("""\
126
+ if ! command -v uv >/dev/null 2>&1; then
127
+ \techo_date "ERROR: 'uv' not found" && exit 1
128
+ fi
129
+ """),
130
+ "activate='.venv/bin/activate'",
131
+ strip_and_dedent("""\
132
+ if [ -f $activate ]; then
133
+ \t. $activate
134
+ else
135
+ \tuv venv
136
+ fi
137
+ """),
138
+ "uv sync --all-extras --all-groups --active --locked",
139
+ ])
140
+ return "\n".join(lines) + "\n"
141
+
142
+
143
+ if __name__ == "__main__":
144
+ _main()
@@ -0,0 +1,179 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from pathlib import Path
5
+ from typing import TYPE_CHECKING
6
+
7
+ from click import command
8
+ from tomlkit import table
9
+ from utilities.click import CONTEXT_SETTINGS
10
+ from utilities.iterables import always_iterable
11
+ from utilities.os import is_pytest
12
+ from utilities.text import kebab_case, snake_case
13
+
14
+ from pre_commit_hooks.constants import (
15
+ DEFAULT_PYTHON_VERSION,
16
+ PYPROJECT_TOML,
17
+ README_MD,
18
+ description_option,
19
+ paths_argument,
20
+ python_package_name_external_option,
21
+ python_package_name_internal_option,
22
+ python_uv_index_option,
23
+ python_version_option,
24
+ )
25
+ from pre_commit_hooks.utilities import (
26
+ ensure_contains,
27
+ ensure_contains_partial_str,
28
+ get_set_aot,
29
+ get_set_array,
30
+ get_set_table,
31
+ get_table,
32
+ run_all_maybe_raise,
33
+ yield_toml_doc,
34
+ )
35
+
36
+ if TYPE_CHECKING:
37
+ from collections.abc import Callable, MutableSet
38
+
39
+ from tomlkit import TOMLDocument
40
+ from tomlkit.items import Table
41
+ from utilities.types import MaybeSequenceStr, PathLike
42
+
43
+
44
+ @command(**CONTEXT_SETTINGS)
45
+ @paths_argument
46
+ @python_version_option
47
+ @description_option
48
+ @python_package_name_external_option
49
+ @python_package_name_internal_option
50
+ @python_uv_index_option
51
+ def _main(
52
+ *,
53
+ paths: tuple[Path, ...],
54
+ python_version: str = DEFAULT_PYTHON_VERSION,
55
+ description: str | None = None,
56
+ python_package_name_external: str | None = None,
57
+ python_package_name_internal: str | None = None,
58
+ python_uv_index: MaybeSequenceStr | None = None,
59
+ ) -> None:
60
+ if is_pytest():
61
+ return
62
+ funcs: list[Callable[[], bool]] = [
63
+ partial(
64
+ _run,
65
+ path=p.parent / PYPROJECT_TOML,
66
+ python_version=python_version,
67
+ description=description,
68
+ python_package_name_external=python_package_name_external,
69
+ python_package_name_internal=python_package_name_internal,
70
+ python_uv_index=python_uv_index,
71
+ )
72
+ for p in paths
73
+ ]
74
+ run_all_maybe_raise(*funcs)
75
+
76
+
77
+ def _run(
78
+ *,
79
+ path: PathLike = PYPROJECT_TOML,
80
+ python_version: str = DEFAULT_PYTHON_VERSION,
81
+ description: str | None = None,
82
+ python_package_name_external: str | None = None,
83
+ python_package_name_internal: str | None = None,
84
+ python_uv_index: MaybeSequenceStr | None = None,
85
+ ) -> bool:
86
+ path = Path(path)
87
+ modifications: set[Path] = set()
88
+ with yield_toml_doc(path, modifications=modifications) as doc:
89
+ build_system = get_set_table(doc, "build-system")
90
+ build_system["build-backend"] = "uv_build"
91
+ build_system["requires"] = ["uv_build"]
92
+ project = get_set_table(doc, "project")
93
+ project["readme"] = str(path.parent / README_MD)
94
+ project["requires-python"] = f">= {python_version}"
95
+ project.setdefault("version", "0.1.0")
96
+ dependency_groups = get_set_table(doc, "dependency-groups")
97
+ dev = get_set_array(dependency_groups, "dev")
98
+ _ = ensure_contains_partial_str(dev, "dycw-utilities[test]")
99
+ _ = ensure_contains_partial_str(dev, "pyright")
100
+ _ = ensure_contains_partial_str(dev, "rich")
101
+ if description is not None:
102
+ _add_description(description, path=path, modifications=modifications)
103
+ if python_package_name_external is not None:
104
+ _add_external_name(
105
+ python_package_name_external, path=path, modifications=modifications
106
+ )
107
+ if python_package_name_internal is not None:
108
+ _add_internal_name(
109
+ python_package_name_internal, path=path, modifications=modifications
110
+ )
111
+ if python_uv_index is not None:
112
+ for name_and_url in always_iterable(python_uv_index):
113
+ _add_index(name_and_url, path=path, modifications=modifications)
114
+ return len(modifications) == 0
115
+
116
+
117
+ def _add_description(
118
+ description: str,
119
+ /,
120
+ *,
121
+ path: PathLike = PYPROJECT_TOML,
122
+ modifications: MutableSet[Path] | None = None,
123
+ ) -> None:
124
+ with yield_toml_doc(path, modifications=modifications) as doc:
125
+ project = get_table(doc, "project")
126
+ project["description"] = description
127
+
128
+
129
+ def _add_external_name(
130
+ name: str,
131
+ /,
132
+ *,
133
+ path: PathLike = PYPROJECT_TOML,
134
+ modifications: MutableSet[Path] | None = None,
135
+ ) -> None:
136
+ with yield_toml_doc(path, modifications=modifications) as doc:
137
+ project = get_table(doc, "project")
138
+ project["name"] = kebab_case(name)
139
+
140
+
141
+ def _add_internal_name(
142
+ name: str,
143
+ /,
144
+ *,
145
+ path: PathLike = PYPROJECT_TOML,
146
+ modifications: MutableSet[Path] | None = None,
147
+ ) -> None:
148
+ with yield_toml_doc(path, modifications=modifications) as doc:
149
+ uv = _get_tool_uv(doc)
150
+ build_backend = get_set_table(uv, "build-backend")
151
+ build_backend["module-name"] = snake_case(name)
152
+ build_backend["module-root"] = "src"
153
+
154
+
155
+ def _add_index(
156
+ name_and_url: str,
157
+ /,
158
+ *,
159
+ path: PathLike = PYPROJECT_TOML,
160
+ modifications: MutableSet[Path] | None = None,
161
+ ) -> None:
162
+ with yield_toml_doc(path, modifications=modifications) as doc:
163
+ uv = _get_tool_uv(doc)
164
+ indexes = get_set_aot(uv, "index")
165
+ tab = table()
166
+ tab["explicit"] = True
167
+ name, url = name_and_url
168
+ tab["name"] = name
169
+ tab["url"] = url
170
+ ensure_contains(indexes, tab)
171
+
172
+
173
+ def _get_tool_uv(doc: TOMLDocument, /) -> Table:
174
+ tool = get_set_table(doc, "tool")
175
+ return get_set_table(tool, "uv")
176
+
177
+
178
+ if __name__ == "__main__":
179
+ _main()
@@ -21,6 +21,7 @@ from pre_commit_hooks.utilities import (
21
21
  )
22
22
 
23
23
  if TYPE_CHECKING:
24
+ from collections.abc import Callable
24
25
  from pathlib import Path
25
26
 
26
27
  from utilities.types import PathLike
@@ -34,14 +35,11 @@ def _main(
34
35
  ) -> None:
35
36
  if is_pytest():
36
37
  return
37
- run_all_maybe_raise(
38
- *(
39
- partial(
40
- _run, path=p.parent / PYRIGHTCONFIG_JSON, python_version=python_version
41
- )
42
- for p in paths
43
- )
44
- )
38
+ funcs: list[Callable[[], bool]] = [
39
+ partial(_run, path=p.parent / PYRIGHTCONFIG_JSON, python_version=python_version)
40
+ for p in paths
41
+ ]
42
+ run_all_maybe_raise(*funcs)
45
43
 
46
44
 
47
45
  def _run(
@@ -0,0 +1,76 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from re import MULTILINE, escape, search
5
+ from typing import TYPE_CHECKING
6
+
7
+ from click import command
8
+ from utilities.click import CONTEXT_SETTINGS
9
+ from utilities.os import is_pytest
10
+
11
+ from pre_commit_hooks.constants import (
12
+ README_MD,
13
+ description_option,
14
+ paths_argument,
15
+ repo_name_option,
16
+ )
17
+ from pre_commit_hooks.utilities import run_all_maybe_raise, yield_text_file
18
+
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Callable, MutableSet
21
+ from pathlib import Path
22
+
23
+ from utilities.types import PathLike
24
+
25
+
26
+ @command(**CONTEXT_SETTINGS)
27
+ @paths_argument
28
+ @repo_name_option
29
+ @description_option
30
+ def _main(
31
+ *,
32
+ paths: tuple[Path, ...],
33
+ repo_name: str | None = None,
34
+ description: str | None = None,
35
+ ) -> None:
36
+ if is_pytest():
37
+ return
38
+ funcs: list[Callable[[], bool]] = [
39
+ partial(
40
+ _run,
41
+ path=p.parent / README_MD,
42
+ repo_name=repo_name,
43
+ description=description,
44
+ )
45
+ for p in paths
46
+ ]
47
+ run_all_maybe_raise(*funcs)
48
+
49
+
50
+ def _run(
51
+ *,
52
+ path: PathLike = README_MD,
53
+ repo_name: str | None = None,
54
+ description: str | None = None,
55
+ ) -> bool:
56
+ modifications: set[Path] = set()
57
+ if (repo_name is not None) and (description is not None):
58
+ _add_header(repo_name, description, path=path, modifications=modifications)
59
+ return len(modifications) == 0
60
+
61
+
62
+ def _add_header(
63
+ repo_name: str,
64
+ description: str,
65
+ path: PathLike = README_MD,
66
+ modifications: MutableSet[Path] | None = None,
67
+ ) -> None:
68
+ with yield_text_file(path, modifications=modifications) as context:
69
+ lines = [f"# `{repo_name}`", description]
70
+ text = "\n\n".join(lines)
71
+ if search(escape(text), context.output, flags=MULTILINE) is None:
72
+ context.output += f"\n\n{text}"
73
+
74
+
75
+ if __name__ == "__main__":
76
+ _main()
@@ -23,6 +23,7 @@ from pre_commit_hooks.utilities import (
23
23
  )
24
24
 
25
25
  if TYPE_CHECKING:
26
+ from collections.abc import Callable
26
27
  from pathlib import Path
27
28
 
28
29
  from utilities.types import PathLike
@@ -36,12 +37,11 @@ def _main(
36
37
  ) -> None:
37
38
  if is_pytest():
38
39
  return
39
- run_all_maybe_raise(
40
- *(
41
- partial(_run, path=p.parent / RUFF_TOML, python_version=python_version)
42
- for p in paths
43
- )
44
- )
40
+ funcs: list[Callable[[], bool]] = [
41
+ partial(_run, path=p.parent / RUFF_TOML, python_version=python_version)
42
+ for p in paths
43
+ ]
44
+ run_all_maybe_raise(*funcs)
45
45
 
46
46
 
47
47
  def _run(
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from re import MULTILINE, sub
5
+ from typing import TYPE_CHECKING
6
+
7
+ from click import command
8
+ from utilities.click import CONTEXT_SETTINGS
9
+ from utilities.os import is_pytest
10
+
11
+ from pre_commit_hooks.constants import paths_argument
12
+ from pre_commit_hooks.utilities import run_all_maybe_raise, yield_text_file
13
+
14
+ if TYPE_CHECKING:
15
+ from pathlib import Path
16
+
17
+ from utilities.types import PathLike
18
+
19
+
20
+ @command(**CONTEXT_SETTINGS)
21
+ @paths_argument
22
+ def _main(*, paths: tuple[Path, ...]) -> None:
23
+ if is_pytest():
24
+ return
25
+ run_all_maybe_raise(*(partial(_run, p) for p in paths))
26
+
27
+
28
+ def _run(path: PathLike, /) -> bool:
29
+ modifications: set[Path] = set()
30
+ versions = {
31
+ "actions/checkout": "v6",
32
+ "actions/setup-python": "v6",
33
+ "astral-sh/ruff-action": "v3",
34
+ "astral-sh/setup-uv": "v7",
35
+ }
36
+ with yield_text_file(path, modifications=modifications) as context:
37
+ text = context.input
38
+ for action, version in versions.items():
39
+ text = sub(
40
+ rf"^(\s*- uses: {action})@.+$", rf"\1@{version}", text, flags=MULTILINE
41
+ )
42
+ context.output = text
43
+ return len(modifications) == 0
44
+
45
+
46
+ if __name__ == "__main__":
47
+ _main()
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from pathlib import Path
5
+ from typing import TYPE_CHECKING
6
+
7
+ from click import command
8
+ from utilities.atomicwrites import move
9
+ from utilities.click import CONTEXT_SETTINGS
10
+ from utilities.os import is_pytest
11
+
12
+ from pre_commit_hooks.constants import paths_argument
13
+ from pre_commit_hooks.utilities import run_all_maybe_raise
14
+
15
+ if TYPE_CHECKING:
16
+ from utilities.types import PathLike
17
+
18
+
19
+ @command(**CONTEXT_SETTINGS)
20
+ @paths_argument
21
+ def _main(*, paths: tuple[Path, ...]) -> None:
22
+ if is_pytest():
23
+ return
24
+ run_all_maybe_raise(*(partial(_run, p) for p in paths))
25
+
26
+
27
+ def _run(path: PathLike, /) -> bool:
28
+ new = Path(path).with_suffix(".yaml")
29
+ move(path, new)
30
+ return False
31
+
32
+
33
+ if __name__ == "__main__":
34
+ _main()
@@ -19,6 +19,7 @@ from pre_commit_hooks.utilities import (
19
19
  )
20
20
 
21
21
  if TYPE_CHECKING:
22
+ from collections.abc import Callable
22
23
  from pathlib import Path
23
24
 
24
25
  from utilities.packaging import Requirement
@@ -39,12 +40,11 @@ def _main(
39
40
  if is_pytest():
40
41
  return
41
42
  versions = _get_versions(index=index, native_tls=native_tls)
42
- run_all_maybe_raise(
43
- *(
44
- partial(_run, path=p, versions=versions, index=index, native_tls=native_tls)
45
- for p in paths
46
- )
47
- )
43
+ funcs: list[Callable[[], bool]] = [
44
+ partial(_run, path=p, versions=versions, index=index, native_tls=native_tls)
45
+ for p in paths
46
+ ]
47
+ run_all_maybe_raise(*funcs)
48
48
 
49
49
 
50
50
  def _get_versions(