aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/ipm/models/index.py27
-rw-r--r--src/ipm/models/ipk.py2
-rw-r--r--src/ipm/models/lock.py7
-rw-r--r--src/ipm/models/requirement.py7
-rw-r--r--src/ipm/utils/resolve.py30
5 files changed, 70 insertions, 3 deletions
diff --git a/src/ipm/models/index.py b/src/ipm/models/index.py
index 0bac21e..f61c818 100644
--- a/src/ipm/models/index.py
+++ b/src/ipm/models/index.py
@@ -1,5 +1,5 @@
from pathlib import Path
-from typing import Any, Literal, Optional, Union
+from typing import Any, List, Literal, Optional, Union, TYPE_CHECKING
from ipm.const import INDEX_PATH
from ipm.exceptions import LockLoadFailed
from ipm.typing import Dict
@@ -9,6 +9,9 @@ import tempfile
import shutil
import json
+if TYPE_CHECKING:
+ from ipm.models.requirement import Requirement
+
class Yggdrasil:
def __init__(self, index: str, uuid: str) -> None:
@@ -100,10 +103,32 @@ class Yggdrasil:
return distribution["hash"]
def get_lastest_version(self, name: str) -> Optional[str]:
+ """从本地获取规则包最新版本"""
if name not in self.packages:
return None
return self.packages[name]["latestVersion"]
+ def get_requirements(self, name: str) -> List["Requirement"]:
+ if not name in self.packages:
+ return []
+ from ipm.models.requirement import Requirement
+
+ res = []
+ requirements = self.packages[name]["requirements"]
+ for requirement in requirements:
+ res.append(
+ Requirement(
+ requirement["name"],
+ requirement["version"],
+ url=requirement.get(
+ "url",
+ f"/packages/{requirement['name']}-{requirement['version']}.ipk",
+ ),
+ yggdrasil=self,
+ )
+ )
+ return res
+
@property
def uuid(self) -> str:
"""世界树唯一标识"""
diff --git a/src/ipm/models/ipk.py b/src/ipm/models/ipk.py
index 1a1e99f..fc77ac3 100644
--- a/src/ipm/models/ipk.py
+++ b/src/ipm/models/ipk.py
@@ -98,7 +98,7 @@ class InfiniProject(InfiniPackage):
requirement.add("yggdrasil", yggdrasil) if yggdrasil else None
requirement.add("index", index) if index else None
if not requirement:
- raise ValueError("")
+ raise ValueError
self._data["requirements"].update({name: requirement}) # type: ignore
def unrequire(self, name: str) -> None:
diff --git a/src/ipm/models/lock.py b/src/ipm/models/lock.py
index 160db4d..439d978 100644
--- a/src/ipm/models/lock.py
+++ b/src/ipm/models/lock.py
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING
import tomlkit
+
if TYPE_CHECKING:
from ipm.models import ipk
from ipm.models.index import Yggdrasil
@@ -135,6 +136,8 @@ class ProjectLock(IPMLock):
def init_from_project(
project: "ipk.InfiniProject", dist_path: Optional[Path] = None
) -> "ProjectLock":
+ from ipm.utils.resolve import get_requirements_by_project
+
lock = ProjectLock(dist_path or project._source_path)
lock._data = tomlkit.document()
@@ -146,7 +149,9 @@ class ProjectLock(IPMLock):
lock._data.add("metadata", metadata)
packages = tomlkit.aot()
- for requirement in project.requirements:
+ requirements = get_requirements_by_project(project)
+
+ for requirement in requirements:
if requirement.is_local():
packages.append(
tomlkit.item(
diff --git a/src/ipm/models/requirement.py b/src/ipm/models/requirement.py
index 223ac18..04e33cb 100644
--- a/src/ipm/models/requirement.py
+++ b/src/ipm/models/requirement.py
@@ -35,6 +35,13 @@ class Requirement:
self.yggdrasil = yggdrasil
self.hash = hash
+ def __eq__(self, __value: "Requirement") -> bool:
+ return (
+ __value.name == self.name
+ and __value.version == self.version
+ and __value.yggdrasil.index == self.yggdrasil.index
+ )
+
def is_local(self) -> bool:
return bool(self.path)
diff --git a/src/ipm/utils/resolve.py b/src/ipm/utils/resolve.py
new file mode 100644
index 0000000..8e0c32d
--- /dev/null
+++ b/src/ipm/utils/resolve.py
@@ -0,0 +1,30 @@
+from typing import List
+from ipm.models.index import Yggdrasil
+from ipm.models.ipk import InfiniProject
+from ipm.models.requirement import Requirement
+
+
+def get_requirements(
+ requirement: Requirement, resolved: List[str] = []
+) -> List[Requirement]:
+ requirements = {}
+ for req in requirement.yggdrasil.get_requirements(requirement.name):
+ if req.name in resolved:
+ continue
+ resolved.append(req.name)
+ requirements[req.name] = req
+ sub_reqs = get_requirements(req, resolved)
+ for sub_seq in sub_reqs:
+ requirements[sub_seq.name] = sub_seq
+
+ return list(requirements.values())
+
+
+def get_requirements_by_project(project: InfiniProject) -> List[Requirement]:
+ requirements = {}
+ for requirement in project.requirements:
+ requirements[requirement.name] = requirement
+ reqs = get_requirements(requirement)
+ for req in reqs:
+ requirements[req.name] = req
+ return list(requirements.values())