diff options
| author | 2024-01-22 12:06:34 +0800 | |
|---|---|---|
| committer | 2024-01-22 12:06:34 +0800 | |
| commit | 3700244871ffdd0f8bde5a6be4c77203a39dac08 (patch) | |
| tree | 5c2e55a29438c9a8f5a17ca871883cf5b39fb2b2 | |
| parent | a93fc8191a24ee4cc984d2e1ddf12d3985f72ff9 (diff) | |
| download | ipm-3700244871ffdd0f8bde5a6be4c77203a39dac08.tar.gz ipm-3700244871ffdd0f8bde5a6be4c77203a39dac08.zip | |
:sparkles: feat(lock): separate lock into packages and storages
| -rw-r--r-- | src/ipm/api.py | 11 | ||||
| -rw-r--r-- | src/ipm/models/lock.py | 80 |
2 files changed, 75 insertions, 16 deletions
diff --git a/src/ipm/api.py b/src/ipm/api.py index 25f9595..5f3fbb9 100644 --- a/src/ipm/api.py +++ b/src/ipm/api.py @@ -94,13 +94,15 @@ def install(uri: str, index: str = "", echo: bool = False) -> None: else: raise FileTypeMismatch("文件类型与预期[.ipk]不匹配.") - if lock.has_ipk(ifp.name): + if lock.has_package(ifp.name): raise # TODO info(f"开始安装[{ifp.name}]中...", echo) ipk = extract(STORAGE / ifp.name / ifp.default_name, SRC_HOME, echo) info("正在处理全局包锁...", echo) - lock.add(ifp, dump=True) + if not lock.has_storage(ifp.name): + lock.add_storage(ifp, dump=True) + lock.add_package(ipk, dump=True) info("全局锁已处理完毕.", echo) success(f"包[{ipk.name}]成功安装在[{ipk.source_path}].", echo) @@ -110,12 +112,11 @@ def uninstall(name: str, confirm: bool = False, echo: bool = False) -> None: lock = PackageLock() path = SRC_HOME / name.strip() - if not (install_info := lock.get_ipk(name)): + if not (install_info := lock.get_package(name)): return warning(f"由于[{name}]未被安装, 故忽略卸载操作.", echo) info(f"发现已经安装的[{name}]版本[{install_info['version']}]:", echo) info(f" 将会清理: {path}", echo) - # TODO: 拆分安装lock和安装ipk的lock confirm: bool = ( True if (input("你确定要继续 (Y/n) ").upper() in ("", "Y") if not confirm else confirm) @@ -126,5 +127,5 @@ def uninstall(name: str, confirm: bool = False, echo: bool = False) -> None: else: return info("忽略.", echo) - lock.remove(name, dump=True) + lock.remove_package(name, dump=True) success(f"规则包[{name}]卸载完成!", echo) diff --git a/src/ipm/models/lock.py b/src/ipm/models/lock.py index d90c690..9346848 100644 --- a/src/ipm/models/lock.py +++ b/src/ipm/models/lock.py @@ -11,6 +11,7 @@ import toml class IpmLock(metaclass=ABCMeta): metadata: Dict[str, str] packages: List[Dict[str, Any]] + storages: List[Dict[str, Any]] source_path: Path def __init__(self, source_path: StrPath = IPM_PATH / "infini.lock") -> None: @@ -22,9 +23,8 @@ class IpmLock(metaclass=ABCMeta): if not self.source_path.exists(): self.metadata = {} self.packages = [] - source_file = self.source_path.open("w", encoding="utf-8") - source_file.write(ATTENSION + toml.dumps(self.dumps())) - source_file.close() + self.storages = [] + self.dumps() else: loaded_data = toml.load(self.source_path.open("r", encoding="utf-8")) self.metadata = ( @@ -33,9 +33,16 @@ class IpmLock(metaclass=ABCMeta): self.packages = ( loaded_data["packages"] if "packages" in loaded_data.keys() else [] ) + self.storages = ( + loaded_data["storages"] if "storages" in loaded_data.keys() else [] + ) def dumps(self) -> dict: - return {"metadata": self.metadata, "packages": self.packages} + return { + "metadata": self.metadata, + "packages": self.packages, + "storages": self.storages, + } def dump(self) -> str: data_to_dump = ATTENSION + toml.dumps(self.dumps()) @@ -50,17 +57,26 @@ class PackageLock(IpmLock): def __init__(self) -> None: super().__init__() - def add(self, ifp: "ipk.InfiniFrozenPackage", dump: bool = False) -> str: + def add_package(self, ipk: "ipk.InfiniProject", dump: bool = False) -> str: + for package in self.packages: + if "name" not in package.keys(): + raise SyntaxError("异常的锁文件!") + if package["name"] == ipk.name and package["version"] == ipk.version: + self.storages.remove(package) + break + self.packages.append( { - "name": ifp.name, - "version": ifp.version, - "hash": ifp.hash, + "name": ipk.name, + "version": ipk.version, + "description": ipk.description, + "requirements": ipk.requirements, + "dependencies": ipk.dependencies, } ) return self.dump() if dump else "" - def remove(self, name: str, dump: bool = False) -> str: + def remove_package(self, name: str, dump: bool = False) -> str: name = name.strip() for package in self.packages: if "name" not in package.keys(): @@ -70,20 +86,62 @@ class PackageLock(IpmLock): break return self.dump() if dump else "" - def get_ipk(self, name: str) -> dict | None: + def add_storage(self, ifp: "ipk.InfiniFrozenPackage", dump: bool = False) -> str: + for storage in self.storages: + if "name" not in storage.keys(): + raise SyntaxError("异常的锁文件!") + if storage["name"] == ifp.name and storage["version"] == ifp.version: + self.storages.remove(storage) + break + + self.storages.append( + { + "name": ifp.name, + "version": ifp.version, + "hash": ifp.hash, + "source": f"storage/{ifp.name}/{ifp.default_name}", + } + ) + return self.dump() if dump else "" + + def remove_storage(self, name: str, dump: bool = False) -> str: + name = name.strip() + for storage in self.storages: + if "name" not in storage.keys(): + raise SyntaxError("异常的锁文件!") + if storage["name"] == name: + self.storages.remove(storage) + break + return self.dump() if dump else "" + + def get_package(self, name: str) -> dict | None: name = name.strip() for package in self.packages: if package["name"] == name: return package return None - def has_ipk(self, name: str) -> bool: + def has_package(self, name: str) -> bool: name = name.strip() for package in self.packages: if package["name"] == name: return True return False + def get_storage(self, name: str) -> dict | None: + name = name.strip() + for storage in self.storages: + if storage["name"] == name: + return storage + return None + + def has_storage(self, name: str) -> dict | None: + name = name.strip() + for storage in self.storages: + if storage["name"] == name: + return True + return False + class ProjectLock: ... |
