dycw-pre-commit-hooks 0.12.1__tar.gz → 0.12.3__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.
Potentially problematic release.
This version of dycw-pre-commit-hooks might be problematic. Click here for more details.
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/PKG-INFO +1 -1
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/pyproject.toml +2 -2
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/__init__.py +1 -1
- dycw_pre_commit_hooks-0.12.3/src/pre_commit_hooks/common.py +79 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/format_requirements/__init__.py +1 -3
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/run_bump_my_version/__init__.py +13 -7
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/tag_commits/__init__.py +24 -10
- dycw_pre_commit_hooks-0.12.1/src/pre_commit_hooks/common.py +0 -66
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/.gitignore +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/README.md +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/format_requirements/__main__.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/py.typed +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/replace_sequence_str/__init__.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/replace_sequence_str/__main__.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/run_bump_my_version/__main__.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/pre_commit_hooks/tag_commits/__main__.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/__init__.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/format_requirements/__init__.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/format_requirements/in.toml +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/format_requirements/out.toml +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/format_requirements/test_format_requirements.py +0 -0
- {dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/test_main.py +0 -0
|
@@ -30,7 +30,7 @@ dependencies = [
|
|
|
30
30
|
name = "dycw-pre-commit-hooks"
|
|
31
31
|
readme = "README.md"
|
|
32
32
|
requires-python = ">= 3.12"
|
|
33
|
-
version = "0.12.
|
|
33
|
+
version = "0.12.3"
|
|
34
34
|
|
|
35
35
|
[project.scripts]
|
|
36
36
|
format-requirements = "pre_commit_hooks.format_requirements:main"
|
|
@@ -41,7 +41,7 @@ tag-commits = "pre_commit_hooks.tag_commits:main"
|
|
|
41
41
|
# bump-my-version
|
|
42
42
|
[tool.bumpversion]
|
|
43
43
|
allow_dirty = true
|
|
44
|
-
current_version = "0.12.
|
|
44
|
+
current_version = "0.12.3"
|
|
45
45
|
|
|
46
46
|
[[tool.bumpversion.files]]
|
|
47
47
|
filename = "src/pre_commit_hooks/__init__.py"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Literal, assert_never
|
|
5
|
+
|
|
6
|
+
from click import Choice, option
|
|
7
|
+
from loguru import logger
|
|
8
|
+
from tomlkit import TOMLDocument, parse
|
|
9
|
+
from tomlkit.items import Table
|
|
10
|
+
from utilities.pathlib import get_repo_root
|
|
11
|
+
from utilities.typing import get_literal_elements
|
|
12
|
+
from utilities.version import Version, parse_version
|
|
13
|
+
|
|
14
|
+
type Mode = Literal["pyproject", "bumpversion"]
|
|
15
|
+
DEFAULT_MODE: Mode = "pyproject"
|
|
16
|
+
mode_option = option(
|
|
17
|
+
"--mode",
|
|
18
|
+
type=Choice(get_literal_elements(Mode), case_sensitive=False),
|
|
19
|
+
default=DEFAULT_MODE,
|
|
20
|
+
show_default=True,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_version(source: Mode | Path | str | bytes | TOMLDocument, /) -> Version:
|
|
25
|
+
"""Get the `[tool.bumpversion]` version from a TOML file."""
|
|
26
|
+
match source:
|
|
27
|
+
case "pyproject" | "bumpversion" as mode:
|
|
28
|
+
return get_version(get_toml_path(mode))
|
|
29
|
+
case Path() as path:
|
|
30
|
+
return get_version(path.read_text())
|
|
31
|
+
case str() | bytes() as text:
|
|
32
|
+
return get_version(parse(text))
|
|
33
|
+
case TOMLDocument() as doc:
|
|
34
|
+
try:
|
|
35
|
+
tool = doc["tool"]
|
|
36
|
+
except KeyError:
|
|
37
|
+
logger.exception("Failed to get version; key 'tool' does not exist")
|
|
38
|
+
raise
|
|
39
|
+
if not isinstance(tool, Table):
|
|
40
|
+
logger.exception("Failed to get version; `tool` is not a Table")
|
|
41
|
+
raise TypeError
|
|
42
|
+
try:
|
|
43
|
+
bumpversion = tool["bumpversion"]
|
|
44
|
+
except KeyError:
|
|
45
|
+
logger.exception(
|
|
46
|
+
"Failed to get version; key 'bumpversion' does not exist"
|
|
47
|
+
)
|
|
48
|
+
raise
|
|
49
|
+
if not isinstance(bumpversion, Table):
|
|
50
|
+
logger.exception("Failed to get version; `bumpversion` is not a Table")
|
|
51
|
+
raise TypeError
|
|
52
|
+
try:
|
|
53
|
+
version = bumpversion["current_version"]
|
|
54
|
+
except KeyError:
|
|
55
|
+
logger.exception(
|
|
56
|
+
"Failed to get version; key 'current_version' does not exist"
|
|
57
|
+
)
|
|
58
|
+
raise
|
|
59
|
+
if not isinstance(version, str):
|
|
60
|
+
logger.exception("Failed to get version; `version` is not a string")
|
|
61
|
+
raise TypeError
|
|
62
|
+
return parse_version(version)
|
|
63
|
+
case never: # pyright: ignore[reportUnnecessaryComparison]
|
|
64
|
+
assert_never(never)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_toml_path(mode: Mode = DEFAULT_MODE, /) -> Path:
|
|
68
|
+
root = get_repo_root()
|
|
69
|
+
match mode:
|
|
70
|
+
case "pyproject":
|
|
71
|
+
filename = "pyproject.toml"
|
|
72
|
+
case "bumpversion":
|
|
73
|
+
filename = ".bumpversion.toml"
|
|
74
|
+
case never: # pyright: ignore[reportUnnecessaryComparison]
|
|
75
|
+
assert_never(never)
|
|
76
|
+
return root.relative_to(filename)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
__all__ = ["DEFAULT_MODE", "Mode", "get_toml_path", "get_version", "mode_option"]
|
|
@@ -15,8 +15,6 @@ from tomlkit import array, dumps, loads, string
|
|
|
15
15
|
from tomlkit.items import Array, Table
|
|
16
16
|
from utilities.atomicwrites import writer
|
|
17
17
|
|
|
18
|
-
from pre_commit_hooks.common import PYPROJECT_TOML
|
|
19
|
-
|
|
20
18
|
if TYPE_CHECKING:
|
|
21
19
|
from collections.abc import Iterator
|
|
22
20
|
from pathlib import Path
|
|
@@ -106,4 +104,4 @@ class _CustomSpecifierSet(SpecifierSet):
|
|
|
106
104
|
return [">=", "<"].index(spec.operator)
|
|
107
105
|
|
|
108
106
|
|
|
109
|
-
__all__ = ["
|
|
107
|
+
__all__ = ["main"]
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from pathlib import Path
|
|
4
3
|
from subprocess import PIPE, STDOUT, CalledProcessError, check_call, check_output
|
|
5
4
|
|
|
6
5
|
from click import command
|
|
7
6
|
from loguru import logger
|
|
8
7
|
|
|
9
|
-
from pre_commit_hooks.common import
|
|
8
|
+
from pre_commit_hooks.common import (
|
|
9
|
+
DEFAULT_MODE,
|
|
10
|
+
Mode,
|
|
11
|
+
get_toml_path,
|
|
12
|
+
get_version,
|
|
13
|
+
mode_option,
|
|
14
|
+
)
|
|
10
15
|
|
|
11
16
|
|
|
12
17
|
@command()
|
|
13
|
-
|
|
18
|
+
@mode_option
|
|
19
|
+
def main(*, mode: Mode = DEFAULT_MODE) -> bool:
|
|
14
20
|
"""CLI for the `run_bump_my_version` hook."""
|
|
15
|
-
return _process()
|
|
21
|
+
return _process(mode=mode)
|
|
16
22
|
|
|
17
23
|
|
|
18
|
-
def _process() -> bool:
|
|
19
|
-
|
|
20
|
-
current = get_version(path)
|
|
24
|
+
def _process(*, mode: Mode = DEFAULT_MODE) -> bool:
|
|
25
|
+
current = get_version(mode)
|
|
21
26
|
commit = check_output(["git", "rev-parse", "origin/master"], text=True).rstrip("\n")
|
|
27
|
+
path = get_toml_path(mode)
|
|
22
28
|
contents = check_output(["git", "show", f"{commit}:{path}"], text=True)
|
|
23
29
|
master = get_version(contents)
|
|
24
30
|
if current in {master.bump_patch(), master.bump_minor(), master.bump_major()}:
|
|
@@ -13,7 +13,13 @@ from utilities.whenever import from_timestamp, get_now_local
|
|
|
13
13
|
from whenever import DateTimeDelta, ZonedDateTime
|
|
14
14
|
from xdg_base_dirs import xdg_cache_home
|
|
15
15
|
|
|
16
|
-
from pre_commit_hooks.common import
|
|
16
|
+
from pre_commit_hooks.common import (
|
|
17
|
+
DEFAULT_MODE,
|
|
18
|
+
Mode,
|
|
19
|
+
get_toml_path,
|
|
20
|
+
get_version,
|
|
21
|
+
mode_option,
|
|
22
|
+
)
|
|
17
23
|
|
|
18
24
|
if TYPE_CHECKING:
|
|
19
25
|
from collections.abc import Set as AbstractSet
|
|
@@ -35,26 +41,29 @@ _MAX_AGE: DateTimeDelta | None = None
|
|
|
35
41
|
default=_MAX_AGE,
|
|
36
42
|
show_default=True,
|
|
37
43
|
)
|
|
44
|
+
@mode_option
|
|
38
45
|
def main(
|
|
39
46
|
*,
|
|
40
47
|
run_every: DateTimeDelta | None = _RUN_EVERY,
|
|
41
48
|
max_age: DateTimeDelta | None = _MAX_AGE,
|
|
49
|
+
mode: Mode = DEFAULT_MODE,
|
|
42
50
|
) -> bool:
|
|
43
51
|
"""CLI for the `tag_commits` hook."""
|
|
44
|
-
return _process(run_every=run_every, max_age=max_age)
|
|
52
|
+
return _process(run_every=run_every, max_age=max_age, mode=mode)
|
|
45
53
|
|
|
46
54
|
|
|
47
55
|
def _process(
|
|
48
56
|
*,
|
|
49
57
|
run_every: DateTimeDelta | None = _RUN_EVERY,
|
|
50
58
|
max_age: DateTimeDelta | None = _MAX_AGE,
|
|
59
|
+
mode: Mode = DEFAULT_MODE,
|
|
51
60
|
) -> bool:
|
|
52
61
|
if run_every is not None:
|
|
53
62
|
last = _get_last_run()
|
|
54
63
|
min_date_time = get_now_local() - run_every
|
|
55
64
|
if (last is not None) and (min_date_time <= last):
|
|
56
65
|
return True
|
|
57
|
-
return _process_commits(max_age=max_age)
|
|
66
|
+
return _process_commits(max_age=max_age, mode=mode)
|
|
58
67
|
|
|
59
68
|
|
|
60
69
|
def _get_last_run() -> ZonedDateTime | None:
|
|
@@ -70,13 +79,16 @@ def _get_last_run() -> ZonedDateTime | None:
|
|
|
70
79
|
return None
|
|
71
80
|
|
|
72
81
|
|
|
73
|
-
def _process_commits(
|
|
82
|
+
def _process_commits(
|
|
83
|
+
*, max_age: DateTimeDelta | None = None, mode: Mode = DEFAULT_MODE
|
|
84
|
+
) -> bool:
|
|
74
85
|
repo = Repo(".", search_parent_directories=True)
|
|
75
86
|
tagged = {tag.commit.hexsha for tag in repo.tags}
|
|
76
87
|
min_date_time = None if max_age is None else (get_now_local() - max_age)
|
|
77
88
|
commits = reversed(list(repo.iter_commits(repo.refs["origin/master"])))
|
|
78
89
|
results = [
|
|
79
|
-
_process_commit(c, tagged, repo, min_date_time=min_date_time)
|
|
90
|
+
_process_commit(c, tagged, repo, min_date_time=min_date_time, mode=mode)
|
|
91
|
+
for c in commits
|
|
80
92
|
] # run all
|
|
81
93
|
return all(results)
|
|
82
94
|
|
|
@@ -88,13 +100,14 @@ def _process_commit(
|
|
|
88
100
|
/,
|
|
89
101
|
*,
|
|
90
102
|
min_date_time: ZonedDateTime | None = None,
|
|
103
|
+
mode: Mode = DEFAULT_MODE,
|
|
91
104
|
) -> bool:
|
|
92
105
|
if (commit.hexsha in tagged) or (
|
|
93
106
|
(min_date_time is not None) and (_get_date_time(commit) < min_date_time)
|
|
94
107
|
):
|
|
95
108
|
return True
|
|
96
109
|
try:
|
|
97
|
-
_tag_commit(commit, repo)
|
|
110
|
+
_tag_commit(commit, repo, mode=mode)
|
|
98
111
|
except GitCommandError:
|
|
99
112
|
return False
|
|
100
113
|
return True
|
|
@@ -104,16 +117,17 @@ def _get_date_time(commit: Commit, /) -> ZonedDateTime:
|
|
|
104
117
|
return from_timestamp(commit.committed_date, time_zone=LOCAL_TIME_ZONE_NAME)
|
|
105
118
|
|
|
106
119
|
|
|
107
|
-
def _tag_commit(commit: Commit, repo: Repo,
|
|
120
|
+
def _tag_commit(commit: Commit, repo: Repo, /, *, mode: Mode = DEFAULT_MODE) -> None:
|
|
108
121
|
sha = commit.hexsha[:7]
|
|
109
122
|
date = _get_date_time(commit)
|
|
123
|
+
path = get_toml_path(mode)
|
|
110
124
|
try:
|
|
111
|
-
joined = commit.tree.join(
|
|
125
|
+
joined = commit.tree.join(str(path))
|
|
112
126
|
except KeyError:
|
|
113
|
-
logger.exception(f"`
|
|
127
|
+
logger.exception(f"`{str(path)!r}` not found; failed to tag {sha!r} ({date})")
|
|
114
128
|
return
|
|
115
129
|
text = joined.data_stream.read()
|
|
116
|
-
version = get_version(text
|
|
130
|
+
version = get_version(text)
|
|
117
131
|
try:
|
|
118
132
|
tag = repo.create_tag(str(version), ref=sha)
|
|
119
133
|
except GitCommandError as error:
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import assert_never
|
|
5
|
-
|
|
6
|
-
from loguru import logger
|
|
7
|
-
from tomlkit import TOMLDocument, parse
|
|
8
|
-
from tomlkit.items import Table
|
|
9
|
-
from utilities.pathlib import get_repo_root
|
|
10
|
-
from utilities.version import Version, parse_version
|
|
11
|
-
|
|
12
|
-
PYPROJECT_TOML = get_repo_root().joinpath("pyproject.toml")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def get_version(
|
|
16
|
-
path_or_text: Path | str | bytes | TOMLDocument, /, *, desc: str = ""
|
|
17
|
-
) -> Version:
|
|
18
|
-
"""Parse the version from a block of text."""
|
|
19
|
-
match path_or_text:
|
|
20
|
-
case Path() as path:
|
|
21
|
-
return get_version(
|
|
22
|
-
path.read_text(), desc=f" from {str(path)!r}" if desc == "" else desc
|
|
23
|
-
)
|
|
24
|
-
case str() | bytes() as text:
|
|
25
|
-
return get_version(parse(text), desc=desc)
|
|
26
|
-
case TOMLDocument() as doc:
|
|
27
|
-
try:
|
|
28
|
-
tool = doc["tool"]
|
|
29
|
-
except KeyError:
|
|
30
|
-
logger.exception(
|
|
31
|
-
f"Failed to get version{desc}; key 'tool' does not exist"
|
|
32
|
-
)
|
|
33
|
-
raise
|
|
34
|
-
if not isinstance(tool, Table):
|
|
35
|
-
logger.exception(f"Failed to get version{desc}; `tool` is not a Table")
|
|
36
|
-
raise TypeError
|
|
37
|
-
try:
|
|
38
|
-
bumpversion = tool["bumpversion"]
|
|
39
|
-
except KeyError:
|
|
40
|
-
logger.exception(
|
|
41
|
-
f"Failed to get version{desc}; key 'bumpversion' does not exist"
|
|
42
|
-
)
|
|
43
|
-
raise
|
|
44
|
-
if not isinstance(bumpversion, Table):
|
|
45
|
-
logger.exception(
|
|
46
|
-
f"Failed to get version{desc}; `bumpversion` is not a Table"
|
|
47
|
-
)
|
|
48
|
-
raise TypeError
|
|
49
|
-
try:
|
|
50
|
-
version = bumpversion["current_version"]
|
|
51
|
-
except KeyError:
|
|
52
|
-
logger.exception(
|
|
53
|
-
f"Failed to get version{desc}; key 'current_version' does not exist"
|
|
54
|
-
)
|
|
55
|
-
raise
|
|
56
|
-
if not isinstance(version, str):
|
|
57
|
-
logger.exception(
|
|
58
|
-
f"Failed to get version{desc}; `version` is not a string"
|
|
59
|
-
)
|
|
60
|
-
raise TypeError
|
|
61
|
-
return parse_version(version)
|
|
62
|
-
case never: # pyright: ignore[reportUnnecessaryComparison]
|
|
63
|
-
assert_never(never)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
__all__ = ["PYPROJECT_TOML", "get_version"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/format_requirements/in.toml
RENAMED
|
File without changes
|
{dycw_pre_commit_hooks-0.12.1 → dycw_pre_commit_hooks-0.12.3}/src/tests/format_requirements/out.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|