dycw-pre-commit-hooks 0.12.8__py3-none-any.whl → 0.14.39__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.
Files changed (42) hide show
  1. dycw_pre_commit_hooks-0.14.39.dist-info/METADATA +57 -0
  2. dycw_pre_commit_hooks-0.14.39.dist-info/RECORD +28 -0
  3. {dycw_pre_commit_hooks-0.12.8.dist-info → dycw_pre_commit_hooks-0.14.39.dist-info}/WHEEL +1 -1
  4. dycw_pre_commit_hooks-0.14.39.dist-info/entry_points.txt +19 -0
  5. pre_commit_hooks/__init__.py +1 -1
  6. pre_commit_hooks/configs/gitignore +243 -0
  7. pre_commit_hooks/constants.py +166 -0
  8. pre_commit_hooks/hooks/__init__.py +1 -0
  9. pre_commit_hooks/hooks/add_future_import_annotations.py +63 -0
  10. pre_commit_hooks/hooks/add_hooks.py +785 -0
  11. pre_commit_hooks/hooks/check_version_bumped.py +37 -0
  12. pre_commit_hooks/hooks/check_versions_consistent.py +42 -0
  13. pre_commit_hooks/hooks/format_pre_commit_config.py +70 -0
  14. pre_commit_hooks/hooks/format_requirements.py +56 -0
  15. pre_commit_hooks/{replace_sequence_str/__init__.py → hooks/replace_sequence_str.py} +25 -19
  16. pre_commit_hooks/hooks/run_prek_autoupdate.py +56 -0
  17. pre_commit_hooks/hooks/run_version_bump.py +48 -0
  18. pre_commit_hooks/hooks/setup_bump_my_version.py +99 -0
  19. pre_commit_hooks/hooks/setup_direnv.py +142 -0
  20. pre_commit_hooks/hooks/setup_git.py +40 -0
  21. pre_commit_hooks/hooks/setup_pyright.py +82 -0
  22. pre_commit_hooks/hooks/setup_ruff.py +129 -0
  23. pre_commit_hooks/hooks/update_ci_action_versions.py +47 -0
  24. pre_commit_hooks/hooks/update_ci_extensions.py +34 -0
  25. pre_commit_hooks/hooks/update_requirements.py +165 -0
  26. pre_commit_hooks/types.py +18 -0
  27. pre_commit_hooks/utilities.py +599 -0
  28. dycw_pre_commit_hooks-0.12.8.dist-info/METADATA +0 -46
  29. dycw_pre_commit_hooks-0.12.8.dist-info/RECORD +0 -19
  30. dycw_pre_commit_hooks-0.12.8.dist-info/entry_points.txt +0 -7
  31. pre_commit_hooks/check_submodules/__init__.py +0 -50
  32. pre_commit_hooks/check_submodules/__main__.py +0 -6
  33. pre_commit_hooks/common.py +0 -131
  34. pre_commit_hooks/format_requirements/__init__.py +0 -107
  35. pre_commit_hooks/format_requirements/__main__.py +0 -6
  36. pre_commit_hooks/mirror_files/__init__.py +0 -57
  37. pre_commit_hooks/mirror_files/__main__.py +0 -6
  38. pre_commit_hooks/replace_sequence_str/__main__.py +0 -6
  39. pre_commit_hooks/run_bump_my_version/__init__.py +0 -53
  40. pre_commit_hooks/run_bump_my_version/__main__.py +0 -6
  41. pre_commit_hooks/tag_commits/__init__.py +0 -103
  42. pre_commit_hooks/tag_commits/__main__.py +0 -6
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from click import command
6
+ from utilities.click import CONTEXT_SETTINGS
7
+ from utilities.os import is_pytest
8
+
9
+ from pre_commit_hooks.constants import BUMPVERSION_TOML
10
+ from pre_commit_hooks.utilities import (
11
+ get_version_from_path,
12
+ get_version_origin_master,
13
+ run_all_maybe_raise,
14
+ )
15
+
16
+ if TYPE_CHECKING:
17
+ from utilities.types import PathLike
18
+
19
+
20
+ @command(**CONTEXT_SETTINGS)
21
+ def _main() -> None:
22
+ if is_pytest():
23
+ return
24
+ run_all_maybe_raise(_run)
25
+
26
+
27
+ def _run(*, path: PathLike = BUMPVERSION_TOML) -> bool:
28
+ try:
29
+ current = get_version_from_path(path=path)
30
+ prev = get_version_origin_master(path=path)
31
+ except ValueError:
32
+ return False
33
+ return current != prev
34
+
35
+
36
+ if __name__ == "__main__":
37
+ _main()
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from subprocess import CalledProcessError
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 BUMPVERSION_TOML, paths_argument
12
+ from pre_commit_hooks.utilities import (
13
+ get_version_from_path,
14
+ run_all_maybe_raise,
15
+ set_version,
16
+ )
17
+
18
+ if TYPE_CHECKING:
19
+ from pathlib import Path
20
+
21
+ from utilities.types import PathLike
22
+
23
+
24
+ @command(**CONTEXT_SETTINGS)
25
+ @paths_argument
26
+ def _main(*, paths: tuple[Path, ...]) -> None:
27
+ if is_pytest():
28
+ return
29
+ run_all_maybe_raise(*(partial(_run, path=p) for p in paths))
30
+
31
+
32
+ def _run(*, path: PathLike = BUMPVERSION_TOML) -> bool:
33
+ version = get_version_from_path(path=path)
34
+ try:
35
+ set_version(version, path=path)
36
+ except CalledProcessError:
37
+ return False
38
+ return True
39
+
40
+
41
+ if __name__ == "__main__":
42
+ _main()
@@ -0,0 +1,70 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import suppress
4
+ from functools import partial
5
+ from pathlib import Path
6
+ from typing import TYPE_CHECKING
7
+
8
+ from click import command
9
+ from utilities.click import CONTEXT_SETTINGS
10
+ from utilities.os import is_pytest
11
+ from utilities.types import PathLike
12
+
13
+ from pre_commit_hooks.constants import (
14
+ PRE_COMMIT_CONFIG_HOOK_KEYS,
15
+ PRE_COMMIT_CONFIG_REPO_KEYS,
16
+ PRE_COMMIT_CONFIG_YAML,
17
+ PRE_COMMIT_HOOKS_HOOK_KEYS,
18
+ paths_argument,
19
+ )
20
+ from pre_commit_hooks.utilities import (
21
+ get_list_dicts,
22
+ run_all_maybe_raise,
23
+ yield_yaml_dict,
24
+ )
25
+
26
+ if TYPE_CHECKING:
27
+ from utilities.types import PathLike, StrDict, StrMapping
28
+
29
+
30
+ @command(**CONTEXT_SETTINGS)
31
+ @paths_argument
32
+ def _main(*, paths: tuple[Path, ...]) -> None:
33
+ if is_pytest():
34
+ return
35
+ run_all_maybe_raise(*(partial(_run, path=p) for p in paths))
36
+
37
+
38
+ def _run(*, path: PathLike = PRE_COMMIT_CONFIG_YAML) -> bool:
39
+ path = Path(path)
40
+ current = path.read_text()
41
+ 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":
49
+ keys = PRE_COMMIT_HOOKS_HOOK_KEYS
50
+ else:
51
+ keys = PRE_COMMIT_CONFIG_HOOK_KEYS
52
+ for hook_dict in hooks_list:
53
+ _re_insert(hook_dict, keys)
54
+ return path.read_text() == current
55
+
56
+
57
+ def _re_insert(dict_: StrDict, keys: list[str], /) -> None:
58
+ copy = dict_.copy()
59
+ dict_.clear()
60
+ for key in keys:
61
+ with suppress(KeyError):
62
+ dict_[key] = copy[key]
63
+
64
+
65
+ def _sort_key(mapping: StrMapping, /) -> tuple[str, str]:
66
+ return mapping["repo"], mapping.get("rev", "")
67
+
68
+
69
+ if __name__ == "__main__":
70
+ _main()
@@ -0,0 +1,56 @@
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 string
9
+ from tomlkit.items import Array
10
+ from utilities.click import CONTEXT_SETTINGS
11
+ from utilities.functions import ensure_str
12
+ from utilities.os import is_pytest
13
+ from utilities.packaging import Requirement
14
+ from utilities.types import PathLike
15
+
16
+ from pre_commit_hooks.constants import PYPROJECT_TOML, paths_argument
17
+ from pre_commit_hooks.utilities import (
18
+ get_pyproject_dependencies,
19
+ run_all_maybe_raise,
20
+ yield_toml_doc,
21
+ )
22
+
23
+ if TYPE_CHECKING:
24
+ from pathlib import Path
25
+
26
+ from tomlkit.items import Array
27
+ from utilities.types import PathLike
28
+
29
+
30
+ @command(**CONTEXT_SETTINGS)
31
+ @paths_argument
32
+ def _main(*, paths: tuple[Path, ...]) -> None:
33
+ if is_pytest():
34
+ return
35
+ run_all_maybe_raise(*(partial(_run, path=p) for p in paths))
36
+
37
+
38
+ def _run(*, path: PathLike = PYPROJECT_TOML) -> bool:
39
+ modifications: set[Path] = set()
40
+ with yield_toml_doc(path, modifications=modifications) as doc:
41
+ get_pyproject_dependencies(doc).map_array(_transform)
42
+ return len(modifications) == 0
43
+
44
+
45
+ def _transform(array: Array, /) -> None:
46
+ new: list[str] = []
47
+ for curr_i in array:
48
+ req = Requirement(ensure_str(curr_i))
49
+ new.append(str(req))
50
+ array.clear()
51
+ for new_i in sorted(new):
52
+ array.append(string(new_i))
53
+
54
+
55
+ if __name__ == "__main__":
56
+ _main()
@@ -1,38 +1,43 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from functools import partial
3
4
  from typing import TYPE_CHECKING, override
4
5
 
5
- import utilities.click
6
- from click import argument, command
7
- from libcst import CSTTransformer, Name, Subscript, parse_module
6
+ from click import command
7
+ from libcst import CSTTransformer, Name, Subscript
8
8
  from libcst.matchers import Index as MIndex
9
9
  from libcst.matchers import Name as MName
10
10
  from libcst.matchers import Subscript as MSubscript
11
11
  from libcst.matchers import SubscriptElement as MSubscriptElement
12
12
  from libcst.matchers import matches
13
13
  from libcst.metadata import MetadataWrapper
14
+ from utilities.click import CONTEXT_SETTINGS
15
+ from utilities.os import is_pytest
16
+
17
+ from pre_commit_hooks.constants import paths_argument
18
+ from pre_commit_hooks.utilities import run_all_maybe_raise, yield_python_file
14
19
 
15
20
  if TYPE_CHECKING:
16
21
  from pathlib import Path
17
22
 
23
+ from utilities.types import PathLike
24
+
18
25
 
19
- @command()
20
- @argument("paths", nargs=-1, type=utilities.click.Path())
21
- def main(*, paths: tuple[Path, ...]) -> bool:
22
- """CLI for the `replace-sequence-str` hook."""
23
- results = list(map(_process, paths)) # run all
24
- return all(results)
26
+ @command(**CONTEXT_SETTINGS)
27
+ @paths_argument
28
+ def _main(*, paths: tuple[Path, ...]) -> None:
29
+ if is_pytest():
30
+ return
31
+ run_all_maybe_raise(*(partial(_run, p) for p in paths))
25
32
 
26
33
 
27
- def _process(path: Path, /) -> bool:
28
- existing = path.read_text()
29
- wrapper = MetadataWrapper(parse_module(existing))
30
- transformed = wrapper.module.visit(SequenceToListTransformer())
31
- new = transformed.code
32
- if existing == new:
33
- return True
34
- _ = path.write_text(new)
35
- return False
34
+ def _run(path: PathLike, /) -> bool:
35
+ modifications: set[Path] = set()
36
+ with yield_python_file(path, modifications=modifications) as context:
37
+ context.output = MetadataWrapper(context.input).module.visit(
38
+ SequenceToListTransformer()
39
+ )
40
+ return len(modifications) == 0
36
41
 
37
42
 
38
43
  class SequenceToListTransformer(CSTTransformer):
@@ -52,4 +57,5 @@ class SequenceToListTransformer(CSTTransformer):
52
57
  return updated_node
53
58
 
54
59
 
55
- __all__ = ["main"]
60
+ if __name__ == "__main__":
61
+ _main()
@@ -0,0 +1,56 @@
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.subprocess import run
11
+ from utilities.throttle import throttle
12
+
13
+ from pre_commit_hooks.constants import (
14
+ PRE_COMMIT_CONFIG_YAML,
15
+ THROTTLE_DURATION,
16
+ paths_argument,
17
+ throttle_option,
18
+ )
19
+ from pre_commit_hooks.utilities import path_throttle_cache, run_all_maybe_raise
20
+
21
+ if TYPE_CHECKING:
22
+ from collections.abc import MutableSet
23
+ from pathlib import Path
24
+
25
+
26
+ @command(**CONTEXT_SETTINGS)
27
+ @paths_argument
28
+ @throttle_option
29
+ def _main(*, paths: tuple[Path, ...], throttle: bool = True) -> None:
30
+ if is_pytest():
31
+ return
32
+ if len(paths) >= 1:
33
+ run_all_maybe_raise(partial(_run, throttle=throttle))
34
+
35
+
36
+ def _run(*, throttle: bool = False) -> bool:
37
+ modifications: set[Path] = set()
38
+ func = _run_throttled if throttle else _run_unthrottled
39
+ func(modifications=modifications)
40
+ return len(modifications) == 0
41
+
42
+
43
+ def _run_unthrottled(*, modifications: MutableSet[Path] | None = None) -> None:
44
+ current = PRE_COMMIT_CONFIG_YAML.read_text()
45
+ run("prek", "autoupdate")
46
+ if (modifications is not None) and (PRE_COMMIT_CONFIG_YAML.read_text() != current):
47
+ modifications.add(PRE_COMMIT_CONFIG_YAML)
48
+
49
+
50
+ _run_throttled = throttle(
51
+ duration=THROTTLE_DURATION, path=path_throttle_cache("run-prek-autoupdate")
52
+ )(_run_unthrottled)
53
+
54
+
55
+ if __name__ == "__main__":
56
+ _main()
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from typing import TYPE_CHECKING
5
+
6
+ from click import command
7
+ from utilities.click import CONTEXT_SETTINGS
8
+ from utilities.os import is_pytest
9
+ from utilities.version import Version3
10
+
11
+ from pre_commit_hooks.constants import BUMPVERSION_TOML, paths_argument
12
+ from pre_commit_hooks.utilities import (
13
+ get_version_from_path,
14
+ get_version_origin_master,
15
+ run_all_maybe_raise,
16
+ set_version,
17
+ )
18
+
19
+ if TYPE_CHECKING:
20
+ from pathlib import Path
21
+
22
+ from utilities.types import PathLike
23
+
24
+
25
+ @command(**CONTEXT_SETTINGS)
26
+ @paths_argument
27
+ def _main(*, paths: tuple[Path, ...]) -> None:
28
+ if is_pytest():
29
+ return
30
+ run_all_maybe_raise(*(partial(_run, path=p) for p in paths))
31
+
32
+
33
+ def _run(*, path: PathLike = BUMPVERSION_TOML) -> bool:
34
+ try:
35
+ prev = get_version_origin_master(path=path)
36
+ current = get_version_from_path(path=path)
37
+ except ValueError:
38
+ set_version(Version3(0, 1, 0), path=path)
39
+ return False
40
+ patched = prev.bump_patch()
41
+ if current in {patched, prev.bump_minor(), prev.bump_major()}:
42
+ return True
43
+ set_version(patched, path=path)
44
+ return False
45
+
46
+
47
+ if __name__ == "__main__":
48
+ _main()
@@ -0,0 +1,99 @@
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.os import is_pytest
11
+ from utilities.string import substitute
12
+ from utilities.version import Version3
13
+
14
+ from pre_commit_hooks.constants import (
15
+ BUMPVERSION_TOML,
16
+ PYPROJECT_TOML,
17
+ paths_argument,
18
+ python_package_name_option,
19
+ )
20
+ from pre_commit_hooks.utilities import (
21
+ ensure_contains,
22
+ get_set_aot,
23
+ get_set_table,
24
+ get_table,
25
+ run_all_maybe_raise,
26
+ yield_toml_doc,
27
+ )
28
+
29
+ if TYPE_CHECKING:
30
+ from collections.abc import MutableSet
31
+
32
+ from utilities.types import PathLike
33
+
34
+
35
+ @command(**CONTEXT_SETTINGS)
36
+ @paths_argument
37
+ @python_package_name_option
38
+ def _main(*, paths: tuple[Path, ...], python_package_name: str | None = None) -> None:
39
+ if is_pytest():
40
+ return
41
+ run_all_maybe_raise(
42
+ *(
43
+ partial(
44
+ _run,
45
+ path=p.parent / BUMPVERSION_TOML,
46
+ python_package_name=python_package_name,
47
+ )
48
+ for p in paths
49
+ )
50
+ )
51
+
52
+
53
+ def _run(
54
+ *, path: PathLike = BUMPVERSION_TOML, python_package_name: str | None = None
55
+ ) -> bool:
56
+ path = Path(path)
57
+ modifications: set[Path] = set()
58
+ with yield_toml_doc(path, modifications=modifications) as doc:
59
+ tool = get_set_table(doc, "tool")
60
+ bumpversion = get_set_table(tool, "bumpversion")
61
+ bumpversion["allow_dirty"] = True
62
+ bumpversion.setdefault("current_version", str(Version3(0, 1, 0)))
63
+ if python_package_name is not None:
64
+ _add_file(
65
+ 'version = "${version}"',
66
+ path.parent / PYPROJECT_TOML,
67
+ path_bumpversion_toml=path,
68
+ modifications=modifications,
69
+ )
70
+ _add_file(
71
+ '__version__ = "${version}"',
72
+ path.parent / "src" / python_package_name / "__init__.py",
73
+ path_bumpversion_toml=path,
74
+ modifications=modifications,
75
+ )
76
+ return len(modifications) == 0
77
+
78
+
79
+ def _add_file(
80
+ path_data: PathLike,
81
+ template: PathLike,
82
+ /,
83
+ *,
84
+ path_bumpversion_toml: PathLike = BUMPVERSION_TOML,
85
+ modifications: MutableSet[Path] | None = None,
86
+ ) -> None:
87
+ with yield_toml_doc(path_bumpversion_toml, modifications=modifications) as doc:
88
+ tool = get_table(doc, "tool")
89
+ bumpversion = get_table(tool, "bumpversion")
90
+ files = get_set_aot(bumpversion, "files")
91
+ tab = table()
92
+ tab["filename"] = str(path_data)
93
+ tab["search"] = substitute(template, version="{current_version}")
94
+ tab["replace"] = substitute(template, version="{new_version}")
95
+ ensure_contains(files, tab)
96
+
97
+
98
+ if __name__ == "__main__":
99
+ _main()
@@ -0,0 +1,142 @@
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 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
+ run_all_maybe_raise(
50
+ *(
51
+ partial(
52
+ _run,
53
+ path=p.parent / ENVRC,
54
+ python=python,
55
+ python_uv_index=python_uv_index,
56
+ python_uv_native_tls=python_uv_native_tls,
57
+ python_version=python_version,
58
+ )
59
+ for p in paths
60
+ )
61
+ )
62
+
63
+
64
+ def _run(
65
+ *,
66
+ path: PathLike = ENVRC,
67
+ python: bool = False,
68
+ python_uv_index: MaybeSequenceStr | None = None,
69
+ python_uv_native_tls: bool = False,
70
+ python_version: str = DEFAULT_PYTHON_VERSION,
71
+ ) -> bool:
72
+ modifications: set[Path] = set()
73
+ with yield_text_file(path, modifications=modifications) as context:
74
+ shebang = strip_and_dedent("""
75
+ #!/usr/bin/env sh
76
+ # shellcheck source=/dev/null
77
+ """)
78
+ if search(escape(shebang), context.output, flags=MULTILINE) is None:
79
+ context.output += f"\n\n{shebang}"
80
+ if python:
81
+ _add_python(
82
+ path=path,
83
+ modifications=modifications,
84
+ uv_index=python_uv_index,
85
+ uv_native_tls=python_uv_native_tls,
86
+ version=python_version,
87
+ )
88
+ return len(modifications) == 0
89
+
90
+
91
+ def _add_python(
92
+ *,
93
+ path: PathLike = ENVRC,
94
+ modifications: MutableSet[Path] | None = None,
95
+ uv_index: MaybeSequenceStr | None = None,
96
+ uv_native_tls: bool = False,
97
+ version: str = DEFAULT_PYTHON_VERSION,
98
+ ) -> None:
99
+ with yield_text_file(path, modifications=modifications) as context:
100
+ text = _get_text(
101
+ uv_index=uv_index, uv_native_tls=uv_native_tls, version=version
102
+ )
103
+ if search(escape(text), context.output, flags=MULTILINE) is None:
104
+ context.output += f"\n\n{text}"
105
+
106
+
107
+ def _get_text(
108
+ *,
109
+ uv_index: MaybeSequenceStr | None = None,
110
+ uv_native_tls: bool = False,
111
+ version: str = DEFAULT_PYTHON_VERSION,
112
+ ) -> str:
113
+ lines: list[str] = ["# uv", "export UV_MANAGED_PYTHON='true'"]
114
+ if uv_index is not None:
115
+ lines.append(f"export UV_INDEX='{','.join(always_iterable(uv_index))}'")
116
+ if uv_native_tls:
117
+ lines.append("export UV_NATIVE_TLS='true'")
118
+ lines.extend([
119
+ "export UV_PRERELEASE='disallow'",
120
+ f"export UV_PYTHON='{version}'",
121
+ "export UV_RESOLUTION='highest'",
122
+ "export UV_VENV_CLEAR=1",
123
+ strip_and_dedent("""\
124
+ if ! command -v uv >/dev/null 2>&1; then
125
+ \techo_date "ERROR: 'uv' not found" && exit 1
126
+ fi
127
+ """),
128
+ "activate='.venv/bin/activate'",
129
+ strip_and_dedent("""\
130
+ if [ -f $activate ]; then
131
+ \t. $activate
132
+ else
133
+ \tuv venv
134
+ fi
135
+ """),
136
+ "uv sync --all-extras --all-groups --active --locked",
137
+ ])
138
+ return "\n".join(lines) + "\n"
139
+
140
+
141
+ if __name__ == "__main__":
142
+ _main()
@@ -0,0 +1,40 @@
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.importlib import files
11
+ from utilities.os import is_pytest
12
+
13
+ from pre_commit_hooks.constants import GITIGNORE, paths_argument
14
+ from pre_commit_hooks.utilities import run_all_maybe_raise, yield_text_file
15
+
16
+ if TYPE_CHECKING:
17
+ from pathlib import Path
18
+
19
+ from utilities.types import PathLike
20
+
21
+
22
+ @command(**CONTEXT_SETTINGS)
23
+ @paths_argument
24
+ def _main(*, paths: tuple[Path, ...]) -> None:
25
+ if is_pytest():
26
+ return
27
+ run_all_maybe_raise(*(partial(_run, path=p.parent / GITIGNORE) for p in paths))
28
+
29
+
30
+ def _run(*, path: PathLike = GITIGNORE) -> bool:
31
+ modifications: set[Path] = set()
32
+ with yield_text_file(path, modifications=modifications) as context:
33
+ text = (files(anchor="pre_commit_hooks") / "configs/gitignore").read_text()
34
+ if search(escape(text), context.output, flags=MULTILINE) is None:
35
+ context.output += f"\n\n{text}"
36
+ return len(modifications) == 0
37
+
38
+
39
+ if __name__ == "__main__":
40
+ _main()