Skip to content

Commit 4546d54

Browse files
authored
Implement VCS Tag Extraction: Git (#68)
1 parent 12e9acd commit 4546d54

File tree

12 files changed

+189
-29
lines changed

12 files changed

+189
-29
lines changed

cppython/console/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+


cppython/console.py renamed to cppython/console/interface.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import tomlkit
1010
from cppython_core.schema import GeneratorDataT, Interface, InterfaceConfiguration
1111

12+
from cppython.console.vcs.git import Git
1213
from cppython.project import Project, ProjectConfiguration
1314

1415

@@ -54,7 +55,11 @@ def __init__(self):
5455

5556
configuration = InterfaceConfiguration()
5657
self.interface = ConsoleInterface(configuration)
57-
self.configuration = ProjectConfiguration(root_path=path)
58+
59+
# TODO: Don't assume git SCM. Implement importing and scm selection
60+
61+
version = Git().extract_version(path)
62+
self.configuration = ProjectConfiguration(root_path=path, version=version.base_version)
5863

5964
def create_project(self) -> Project:
6065
"""

cppython/console/vcs/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+


cppython/console/vcs/base.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
TODO
3+
"""
4+
5+
6+
from abc import ABC, abstractmethod
7+
from pathlib import Path
8+
9+
from packaging.version import Version
10+
11+
12+
class VCS(ABC):
13+
"""
14+
Base class for version control systems
15+
"""
16+
17+
subclasses = []
18+
19+
def __init_subclass__(cls, **kwargs):
20+
super().__init_subclass__(**kwargs)
21+
cls.subclasses.append(cls)
22+
23+
@abstractmethod
24+
def is_repository(self, path: Path) -> bool:
25+
"""
26+
TODO
27+
"""
28+
raise NotImplementedError()
29+
30+
@abstractmethod
31+
def extract_version(self, path: Path) -> Version:
32+
"""
33+
TODO
34+
"""
35+
raise NotImplementedError()

cppython/console/vcs/git.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
TODO
3+
"""
4+
5+
from pathlib import Path
6+
7+
from dulwich.porcelain import tag_list
8+
from dulwich.repo import Repo
9+
from packaging.version import Version
10+
11+
from cppython.console.vcs.base import VCS
12+
13+
14+
class Git(VCS):
15+
"""
16+
Git implementation hooks
17+
"""
18+
19+
def is_repository(self, path: Path) -> bool:
20+
"""
21+
TODO
22+
"""
23+
24+
try:
25+
Repo(str(path))
26+
return True
27+
28+
except Exception:
29+
return False
30+
31+
def extract_version(self, path: Path) -> Version:
32+
"""
33+
TODO
34+
"""
35+
36+
repo = Repo(str(path))
37+
tags = tag_list(repo)
38+
39+
try:
40+
tag = tags[-1].decode("utf-8")
41+
except Exception:
42+
tag = "v0.1.0"
43+
return Version(tag)

cppython/schema.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -107,28 +107,21 @@ def validate_path(cls, values):
107107
return None
108108

109109

110-
@dataclass
111-
class ProjectConfiguration:
110+
class ProjectConfiguration(BaseModel):
112111
"""
113112
TODO
114113
"""
115114

116115
root_path: Path # The path where the pyproject.toml lives
117-
_verbosity: int = 0
116+
version: str # The version number a 'dynamic' project version will resolve to
117+
verbosity: int = 0
118118

119-
@property
120-
def verbosity(self) -> int:
119+
@validator("verbosity")
120+
def min_max(cls, value):
121121
"""
122122
TODO
123123
"""
124-
return self._verbosity
125-
126-
@verbosity.setter
127-
def verbosity(self, value: int) -> None:
128-
"""
129-
TODO
130-
"""
131-
self._verbosity = min(max(value, 0), 2)
124+
return min(max(value, 0), 2)
132125

133126

134127
class API:

pdm.lock

Lines changed: 54 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ dynamic = ["version"]
1414
requires-python = ">=3.10"
1515

1616
dependencies = [
17-
"click>=8.1.3",
18-
"tomlkit>=0.10.2",
19-
"cppython-core>=0.3.3.dev0",
20-
"pydantic>=1.9.0",
17+
"click>=8.1.3",
18+
"tomlkit>=0.10.2",
19+
"cppython-core>=0.3.3.dev0",
20+
"pydantic>=1.9.0",
21+
"dulwich>=0.20.42",
22+
"packaging>=21.3",
2123
]
2224

2325
[project.license-files]
@@ -44,7 +46,7 @@ test = [
4446
]
4547

4648
[project.scripts]
47-
cppython = "cppython.console:cli"
49+
cppython = "cppython.console.interface:cli"
4850

4951
[tool.pytest.ini_options]
5052
testpaths = [

tests/integration/test_interface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from cppython_core.schema import InterfaceConfiguration
77
from pytest_cppython.plugin import InterfaceIntegrationTests
88

9-
from cppython.console import ConsoleInterface
9+
from cppython.console.interface import ConsoleInterface
1010

1111

1212
class TestCLIInterface(InterfaceIntegrationTests):

tests/unit/test_interface.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from pytest_cppython.plugin import InterfaceUnitTests
1616
from pytest_mock.plugin import MockerFixture
1717

18-
from cppython.console import Config, ConsoleInterface, cli
18+
from cppython.console.interface import Config, ConsoleInterface, cli
1919
from cppython.schema import API
2020

2121
default_pep621 = PEP621(name="test_name", version="1.0")
@@ -56,7 +56,7 @@ def test_command(self, command: str, mocker: MockerFixture):
5656
mocker.patch("cppython.project.Project.__init__", return_value=None)
5757

5858
# Patch the reading of data
59-
mocker.patch("cppython.console._create_pyproject", return_value=default_pyproject)
59+
mocker.patch("cppython.console.interface._create_pyproject", return_value=default_pyproject)
6060

6161
config = Config()
6262

tests/unit/test_project.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def test_construction(self, mocker: MockerFixture):
4444
"""
4545

4646
interface_mock = mocker.MagicMock()
47-
configuration = ProjectConfiguration(root_path=Path())
47+
configuration = ProjectConfiguration(root_path=Path(), version="1.0.0")
4848
Project(configuration, interface_mock, default_pyproject.dict(by_alias=True))
4949

5050

@@ -58,7 +58,7 @@ def test_plugin_gather(self):
5858
TODO
5959
"""
6060

61-
configuration = ProjectConfiguration(root_path=Path())
61+
configuration = ProjectConfiguration(root_path=Path(), version="1.0.0")
6262
builder = ProjectBuilder(configuration)
6363
plugins = builder.gather_plugins(Generator)
6464

@@ -69,7 +69,7 @@ def test_generator_data_construction(self, mocker: MockerFixture):
6969
TODO
7070
"""
7171

72-
configuration = ProjectConfiguration(root_path=Path())
72+
configuration = ProjectConfiguration(root_path=Path(), version="1.0.0")
7373
builder = ProjectBuilder(configuration)
7474
model_type = builder.generate_model([])
7575

@@ -97,7 +97,7 @@ def test_generator_creation(self, mocker: MockerFixture):
9797
TODO
9898
"""
9999

100-
configuration = ProjectConfiguration(root_path=Path())
100+
configuration = ProjectConfiguration(root_path=Path(), version="1.0.0")
101101
builder = ProjectBuilder(configuration)
102102

103103
generator_configuration = GeneratorConfiguration()
@@ -118,7 +118,7 @@ def test_presets(self, tmpdir):
118118
"""
119119

120120
temporary_directory = Path(tmpdir)
121-
configuration = ProjectConfiguration(root_path=temporary_directory)
121+
configuration = ProjectConfiguration(root_path=temporary_directory, version="1.0.0")
122122
builder = ProjectBuilder(configuration)
123123

124124
input_toolchain = temporary_directory / "input.cmake"
@@ -147,7 +147,7 @@ def test_root_unmodified(self, tmpdir):
147147
"""
148148

149149
temporary_directory = Path(tmpdir)
150-
configuration = ProjectConfiguration(root_path=temporary_directory)
150+
configuration = ProjectConfiguration(root_path=temporary_directory, version="1.0.0")
151151
builder = ProjectBuilder(configuration)
152152

153153
# TODO: Translate into reuseable testing data

tests/unit/test_vcs.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
TODO
3+
"""
4+
5+
6+
from pathlib import Path
7+
8+
from cppython.console.vcs.git import Git
9+
10+
11+
class TestGit:
12+
"""
13+
TODO
14+
"""
15+
16+
def test_version(self):
17+
"""
18+
TODO
19+
"""
20+
21+
directory = Path()
22+
23+
git = Git()
24+
25+
result = git.extract_version(directory)
26+
27+
assert result != ""

0 commit comments

Comments
 (0)