diff --git a/hatch_cpp/plugin.py b/hatch_cpp/plugin.py index 0de620f..6b57f2d 100644 --- a/hatch_cpp/plugin.py +++ b/hatch_cpp/plugin.py @@ -3,11 +3,10 @@ import logging import os import typing as t -from dataclasses import fields from hatchling.builders.hooks.plugin.interface import BuildHookInterface -from .structs import HatchCppBuildConfig, HatchCppBuildPlan, HatchCppLibrary, HatchCppPlatform +from .structs import HatchCppBuildConfig, HatchCppBuildPlan __all__ = ("HatchCppBuildHook",) @@ -30,18 +29,10 @@ def initialize(self, version: str, _: dict[str, t.Any]) -> None: self._logger.info("Skipping the build hook since SKIP_HATCH_CPP was set") return - kwargs = {k.replace("-", "_"): v if not isinstance(v, bool) else str(v) for k, v in self.config.items()} - available_fields = [f.name for f in fields(HatchCppBuildConfig)] - for key in list(kwargs): - if key not in available_fields: - del kwargs[key] - config = HatchCppBuildConfig(**kwargs) + config = HatchCppBuildConfig(**self.config) - library_kwargs = [ - {k.replace("-", "_"): v if not isinstance(v, bool) else str(v) for k, v in library_kwargs.items()} for library_kwargs in config.libraries - ] - libraries = [HatchCppLibrary(**library_kwargs) for library_kwargs in library_kwargs] - platform = HatchCppPlatform.default() + libraries = config.libraries + platform = config.platform if config.toolchain == "raw": build_plan = HatchCppBuildPlan(libraries=libraries, platform=platform) build_plan.generate() @@ -51,39 +42,5 @@ def initialize(self, version: str, _: dict[str, t.Any]) -> None: build_plan.execute() build_plan.cleanup() - # build_kwargs = config.build_kwargs - # if version == "editable": - # build_kwargs = config.editable_build_kwargs or build_kwargs - - # should_skip_build = False - # if not config.build_function: - # log.warning("No build function found") - # should_skip_build = True - - # elif config.skip_if_exists and version == "standard": - # should_skip_build = should_skip(config.skip_if_exists) - # if should_skip_build: - # log.info("Skip-if-exists file(s) found") - - # # Get build function and call it with normalized parameter names. - # if not should_skip_build and config.build_function: - # build_func = get_build_func(config.build_function) - # build_kwargs = normalize_kwargs(build_kwargs) - # log.info("Building with %s", config.build_function) - # log.info("With kwargs: %s", build_kwargs) - # try: - # build_func(self.target_name, version, **build_kwargs) - # except Exception as e: - # if version == "editable" and config.optional_editable_build.lower() == "true": - # warnings.warn(f"Encountered build error:\n{e}", stacklevel=2) - # else: - # raise e - # else: - # log.info("Skipping build") - - # # Ensure targets in distributable dists. - # if version == "standard": - # ensure_targets(config.ensured_targets) - self._logger.info("Finished running hatch-cpp") return diff --git a/hatch_cpp/structs.py b/hatch_cpp/structs.py index cc9c99c..4241a7b 100644 --- a/hatch_cpp/structs.py +++ b/hatch_cpp/structs.py @@ -1,13 +1,12 @@ from __future__ import annotations -from dataclasses import dataclass, field from os import environ, system from pathlib import Path from sys import executable, platform as sys_platform from sysconfig import get_path -from typing import Literal +from typing import List, Literal, Optional -from hatchling.builders.config import BuilderConfig +from pydantic import BaseModel, Field __all__ = ( "HatchCppBuildConfig", @@ -25,42 +24,26 @@ } -@dataclass -class HatchCppBuildConfig(BuilderConfig): - """Build config values for Hatch C++ Builder.""" - - toolchain: str | None = field(default="raw") - libraries: list[dict[str, str]] = field(default_factory=list) - verbose: bool | None = field(default=False) - # build_function: str | None = None - # build_kwargs: t.Mapping[str, str] = field(default_factory=dict) - # editable_build_kwargs: t.Mapping[str, str] = field(default_factory=dict) - # ensured_targets: list[str] = field(default_factory=list) - # skip_if_exists: list[str] = field(default_factory=list) - - -@dataclass -class HatchCppLibrary(object): +class HatchCppLibrary(BaseModel): """A C++ library.""" name: str - sources: list[str] + sources: List[str] - include_dirs: list[str] = field(default_factory=list) - library_dirs: list[str] = field(default_factory=list) - libraries: list[str] = field(default_factory=list) - extra_compile_args: list[str] = field(default_factory=list) - extra_link_args: list[str] = field(default_factory=list) - extra_objects: list[str] = field(default_factory=list) - define_macros: list[str] = field(default_factory=list) - undef_macros: list[str] = field(default_factory=list) + include_dirs: List[str] = Field(default_factory=list, alias="include-dirs") + library_dirs: List[str] = Field(default_factory=list, alias="library-dirs") + libraries: List[str] = Field(default_factory=list) + extra_compile_args: List[str] = Field(default_factory=list, alias="extra-compile-args") + extra_link_args: List[str] = Field(default_factory=list, alias="extra-link-args") + extra_objects: List[str] = Field(default_factory=list, alias="extra-objects") + define_macros: List[str] = Field(default_factory=list, alias="define-macros") + undef_macros: List[str] = Field(default_factory=list, alias="undef-macros") - export_symbols: list[str] = field(default_factory=list) - depends: list[str] = field(default_factory=list) + export_symbols: List[str] = Field(default_factory=list, alias="export-symbols") + depends: List[str] = Field(default_factory=list) -@dataclass -class HatchCppPlatform(object): +class HatchCppPlatform(BaseModel): cc: str cxx: str platform: Platform @@ -133,11 +116,10 @@ def get_link_flags(self, library: HatchCppLibrary) -> str: return flags -@dataclass -class HatchCppBuildPlan(object): - libraries: list[HatchCppLibrary] = field(default_factory=list) - platform: HatchCppPlatform = field(default_factory=HatchCppPlatform.default) - commands: list[str] = field(default_factory=list) +class HatchCppBuildPlan(BaseModel): + libraries: List[HatchCppLibrary] = Field(default_factory=list) + platform: HatchCppPlatform = Field(default_factory=HatchCppPlatform.default) + commands: List[str] = Field(default_factory=list) def generate(self): self.commands = [] @@ -157,3 +139,17 @@ def cleanup(self): temp_obj = Path(f"{library.name}.obj") if temp_obj.exists(): temp_obj.unlink() + + +class HatchCppBuildConfig(BaseModel): + """Build config values for Hatch C++ Builder.""" + + toolchain: Optional[str] = Field(default="raw") + libraries: List[HatchCppLibrary] = Field(default_factory=list) + verbose: Optional[bool] = Field(default=False) + platform: Optional[HatchCppPlatform] = Field(default_factory=HatchCppPlatform.default) + # build_function: str | None = None + # build_kwargs: t.Mapping[str, str] = field(default_factory=dict) + # editable_build_kwargs: t.Mapping[str, str] = field(default_factory=dict) + # ensured_targets: list[str] = field(default_factory=list) + # skip_if_exists: list[str] = field(default_factory=list) diff --git a/pyproject.toml b/pyproject.toml index 451b580..7e45b50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ classifiers = [ dependencies = [ "hatchling>=1.20", + "pydantic", ] [project.optional-dependencies]