Skip to content

Refactoring #56

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 56 additions & 10 deletions cppython/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import logging
from importlib import metadata
from pathlib import Path
from typing import Any, Type, TypeVar

from cppython_core.core import cppython_logger
from cppython_core.schema import (
PEP621,
CPPythonData,
Expand All @@ -18,10 +18,11 @@
PyProject,
ToolData,
)
from cppython_core.utility import cppython_logger
from pydantic import create_model

from cppython.schema import API, ProjectConfiguration
from cppython.utility import write_presets
from cppython.schema import API, CMakePresets, ConfigurePreset, ProjectConfiguration
from cppython.utility import write_model_json


class ProjectBuilder:
Expand Down Expand Up @@ -110,6 +111,49 @@ def generate_modified(self, original: CPPythonDataT) -> CPPythonDataT:

return modified

def write_presets(self, tool_path: Path, generator_output: list[tuple[str, Path]]) -> None:
"""
Write the cppython presets
"""

def write_generator_presets(tool_path: Path, generator_name: str, toolchain_path: Path) -> Path:
"""
Write a generator preset.
@returns - The written json file
"""
generator_tool_path = tool_path / generator_name
generator_tool_path.mkdir(parents=True, exist_ok=True)

configure_preset = ConfigurePreset(name=generator_name, hidden=True, toolchainFile=str(toolchain_path))
presets = CMakePresets(configurePresets=[configure_preset])

json_path = generator_tool_path / f"{generator_name}.json"

write_model_json(json_path, presets)

return json_path

names = []
includes = []

tool_path = tool_path / "cppython"

for generator_name, toolchain in generator_output:

preset_file = write_generator_presets(tool_path, generator_name, toolchain)

relative_file = preset_file.relative_to(tool_path)

names.append(generator_name)
includes.append(str(relative_file))

configure_preset = ConfigurePreset(name="cppython", hidden=True, inherits=names)
presets = CMakePresets(configurePresets=[configure_preset], include=includes)

json_path = tool_path / "cppython.json"

write_model_json(json_path, presets)


class Project(API):
"""
Expand All @@ -132,8 +176,8 @@ def __init__(

cppython_logger.info("Initializing project")

builder = ProjectBuilder(self.configuration)
plugins = builder.gather_plugins(Generator)
self._builder = ProjectBuilder(self.configuration)
plugins = self._builder.gather_plugins(Generator)

if not plugins:
cppython_logger.error("No generator plugin was found")
Expand All @@ -142,7 +186,7 @@ def __init__(
for plugin in plugins:
cppython_logger.warning(f"Generator plugin found: {plugin.name()}")

extended_pyproject_type = builder.generate_model(plugins)
extended_pyproject_type = self._builder.generate_model(plugins)
pyproject = extended_pyproject_type(**pyproject_data)

if pyproject is None:
Expand All @@ -161,12 +205,14 @@ def __init__(

self._project = pyproject.project

self._modified_cppython_data = builder.generate_modified(pyproject.tool.cppython)
self._modified_cppython_data = self._builder.generate_modified(pyproject.tool.cppython)

self._interface = interface

generator_configuration = GeneratorConfiguration()
self._generators = builder.create_generators(plugins, generator_configuration, self.project, self.cppython)
self._generators = self._builder.create_generators(
plugins, generator_configuration, self.project, self.cppython
)

cppython_logger.info("Initialized project successfully")

Expand Down Expand Up @@ -251,7 +297,7 @@ def install(self) -> None:
cppython_logger.error(f"Generator {generator.name()} failed to install")
raise exception

write_presets(tool_path, generator_output)
self._builder.write_presets(tool_path, generator_output)

def update(self) -> None:
"""
Expand Down Expand Up @@ -279,4 +325,4 @@ def update(self) -> None:
cppython_logger.error(f"Generator {generator.name()} failed to update")
raise exception

write_presets(tool_path, generator_output)
self._builder.write_presets(tool_path, generator_output)
58 changes: 9 additions & 49 deletions cppython/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,25 @@

import json
from pathlib import Path
from typing import Type

from cppython.schema import CMakePresets, ConfigurePreset
from cppython_core.schema import ModelT
from pydantic import BaseModel


def read_preset(name: str, path: Path) -> CMakePresets:
def read_model_json(path: Path, model: Type[ModelT]) -> ModelT:
"""
Reading routing
Reading routine
"""

preset_path = path / f"{name}.json"
return CMakePresets.parse_file(path=preset_path)
return model.parse_file(path=path)


def write_preset(name: str, path: Path, presets: CMakePresets) -> Path:
def write_model_json(path: Path, model: BaseModel) -> None:
"""
Writing routine
"""
file = path / f"{name}.json"

serialized = json.loads(presets.json(exclude_none=True))
with open(file, "w", encoding="utf8") as json_file:
serialized = json.loads(model.json(exclude_none=True))
with open(path, "w", encoding="utf8") as json_file:
json.dump(serialized, json_file, ensure_ascii=False, indent=2)

return file


def write_presets(tool_path: Path, generator_output: list[tuple[str, Path]]) -> None:
"""
Write the cppython presets
"""

def write_generator_presets(tool_path: Path, generator_name: str, toolchain_path: Path) -> Path:
"""
Write a generator preset.
@returns - The written json file
"""
generator_tool_path = tool_path / generator_name
generator_tool_path.mkdir(parents=True, exist_ok=True)

configure_preset = ConfigurePreset(name=generator_name, hidden=True, toolchainFile=str(toolchain_path))
presets = CMakePresets(configurePresets=[configure_preset])

return write_preset(generator_name, generator_tool_path, presets)

names = []
includes = []

tool_path = tool_path / "cppython"

for generator_name, toolchain in generator_output:

preset_file = write_generator_presets(tool_path, generator_name, toolchain)

relative_file = preset_file.relative_to(tool_path)

names.append(generator_name)
includes.append(str(relative_file))

configure_preset = ConfigurePreset(name="cppython", hidden=True, inherits=names)
presets = CMakePresets(configurePresets=[configure_preset], include=includes)

write_preset("cppython", tool_path, presets)
28 changes: 15 additions & 13 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions tests/unit/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,33 @@ def test_generator_creation(self, mocker: MockerFixture):
)

assert len(generators) == 1

def test_presets(self, tmpdir):
"""
TODO
"""

configuration = ProjectConfiguration(root_path=Path())
builder = ProjectBuilder(configuration)

temporary_directory = Path(tmpdir)

input_toolchain = temporary_directory / "input.cmake"

with open(input_toolchain, "w", encoding="utf8") as file:
file.write("")

generator_output = [("test", input_toolchain)]
builder.write_presets(temporary_directory, generator_output)

cppython_tool = temporary_directory / "cppython"
assert cppython_tool.exists()

cppython_file = cppython_tool / "cppython.json"
assert cppython_file.exists()

test_tool = cppython_tool / "test"
assert test_tool.exists()

test_file = test_tool / "test.json"
assert test_file.exists()
45 changes: 15 additions & 30 deletions tests/unit/test_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,36 @@
"""
from pathlib import Path

from cppython.schema import CMakePresets
from cppython.utility import read_preset, write_preset, write_presets
from pydantic.main import BaseModel

from cppython.utility import read_model_json, write_model_json


class TestBuilder:
"""
TODO
"""

def test_preset_read_write(self, tmpdir):
def test_model_read_write(self, tmpdir):
"""
TODO
"""

temporary_directory = Path(tmpdir)

presets = CMakePresets()
write_preset("test", temporary_directory, presets)
output = read_preset("test", temporary_directory)
class TestModel(BaseModel):
"""
TODO
"""

assert presets == output
test_path: Path
test_int: int

def test_presets(self, tmpdir):
"""
TODO
"""
test_model = TestModel(test_path=Path(), test_int=3)

temporary_directory = Path(tmpdir)

input_toolchain = temporary_directory / "input.cmake"

with open(input_toolchain, "w", encoding="utf8") as file:
file.write("")

generator_output = [("test", input_toolchain)]
write_presets(temporary_directory, generator_output)

cppython_tool = temporary_directory / "cppython"
assert cppython_tool.exists()

cppython_file = cppython_tool / "cppython.json"
assert cppython_file.exists()
json_path = temporary_directory / "test.json"

test_tool = cppython_tool / "test"
assert test_tool.exists()
write_model_json(json_path, test_model)
output = read_model_json(json_path, TestModel)

test_file = test_tool / "test.json"
assert test_file.exists()
assert test_model == output