PyVCC 1.2.2__tar.gz → 1.3.1__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.
- {pyvcc-1.2.2 → pyvcc-1.3.1}/PKG-INFO +1 -1
- {pyvcc-1.2.2 → pyvcc-1.3.1}/pyproject.toml +4 -1
- {pyvcc-1.2.2 → pyvcc-1.3.1}/pyvcc/__init__.py +1 -1
- pyvcc-1.3.1/pyvcc/__main__.py +51 -0
- {pyvcc-1.2.2 → pyvcc-1.3.1}/pyvcc/cli.py +5 -4
- {pyvcc-1.2.2 → pyvcc-1.3.1}/pyvcc/semver.py +9 -6
- {pyvcc-1.2.2 → pyvcc-1.3.1}/tests/cli/test_cli.py +11 -11
- {pyvcc-1.2.2 → pyvcc-1.3.1}/tests/semver/test_bump_version.py +34 -0
- pyvcc-1.2.2/pyvcc/__main__.py +0 -27
- {pyvcc-1.2.2 → pyvcc-1.3.1}/LICENSE +0 -0
- {pyvcc-1.2.2 → pyvcc-1.3.1}/README.md +0 -0
- {pyvcc-1.2.2 → pyvcc-1.3.1}/tests/__init__.py +0 -0
- {pyvcc-1.2.2 → pyvcc-1.3.1}/tests/cli/__init__.py +0 -0
- {pyvcc-1.2.2 → pyvcc-1.3.1}/tests/semver/__init__.py +0 -0
- {pyvcc-1.2.2 → pyvcc-1.3.1}/tests/semver/conftest.py +0 -0
- {pyvcc-1.2.2 → pyvcc-1.3.1}/tests/semver/test_breaking_change.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "PyVCC"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.3.1"
|
|
4
4
|
description = "PyVCC python version controller using conventional commits"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -10,6 +10,9 @@ dependencies = [
|
|
|
10
10
|
"typing-extensions>=4.0.0; python_version < '3.11'",
|
|
11
11
|
]
|
|
12
12
|
|
|
13
|
+
[project.scripts]
|
|
14
|
+
pyvcc = "pyvcc.__main__:main"
|
|
15
|
+
|
|
13
16
|
[dependency-groups]
|
|
14
17
|
dev = [
|
|
15
18
|
"coverage[toml]>=7.8.0",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Entry point for running the package as a module.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import structlog
|
|
8
|
+
import sys
|
|
9
|
+
import argparse
|
|
10
|
+
from pyvcc.cli import run
|
|
11
|
+
from pyvcc.cli import validate_args
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
parser = argparse.ArgumentParser(prog="PyVC", description=__doc__)
|
|
16
|
+
parser.add_argument("--root", type=str, default=".", required=False)
|
|
17
|
+
parser.add_argument("--initial-version", type=str, required=False, default="0.1.0")
|
|
18
|
+
parser.add_argument("--initial-commit", type=str, required=False, default="")
|
|
19
|
+
parser.add_argument("--verbose", "-v", action="store_true", required=False)
|
|
20
|
+
parser.add_argument("--silent", "-s", action="store_true", required=False)
|
|
21
|
+
|
|
22
|
+
args = parser.parse_args()
|
|
23
|
+
root = os.getenv(key="PYVC_REPO_ROOT", default=args.root)
|
|
24
|
+
version = os.getenv(key="PYVC_INITIAL_VERSION", default=args.initial_version)
|
|
25
|
+
commit = os.getenv(key="PYVC_INITIAL_COMMIT", default=args.initial_commit)
|
|
26
|
+
if not validate_args(root=root, version=version):
|
|
27
|
+
sys.exit(1)
|
|
28
|
+
|
|
29
|
+
log_level = logging.INFO
|
|
30
|
+
if args.verbose:
|
|
31
|
+
log_level = logging.DEBUG
|
|
32
|
+
if args.silent:
|
|
33
|
+
log_level = logging.CRITICAL
|
|
34
|
+
structlog.configure(
|
|
35
|
+
processors=[
|
|
36
|
+
structlog.dev.set_exc_info,
|
|
37
|
+
structlog.processors.add_log_level,
|
|
38
|
+
structlog.processors.StackInfoRenderer(),
|
|
39
|
+
structlog.dev.ConsoleRenderer(colors=True),
|
|
40
|
+
],
|
|
41
|
+
wrapper_class=structlog.make_filtering_bound_logger(log_level),
|
|
42
|
+
logger_factory=structlog.PrintLoggerFactory(),
|
|
43
|
+
cache_logger_on_first_use=True,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
version = run(root, version, commit)
|
|
47
|
+
sys.stdout.write(version)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
CLI parsing for pyvc command.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from pygit2 import Commit
|
|
6
5
|
import structlog
|
|
6
|
+
|
|
7
7
|
from pathlib import Path, PurePath
|
|
8
|
+
from pygit2 import Commit
|
|
8
9
|
from pygit2.repository import Repository
|
|
9
10
|
from pygit2.enums import SortMode
|
|
10
11
|
|
|
@@ -30,7 +31,7 @@ def validate_args(root: str, version: str) -> bool:
|
|
|
30
31
|
return is_valid
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
def
|
|
34
|
+
def run(root: str, version: str, start_commit_id: str | None = None) -> str:
|
|
34
35
|
repo_path = Path(root) / PurePath(".git")
|
|
35
36
|
semver = SemVer.semver_from_string(version)
|
|
36
37
|
|
|
@@ -48,8 +49,8 @@ def main(root: str, version: str, start_commit_id: str | None = None) -> str:
|
|
|
48
49
|
|
|
49
50
|
for commit in commit_walker:
|
|
50
51
|
message = commit.message
|
|
51
|
-
log.
|
|
52
|
+
log.debug("commit", id=commit.id, short=commit.short_id)
|
|
52
53
|
semver.bump_version(message)
|
|
53
54
|
|
|
54
|
-
log.
|
|
55
|
+
log.debug(f"final version {str(semver)}")
|
|
55
56
|
return str(semver)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import re
|
|
2
2
|
import sys
|
|
3
3
|
import structlog
|
|
4
4
|
|
|
5
|
+
from enum import Enum, auto
|
|
6
|
+
|
|
5
7
|
# Python 3.11+ has Self in typing module
|
|
6
8
|
if sys.version_info >= (3, 11):
|
|
7
9
|
from typing import Self
|
|
@@ -94,14 +96,15 @@ class SemVer:
|
|
|
94
96
|
message (str): commit message content
|
|
95
97
|
"""
|
|
96
98
|
|
|
99
|
+
regex = re.compile(r"[.*]?([a-z]*!?)(\(.*\))?:\s(.*)$")
|
|
97
100
|
bump = BumpEnum.NO_BUMP
|
|
98
101
|
head = message.split("\n")[0]
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
parsed_head = head.split(":")
|
|
103
|
+
parsed_head = regex.search(head)
|
|
102
104
|
|
|
103
|
-
if
|
|
104
|
-
commit_type = parsed_head[0].
|
|
105
|
+
if parsed_head is not None:
|
|
106
|
+
commit_type = parsed_head.groups()[0].upper()
|
|
107
|
+
log.debug("trying bump", type=commit_type, message=head)
|
|
105
108
|
|
|
106
109
|
if cls.is_breaking_change(commit_type, message):
|
|
107
110
|
bump = BumpEnum.MAJOR
|
|
@@ -112,7 +115,7 @@ class SemVer:
|
|
|
112
115
|
else:
|
|
113
116
|
bump = BumpEnum.NO_BUMP
|
|
114
117
|
else:
|
|
115
|
-
log.
|
|
118
|
+
log.error("not in conventional commit spec", message=head)
|
|
116
119
|
|
|
117
120
|
return bump
|
|
118
121
|
|
|
@@ -2,7 +2,7 @@ from pygit2 import Commit
|
|
|
2
2
|
import pytest
|
|
3
3
|
from pygit2.repository import Repository
|
|
4
4
|
|
|
5
|
-
from pyvcc.cli import
|
|
5
|
+
from pyvcc.cli import run, validate_args
|
|
6
6
|
from pyvcc.semver import BumpEnum, SemVer
|
|
7
7
|
|
|
8
8
|
|
|
@@ -13,14 +13,14 @@ class MockCommit:
|
|
|
13
13
|
self.short_id = short_id
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
def
|
|
16
|
+
def test_run_invalid_path():
|
|
17
17
|
with pytest.raises(Exception):
|
|
18
|
-
|
|
18
|
+
run("/(7", "1.0.0")
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def
|
|
21
|
+
def test_run_invalid_semver():
|
|
22
22
|
with pytest.raises(Exception):
|
|
23
|
-
|
|
23
|
+
run(".", "1.0.0.2")
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def test_validate_version():
|
|
@@ -41,7 +41,7 @@ def test_single_commit(monkeypatch):
|
|
|
41
41
|
|
|
42
42
|
monkeypatch.setattr(Repository, "walk", mock_walk)
|
|
43
43
|
|
|
44
|
-
assert
|
|
44
|
+
assert run(".", "1.0.0") == "1.1.0"
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def test_two_commits(monkeypatch):
|
|
@@ -53,7 +53,7 @@ def test_two_commits(monkeypatch):
|
|
|
53
53
|
|
|
54
54
|
monkeypatch.setattr(Repository, "walk", mock_walk)
|
|
55
55
|
|
|
56
|
-
assert
|
|
56
|
+
assert run(".", "1.0.0") == "1.2.0"
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
def test_head_bump_commit():
|
|
@@ -64,10 +64,10 @@ def test_head_bump_commit():
|
|
|
64
64
|
message = commit.message
|
|
65
65
|
match SemVer.bump_type(message):
|
|
66
66
|
case BumpEnum.MAJOR:
|
|
67
|
-
assert
|
|
67
|
+
assert run(".", "1.0.0", str(repo.head.target)) == "2.0.0"
|
|
68
68
|
case BumpEnum.MINOR:
|
|
69
|
-
assert
|
|
69
|
+
assert run(".", "1.0.0", str(repo.head.target)) == "1.1.0"
|
|
70
70
|
case BumpEnum.PATCH:
|
|
71
|
-
assert
|
|
71
|
+
assert run(".", "1.0.0", str(repo.head.target)) == "1.0.1"
|
|
72
72
|
case BumpEnum.NO_BUMP:
|
|
73
|
-
assert
|
|
73
|
+
assert run(".", "1.0.0", str(repo.head.target)) == "1.0.0"
|
|
@@ -51,6 +51,20 @@ def test_no_bump_no_type(no_cc_simple_commit: tuple[str, str]):
|
|
|
51
51
|
assert str(version) == "1.0.0"
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def test_bump_merge():
|
|
55
|
+
version = SemVer(1, 0, 0)
|
|
56
|
+
message = "Merged feat!(xyz): break"
|
|
57
|
+
version.bump_version(message)
|
|
58
|
+
assert str(version) == "2.0.0"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_bump_merge2():
|
|
62
|
+
version = SemVer(1, 0, 0)
|
|
63
|
+
message = "Merged feat(xyz): break"
|
|
64
|
+
version.bump_version(message)
|
|
65
|
+
assert str(version) == "1.1.0"
|
|
66
|
+
|
|
67
|
+
|
|
54
68
|
def test_bump_multiple():
|
|
55
69
|
"""patch -> minor -> major"""
|
|
56
70
|
version = SemVer(0, 1, 0)
|
|
@@ -107,6 +121,26 @@ def test_bump_multiple4():
|
|
|
107
121
|
assert str(version) == "0.2.0"
|
|
108
122
|
|
|
109
123
|
|
|
124
|
+
def test_bump_multiple5():
|
|
125
|
+
"""patch -> patch -> minor"""
|
|
126
|
+
version = SemVer(0, 1, 0)
|
|
127
|
+
|
|
128
|
+
version.bump_version("fix: Fix login bug")
|
|
129
|
+
assert str(version) == "0.1.1"
|
|
130
|
+
|
|
131
|
+
version.bump_version("fix: Fix logout bug")
|
|
132
|
+
assert str(version) == "0.1.2"
|
|
133
|
+
|
|
134
|
+
version.bump_version("Fix logout bug")
|
|
135
|
+
assert str(version) == "0.1.2"
|
|
136
|
+
|
|
137
|
+
version.bump_version("feat(asdf): Add new feature")
|
|
138
|
+
assert str(version) == "0.2.0"
|
|
139
|
+
|
|
140
|
+
version.bump_version("Merge feat!(asdf): break new feature")
|
|
141
|
+
assert str(version) == "1.0.0"
|
|
142
|
+
|
|
143
|
+
|
|
110
144
|
def test_parse_semver_str():
|
|
111
145
|
version = SemVer.semver_from_string("1.1.0")
|
|
112
146
|
assert str(version) == "1.1.0"
|
pyvcc-1.2.2/pyvcc/__main__.py
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Entry point for running the package as a module.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
import sys
|
|
7
|
-
import argparse
|
|
8
|
-
import structlog
|
|
9
|
-
from pyvc.cli import main, validate_args
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
log = structlog.get_logger()
|
|
13
|
-
|
|
14
|
-
if __name__ == "__main__":
|
|
15
|
-
parser = argparse.ArgumentParser(prog="PyVC", description=__doc__)
|
|
16
|
-
parser.add_argument("--root", type=str, default=".", required=False)
|
|
17
|
-
parser.add_argument("--initial-version", type=str, required=False, default="0.1.0")
|
|
18
|
-
parser.add_argument("--initial-commit", type=str, required=False, default="")
|
|
19
|
-
|
|
20
|
-
args = parser.parse_args()
|
|
21
|
-
root = os.getenv(key="PYVC_REPO_ROOT", default=args.root)
|
|
22
|
-
version = os.getenv(key="PYVC_INITIAL_VERSION", default=args.initial_version)
|
|
23
|
-
commit = os.getenv(key="PYVC_INITIAL_COMMIT", default=args.initial_commit)
|
|
24
|
-
if not validate_args(root=root, version=version):
|
|
25
|
-
sys.exit(1)
|
|
26
|
-
|
|
27
|
-
main(root, version, commit)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|