From 51b136e3f489273e5b155c05c2418c4594c60ac7 Mon Sep 17 00:00:00 2001 From: Asher Norland Date: Sat, 28 May 2022 10:13:54 -0400 Subject: [PATCH 1/4] Fix Tests --- cppython/console.py | 4 +++- cppython/schema.py | 1 + tests/unit/test_project.py | 12 ++++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cppython/console.py b/cppython/console.py index 434e912..e81b48d 100644 --- a/cppython/console.py +++ b/cppython/console.py @@ -54,7 +54,9 @@ def __init__(self): configuration = InterfaceConfiguration() self.interface = ConsoleInterface(configuration) - self.configuration = ProjectConfiguration(root_path=path) + + # TODO: Fill this with a VCS extracted value + self.configuration = ProjectConfiguration(root_path=path, version="1.0.0") def create_project(self) -> Project: """ diff --git a/cppython/schema.py b/cppython/schema.py index 62230e5..5c04f3d 100644 --- a/cppython/schema.py +++ b/cppython/schema.py @@ -114,6 +114,7 @@ class ProjectConfiguration: """ root_path: Path # The path where the pyproject.toml lives + version: str # The version number a 'dynamic' project version will resolve to _verbosity: int = 0 @property diff --git a/tests/unit/test_project.py b/tests/unit/test_project.py index 6ac86f6..6b2fd50 100644 --- a/tests/unit/test_project.py +++ b/tests/unit/test_project.py @@ -44,7 +44,7 @@ def test_construction(self, mocker: MockerFixture): """ interface_mock = mocker.MagicMock() - configuration = ProjectConfiguration(root_path=Path()) + configuration = ProjectConfiguration(root_path=Path(), version="1.0.0") Project(configuration, interface_mock, default_pyproject.dict(by_alias=True)) @@ -58,7 +58,7 @@ def test_plugin_gather(self): TODO """ - configuration = ProjectConfiguration(root_path=Path()) + configuration = ProjectConfiguration(root_path=Path(), version="1.0.0") builder = ProjectBuilder(configuration) plugins = builder.gather_plugins(Generator) @@ -69,7 +69,7 @@ def test_generator_data_construction(self, mocker: MockerFixture): TODO """ - configuration = ProjectConfiguration(root_path=Path()) + configuration = ProjectConfiguration(root_path=Path(), version="1.0.0") builder = ProjectBuilder(configuration) model_type = builder.generate_model([]) @@ -97,7 +97,7 @@ def test_generator_creation(self, mocker: MockerFixture): TODO """ - configuration = ProjectConfiguration(root_path=Path()) + configuration = ProjectConfiguration(root_path=Path(), version="1.0.0") builder = ProjectBuilder(configuration) generator_configuration = GeneratorConfiguration() @@ -118,7 +118,7 @@ def test_presets(self, tmpdir): """ temporary_directory = Path(tmpdir) - configuration = ProjectConfiguration(root_path=temporary_directory) + configuration = ProjectConfiguration(root_path=temporary_directory, version="1.0.0") builder = ProjectBuilder(configuration) input_toolchain = temporary_directory / "input.cmake" @@ -147,7 +147,7 @@ def test_root_unmodified(self, tmpdir): """ temporary_directory = Path(tmpdir) - configuration = ProjectConfiguration(root_path=temporary_directory) + configuration = ProjectConfiguration(root_path=temporary_directory, version="1.0.0") builder = ProjectBuilder(configuration) # TODO: Translate into reuseable testing data From dd310fa7b035fccf12f57265ce4bbe0e61541ca9 Mon Sep 17 00:00:00 2001 From: Asher Norland Date: Sat, 28 May 2022 10:19:07 -0400 Subject: [PATCH 2/4] Convert Dataclass to Model --- cppython/schema.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/cppython/schema.py b/cppython/schema.py index 5c04f3d..8e5c954 100644 --- a/cppython/schema.py +++ b/cppython/schema.py @@ -107,29 +107,21 @@ def validate_path(cls, values): return None -@dataclass -class ProjectConfiguration: +class ProjectConfiguration(BaseModel): """ TODO """ root_path: Path # The path where the pyproject.toml lives version: str # The version number a 'dynamic' project version will resolve to - _verbosity: int = 0 + verbosity: int = 0 - @property - def verbosity(self) -> int: + @validator("verbosity") + def min_max(cls, value): """ TODO """ - return self._verbosity - - @verbosity.setter - def verbosity(self, value: int) -> None: - """ - TODO - """ - self._verbosity = min(max(value, 0), 2) + return min(max(value, 0), 2) class API: From a37aa56f0c321e1e7278d54df11279c4a3ae364c Mon Sep 17 00:00:00 2001 From: Asher Norland Date: Sat, 28 May 2022 12:08:31 -0400 Subject: [PATCH 3/4] Move Console to SubPackage --- cppython/{console.py => console/interface.py} | 0 pyproject.toml | 2 +- tests/integration/test_interface.py | 2 +- tests/unit/test_interface.py | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) rename cppython/{console.py => console/interface.py} (100%) diff --git a/cppython/console.py b/cppython/console/interface.py similarity index 100% rename from cppython/console.py rename to cppython/console/interface.py diff --git a/pyproject.toml b/pyproject.toml index 4ba051c..6583a46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ test = [ ] [project.scripts] -cppython = "cppython.console:cli" +cppython = "cppython.console.interface:cli" [tool.pytest.ini_options] testpaths = [ diff --git a/tests/integration/test_interface.py b/tests/integration/test_interface.py index fe4725d..770caa5 100644 --- a/tests/integration/test_interface.py +++ b/tests/integration/test_interface.py @@ -6,7 +6,7 @@ from cppython_core.schema import InterfaceConfiguration from pytest_cppython.plugin import InterfaceIntegrationTests -from cppython.console import ConsoleInterface +from cppython.console.interface import ConsoleInterface class TestCLIInterface(InterfaceIntegrationTests): diff --git a/tests/unit/test_interface.py b/tests/unit/test_interface.py index 89ff164..e0bb294 100644 --- a/tests/unit/test_interface.py +++ b/tests/unit/test_interface.py @@ -15,7 +15,7 @@ from pytest_cppython.plugin import InterfaceUnitTests from pytest_mock.plugin import MockerFixture -from cppython.console import Config, ConsoleInterface, cli +from cppython.console.interface import Config, ConsoleInterface, cli from cppython.schema import API default_pep621 = PEP621(name="test_name", version="1.0") @@ -56,7 +56,7 @@ def test_command(self, command: str, mocker: MockerFixture): mocker.patch("cppython.project.Project.__init__", return_value=None) # Patch the reading of data - mocker.patch("cppython.console._create_pyproject", return_value=default_pyproject) + mocker.patch("cppython.console.interface._create_pyproject", return_value=default_pyproject) config = Config() From af52622aa4281a76d63400f81ffa2683ee01b8d2 Mon Sep 17 00:00:00 2001 From: Asher Norland Date: Mon, 30 May 2022 10:27:38 -0400 Subject: [PATCH 4/4] Implement VCS Version Extraction --- cppython/console/__init__.py | 1 + cppython/console/interface.py | 7 ++-- cppython/console/vcs/__init__.py | 1 + cppython/console/vcs/base.py | 35 ++++++++++++++++++++ cppython/console/vcs/git.py | 43 +++++++++++++++++++++++++ pdm.lock | 55 +++++++++++++++++++++++++++++++- pyproject.toml | 10 +++--- tests/unit/test_vcs.py | 27 ++++++++++++++++ 8 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 cppython/console/__init__.py create mode 100644 cppython/console/vcs/__init__.py create mode 100644 cppython/console/vcs/base.py create mode 100644 cppython/console/vcs/git.py create mode 100644 tests/unit/test_vcs.py diff --git a/cppython/console/__init__.py b/cppython/console/__init__.py new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/cppython/console/__init__.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cppython/console/interface.py b/cppython/console/interface.py index e81b48d..d8696c7 100644 --- a/cppython/console/interface.py +++ b/cppython/console/interface.py @@ -9,6 +9,7 @@ import tomlkit from cppython_core.schema import GeneratorDataT, Interface, InterfaceConfiguration +from cppython.console.vcs.git import Git from cppython.project import Project, ProjectConfiguration @@ -55,8 +56,10 @@ def __init__(self): configuration = InterfaceConfiguration() self.interface = ConsoleInterface(configuration) - # TODO: Fill this with a VCS extracted value - self.configuration = ProjectConfiguration(root_path=path, version="1.0.0") + # TODO: Don't assume git SCM. Implement importing and scm selection + + version = Git().extract_version(path) + self.configuration = ProjectConfiguration(root_path=path, version=version.base_version) def create_project(self) -> Project: """ diff --git a/cppython/console/vcs/__init__.py b/cppython/console/vcs/__init__.py new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/cppython/console/vcs/__init__.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cppython/console/vcs/base.py b/cppython/console/vcs/base.py new file mode 100644 index 0000000..ebdf482 --- /dev/null +++ b/cppython/console/vcs/base.py @@ -0,0 +1,35 @@ +""" +TODO +""" + + +from abc import ABC, abstractmethod +from pathlib import Path + +from packaging.version import Version + + +class VCS(ABC): + """ + Base class for version control systems + """ + + subclasses = [] + + def __init_subclass__(cls, **kwargs): + super().__init_subclass__(**kwargs) + cls.subclasses.append(cls) + + @abstractmethod + def is_repository(self, path: Path) -> bool: + """ + TODO + """ + raise NotImplementedError() + + @abstractmethod + def extract_version(self, path: Path) -> Version: + """ + TODO + """ + raise NotImplementedError() diff --git a/cppython/console/vcs/git.py b/cppython/console/vcs/git.py new file mode 100644 index 0000000..fa11334 --- /dev/null +++ b/cppython/console/vcs/git.py @@ -0,0 +1,43 @@ +""" +TODO +""" + +from pathlib import Path + +from dulwich.porcelain import tag_list +from dulwich.repo import Repo +from packaging.version import Version + +from cppython.console.vcs.base import VCS + + +class Git(VCS): + """ + Git implementation hooks + """ + + def is_repository(self, path: Path) -> bool: + """ + TODO + """ + + try: + Repo(str(path)) + return True + + except Exception: + return False + + def extract_version(self, path: Path) -> Version: + """ + TODO + """ + + repo = Repo(str(path)) + tags = tag_list(repo) + + try: + tag = tags[-1].decode("utf-8") + except Exception: + tag = "v0.1.0" + return Version(tag) diff --git a/pdm.lock b/pdm.lock index 0dcfc69..492279f 100644 --- a/pdm.lock +++ b/pdm.lock @@ -34,6 +34,12 @@ dependencies = [ "tomli>=1.1.0; python_version < \"3.11\"", ] +[[package]] +name = "certifi" +version = "2022.5.18.1" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." + [[package]] name = "click" version = "8.1.3" @@ -82,6 +88,16 @@ version = "0.3.5.1" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" summary = "serialize all of python" +[[package]] +name = "dulwich" +version = "0.20.42" +requires_python = ">=3.6" +summary = "Python Git Library" +dependencies = [ + "certifi", + "urllib3>=1.24.1", +] + [[package]] name = "iniconfig" version = "1.1.1" @@ -241,6 +257,12 @@ version = "4.2.0" requires_python = ">=3.7" summary = "Backported and Experimental Type Hints for Python 3.7+" +[[package]] +name = "urllib3" +version = "1.26.9" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +summary = "HTTP library with thread-safe connection pooling, file post, and more." + [[package]] name = "wrapt" version = "1.14.1" @@ -249,7 +271,7 @@ summary = "Module for decorators, wrappers and monkey patching." [metadata] lock_version = "3.1" -content_hash = "sha256:9842348d0ddc71440b500499ed71e9b60aea9edcf388f5d8ef170c125c802e99" +content_hash = "sha256:0faf7f9fc3975f7bfc743c5e74d8f396304b96d97ac53337073dc076d98d4432" [metadata.files] "astroid 2.11.5" = [ @@ -289,6 +311,10 @@ content_hash = "sha256:9842348d0ddc71440b500499ed71e9b60aea9edcf388f5d8ef170c125 {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, ] +"certifi 2022.5.18.1" = [ + {file = "certifi-2022.5.18.1-py3-none-any.whl", hash = "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"}, + {file = "certifi-2022.5.18.1.tar.gz", hash = "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7"}, +] "click 8.1.3" = [ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, @@ -348,6 +374,29 @@ content_hash = "sha256:9842348d0ddc71440b500499ed71e9b60aea9edcf388f5d8ef170c125 {file = "dill-0.3.5.1-py2.py3-none-any.whl", hash = "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302"}, {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"}, ] +"dulwich 0.20.42" = [ + {file = "dulwich-0.20.42-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:1e47b2f84d280b9bc0060a19b767402a43efb3a37774d6f613a23e1c1d813e43"}, + {file = "dulwich-0.20.42-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3f67e145762fce0f48703f9e4ce20577e52585a9efe9282a74ed2b5e9059a0f"}, + {file = "dulwich-0.20.42-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f4a92eb77377886fdf5c7043842d83372c37175e0af3fcfbb226414ce30a1f88"}, + {file = "dulwich-0.20.42-cp310-cp310-win_amd64.whl", hash = "sha256:546c3cfd8df20cd145cb8751e3abd52d84911422014a93b95bb324274f5b0756"}, + {file = "dulwich-0.20.42-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:bf9944b8af7d8655056af6abafa72f09796aadef40b56db395beeaac93d82e6c"}, + {file = "dulwich-0.20.42-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6adb07cb06922b4814ee1080f39e36eb15e08fff5ed51b0f78f162142b2b2e4"}, + {file = "dulwich-0.20.42-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ae8a475c0a7d981255695e9f5a15c7de5f45a2cad56633171cc771820850a6b2"}, + {file = "dulwich-0.20.42-cp36-cp36m-win_amd64.whl", hash = "sha256:e56e3eeb091f9ed9a7156c0bccc3dcf13d44aada86303232f68ea17ecd6aa391"}, + {file = "dulwich-0.20.42-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:5ce7a97ea2c25a71c18749de449f81a9728e77e33a6f23d891785c00d05bca2e"}, + {file = "dulwich-0.20.42-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c488427dcbc0861f5bf16829298f061332667af6efd65fab5d8f22ab896e71d"}, + {file = "dulwich-0.20.42-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9f8c224dece64f9750bedfdeaf89ed94d9ae2f38f9600812615bd5dc4ea84f53"}, + {file = "dulwich-0.20.42-cp37-cp37m-win_amd64.whl", hash = "sha256:6df2d3fa24c69cd2c6daa2ba05c559e3876819d5b1abfc84b849f34686a56fd9"}, + {file = "dulwich-0.20.42-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:2145f1299b221d60379517983f430d68f43243df1bde86b2c793ac752833bf3c"}, + {file = "dulwich-0.20.42-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91299d239afce5246eba38fe0667d7b9dae0d058360fbe253c6f388650dc8b01"}, + {file = "dulwich-0.20.42-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1cdd1ad1bd067b1bbb726c5d0865f5db2cf2824b9c77737e028cd157ceec1efb"}, + {file = "dulwich-0.20.42-cp38-cp38-win_amd64.whl", hash = "sha256:76e2da298a7bfd59a522750903656c7a2202a47a107ae711e0741b08729c51ee"}, + {file = "dulwich-0.20.42-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:67a626230665bc95f0aa955530fac7b8802c62d7a254acabc2764ac1985afcba"}, + {file = "dulwich-0.20.42-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f69595e14061752cff04ac0cbada210d550645e189071bc3e24c9b1043d3064"}, + {file = "dulwich-0.20.42-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3ac93b9df220ee5f99c86538d46c337d82d35caa72d013b95084ca06325e90c9"}, + {file = "dulwich-0.20.42-cp39-cp39-win_amd64.whl", hash = "sha256:23922557bc487597ff1a0efc56e4436e275a82837b55e5f733e3e05c873e92b1"}, + {file = "dulwich-0.20.42.tar.gz", hash = "sha256:72ba3b60ae6a554d1332b3b40a345febe16ec469cf6014bb443b719902e33ef0"}, +] "iniconfig 1.1.1" = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, @@ -500,6 +549,10 @@ content_hash = "sha256:9842348d0ddc71440b500499ed71e9b60aea9edcf388f5d8ef170c125 {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, ] +"urllib3 1.26.9" = [ + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, +] "wrapt 1.14.1" = [ {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, diff --git a/pyproject.toml b/pyproject.toml index 6583a46..c2b55dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,10 +14,12 @@ dynamic = ["version"] requires-python = ">=3.10" dependencies = [ - "click>=8.1.3", - "tomlkit>=0.10.2", - "cppython-core>=0.3.3.dev0", - "pydantic>=1.9.0", + "click>=8.1.3", + "tomlkit>=0.10.2", + "cppython-core>=0.3.3.dev0", + "pydantic>=1.9.0", + "dulwich>=0.20.42", + "packaging>=21.3", ] [project.license-files] diff --git a/tests/unit/test_vcs.py b/tests/unit/test_vcs.py new file mode 100644 index 0000000..6f6d2e6 --- /dev/null +++ b/tests/unit/test_vcs.py @@ -0,0 +1,27 @@ +""" +TODO +""" + + +from pathlib import Path + +from cppython.console.vcs.git import Git + + +class TestGit: + """ + TODO + """ + + def test_version(self): + """ + TODO + """ + + directory = Path() + + git = Git() + + result = git.extract_version(directory) + + assert result != ""