diff options
| author | 2024-03-07 16:51:06 +0800 | |
|---|---|---|
| committer | 2024-03-07 16:51:06 +0800 | |
| commit | 1fee431d05143d247245fbac5ea4a877836c18bb (patch) | |
| tree | d8da83bc0e680871abb3a3ffba58131369f92bd6 | |
| parent | 57e639f755aa97d0952e136dc6925fd38962a396 (diff) | |
| download | ipm-1fee431d05143d247245fbac5ea4a877836c18bb.tar.gz ipm-1fee431d05143d247245fbac5ea4a877836c18bb.zip | |
refactor(models): rewrite infini package model
| -rw-r--r-- | src/ipm/models/ipk.py | 153 |
1 files changed, 120 insertions, 33 deletions
diff --git a/src/ipm/models/ipk.py b/src/ipm/models/ipk.py index 62beb96..c8e14de 100644 --- a/src/ipm/models/ipk.py +++ b/src/ipm/models/ipk.py @@ -1,13 +1,14 @@ from pathlib import Path -from typing import Optional, Union +from typing import Any, Optional, Union from tomlkit.toml_document import TOMLDocument -from ipm.models import lock + +from ipm.const import INDEX +from ipm.models.index import Yggdrasil from ipm.typing import List, Dict, Literal, StrPath -from ipm.exceptions import SyntaxError, TomlLoadFailed +from ipm.exceptions import TomlLoadFailed import tomlkit - -# ProjectLock = lock.ProjectLock +import abc class Author: @@ -20,23 +21,76 @@ class Author: class Authors: - authors: list[Author] = [] + authors: List[Author] = [] def __init__(self, authors: List[Dict[Literal["name", "email"], str]]) -> None: for author in authors: self.authors.append(Author(author["name"], author["email"])) @property - def first(self) -> Author | None: + def first(self) -> Optional[Author]: return None if not self.authors else self.authors[0] -class InfiniPackage: - _source_path: Path - - name: str | None - version: str | None - +class Requirement: + name: str + version: str + path: Optional[str] + yggdrasil: Yggdrasil + + def __init__( + self, + name: str, + version: str, + path: Optional[str] = None, + yggdrasil: Optional[Yggdrasil] = None, + ) -> None: + self.name = name + self.version = version + self.path = path + self.yggdrasil = yggdrasil or Yggdrasil(INDEX) + + def is_local(self) -> bool: + return bool(self.path) + + +class Requirements: + requirements: List[Requirement] + + def __init__( + self, + dependencies: Dict[str, Union[Dict, str]], + yggdrasils: Optional[Dict[str, Yggdrasil]] = None, + ) -> None: + path = yggdrasil = version = None + for name, dependency in dependencies.items(): + if isinstance(dependency, str): + self.requirements.append(Requirement(name=name, version=dependency)) + else: + for key, value in dependency.items(): + if key == "index": + yggdrasil = Yggdrasil(key) + elif key == "yggdrasil": + yggdrasil = (yggdrasils or {}).get(value) + if not yggdrasil: + raise ValueError(f"未知的世界树标识符: '{value}'") + elif key == "path": + path = value + elif key == "version": + version = value + else: + raise ValueError(f"未知的依赖项键值: '{key}'") + self.requirements.append( + Requirement( + name=name, + version=version or "*", + path=path, + yggdrasil=yggdrasil, + ) + ) + + +class InfiniPackage(metaclass=abc.ABCMeta): @property def default_name(self) -> str: return f"{self.name}-{self.version}.ipk" @@ -45,17 +99,18 @@ class InfiniPackage: def hash_name(self) -> str: return f"{self.name}-{self.version}.ipk.hash" + @property + @abc.abstractmethod + def name(self) -> str: + raise NotImplementedError -class InfiniProject(InfiniPackage): - # name: str - # version: str - # description: str - # authors: Authors - # license: str + @property + @abc.abstractmethod + def version(self) -> str: + raise NotImplementedError - # requirements: Dict[str, Any] - # dependencies: Dict[str, Any] +class InfiniProject(InfiniPackage): def __init__(self, path: StrPath = ".") -> None: self._source_path = Path(path).resolve() self._toml_path = self._source_path / "infini.toml" @@ -82,35 +137,67 @@ class InfiniProject(InfiniPackage): def dump(self) -> None: return tomlkit.dump(self._data, self._toml_path.open("w", encoding="utf-8")) + def require(self, name: str) -> None: + version = "*" + self._data["requirements"][name] = version # type: ignore + @property def plain_dict(self) -> TOMLDocument: return self._data @property def name(self) -> str: - project = self._data["project"] - if not (name := project.get("name")): # type: ignore - raise ValueError("项目文件不存在`name`属性.") - return name + return self._data["project"]["name"] # type: ignore + @property + def version(self) -> str: + return self._data["project"]["version"] # type: ignore + + @property + def description(self) -> str: + return self._data["project"]["description"] # type: ignore + + @property + def authors(self) -> Authors: + return Authors(self._data["project"]["authors"]) # type: ignore + + @property + def license(self) -> str: + return self._data["project"]["license"] # type: ignore + + @property + def dependencies(self) -> Dict[str, Any]: + return self._data["dependenciess"] # type: ignore + + @property + def requirements(self) -> Requirements: + return Requirements(self._data["requirement"]) # type: ignore + + @property + def yggdrasils(self) -> Yggdrasil: ... -class InfiniFrozenPackage(InfiniPackage): - name: str | None - version: str | None - hash: str - def __init__(self, source_path: Union[str, Path], **kwargs) -> None: +class InfiniFrozenPackage(InfiniPackage): + def __init__(self, source_path: Union[str, Path], name: str, version: str) -> None: self._source_path = Path(source_path).resolve() self.hash = ( - (self._source_path.parent / (self._source_path.name + ".hash")) + (self._source_path.parent.joinpath(self._source_path.name + ".hash")) .read_bytes() .hex() ) - self.name = kwargs.get("name") - self.version = kwargs.get("version") + self._name = name + self._version = version @property def hash_name(self) -> str: return f"{self._source_path.name}.hash" + + @property + def name(self) -> str: + return self._name + + @property + def version(self) -> str: + return self._version |
