From 96f5767109da53373ddc00206aeb69ed79821137 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Tue, 16 Jan 2024 23:50:56 +0800 Subject: :sparkles: feat(cli): add console output --- src/ipm/__main__.py | 2 +- src/ipm/api.py | 21 +++++++++++++++------ src/ipm/const.py | 4 +++- src/ipm/logging.py | 10 +++++++++- src/ipm/models/ipk.py | 3 +++ src/ipm/utils/freeze.py | 24 ++++++++++++++++++------ src/ipm/utils/loader.py | 6 ++++-- 7 files changed, 53 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/ipm/__main__.py b/src/ipm/__main__.py index 0c1267a..9e25085 100644 --- a/src/ipm/__main__.py +++ b/src/ipm/__main__.py @@ -31,7 +31,7 @@ def main(): args = parser.parse_args() if args.command == "install": - install(args.uri, args.index) + install(args.uri, args.index, echo=True) elif args.command == "extract": extract(args.package, args.dist) elif args.command == "build": diff --git a/src/ipm/api.py b/src/ipm/api.py index 50f1a32..30f7040 100644 --- a/src/ipm/api.py +++ b/src/ipm/api.py @@ -4,33 +4,40 @@ from .utils import freeze, urlparser, loader from .models.ipk import InfiniPackage from .exceptions import FileTypeMismatch from .const import INDEX, HOME +from .logging import info, success import os -def build(source_path: StrPath) -> None: +def build(source_path: StrPath, echo: bool = False) -> None: freeze.build_ipk(InfiniPackage(source_path)) -def extract(source_path: StrPath, dist_path: StrPath | None = None) -> None: +def extract( + source_path: StrPath, dist_path: StrPath | None = None, echo: bool = False +) -> InfiniPackage: dist_path = ( Path(dist_path).resolve() if dist_path else Path(source_path).resolve().parent ) - freeze.extract_ipk(source_path, dist_path) + return freeze.extract_ipk(source_path, dist_path, echo) -def install(uri: str, index: str = "") -> None: +def install(uri: str, index: str = "", echo: bool = False) -> None: + info("正在初始化 IPM 环境...", echo) + HOME.mkdir(parents=True, exist_ok=True) index = index if index else INDEX if os.path.isabs(uri): + info(f"检定给定的 URI 地址[{uri}]为本地路径.", echo) if uri.endswith(".ipk"): - extract(Path(uri).resolve(), HOME) + info("安装中...", echo) + ipk = extract(Path(uri).resolve(), HOME, echo) else: raise FileTypeMismatch("文件类型与预期[.ipk]不匹配.") elif urlparser.is_valid_url(uri): filename = uri.rstrip("/").split("/")[-1] - loader.load( + ipk = loader.load( "temp", uri.rstrip("/").rsplit("/")[0], filename, @@ -39,3 +46,5 @@ def install(uri: str, index: str = "") -> None: ... else: raise FileTypeMismatch("URI指向未知的位置.") + + success(f"包[{ipk.name}]成功安装在[{ipk.source_path}].", echo) diff --git a/src/ipm/const.py b/src/ipm/const.py index fba2345..c682fdd 100644 --- a/src/ipm/const.py +++ b/src/ipm/const.py @@ -1,6 +1,8 @@ from pathlib import Path -DEBUG = True +DEBUG = False INDEX = "https://ipm.hydroroll.team/index/" HOME = Path.home() / ".ipm" / "src" +ATTENSION = """# This file is @generated by IPM. +# It is not intended for manual editing.""" diff --git a/src/ipm/logging.py b/src/ipm/logging.py index 41538c1..2594930 100644 --- a/src/ipm/logging.py +++ b/src/ipm/logging.py @@ -1,4 +1,12 @@ from multilogging import multilogger from .const import DEBUG -logger = multilogger(name="IPM", level="DEBUG" if DEBUG else "INFO") +logger = multilogger(name="IPM", level="DEBUG" if DEBUG else "INFO", notime=True) + + +def info(message: str, echo: bool = True) -> None: + return logger.info(message) if echo else None + + +def success(message: str, echo: bool = True) -> None: + return logger.success(message) if echo else None diff --git a/src/ipm/models/ipk.py b/src/ipm/models/ipk.py index 14dca06..a50ebde 100644 --- a/src/ipm/models/ipk.py +++ b/src/ipm/models/ipk.py @@ -58,6 +58,9 @@ class InfiniPackage: def hash_name(self) -> str: return f"{self.name}-{self.version}.ipk.hash" + # @property + # def home_p + class InfiniFrozenPackage: source_path: Path diff --git a/src/ipm/utils/freeze.py b/src/ipm/utils/freeze.py index 8f7698f..74f4b40 100644 --- a/src/ipm/utils/freeze.py +++ b/src/ipm/utils/freeze.py @@ -1,9 +1,10 @@ from pathlib import Path -from . import _freeze from ..exceptions import FileNotFoundError, VerifyFailed from ..models.ipk import InfiniPackage, InfiniFrozenPackage -from .hash import ifp_hash, ifp_verify from ..typing import StrPath +from ..logging import logger, info, success +from .hash import ifp_hash, ifp_verify +from . import _freeze import tempfile import shutil @@ -36,7 +37,9 @@ def build_ipk(ipk: InfiniPackage) -> InfiniFrozenPackage: return InfiniFrozenPackage(source_path=ifp_path, **{"name": ipk.name}) -def extract_ipk(source_path: StrPath, dist_path: str | Path) -> InfiniPackage: +def extract_ipk( + source_path: StrPath, dist_path: str | Path, echo: bool = False +) -> InfiniPackage: ifp_path = Path(source_path).resolve() dist_path = Path(dist_path).resolve() hash_path = ifp_path.parent / (ifp_path.name + ".hash") @@ -50,14 +53,23 @@ def extract_ipk(source_path: StrPath, dist_path: str | Path) -> InfiniPackage: temp_dir = tempfile.TemporaryDirectory() temp_path = Path(temp_dir.name).resolve() / "ifp" + info(f"创建临时目录[{temp_dir}], 开始解压...", echo) _freeze.extract_tar_gz(str(ifp_path), str(temp_path)) temp_pkg = InfiniPackage(temp_path) dist_pkg_path = dist_path / temp_pkg.name + success(f"包[{temp_pkg.name}]解压完成.", echo) if dist_pkg_path.exists(): - shutil.rmtree(dist_pkg_path) - + info("目标路径已存在, 清理旧文件...", echo) + try: + shutil.rmtree(dist_pkg_path) + except Exception as error: + logger.exception(error) if echo else logger.error(error) + success("旧规则包清理完毕.", echo) + + info(f"迁移文件至安装目录中...", echo) shutil.move(temp_path, dist_pkg_path) - + info(f"任务完成, 开始清理临时文件...", echo) temp_dir.cleanup() + info(f"临时文件清理完毕.", echo) return InfiniPackage(dist_pkg_path) diff --git a/src/ipm/utils/loader.py b/src/ipm/utils/loader.py index 297b0c0..41b19f9 100644 --- a/src/ipm/utils/loader.py +++ b/src/ipm/utils/loader.py @@ -1,12 +1,13 @@ from pathlib import Path from .freeze import extract_ipk from ..const import HOME +from ..models.ipk import InfiniPackage import requests import tempfile -def load(name: str, baseurl: str = "", filename: str = "") -> None: +def load(name: str, baseurl: str = "", filename: str = "") -> InfiniPackage: ipk_bytes = requests.get(baseurl.rstrip("/") + "/" + filename).content hash_bytes = requests.get(baseurl.rstrip("/") + "/" + filename + ".hash").content @@ -21,5 +22,6 @@ def load(name: str, baseurl: str = "", filename: str = "") -> None: hash_file.write(hash_bytes) hash_file.close() - extract_ipk(ipk_file, HOME) + ipk = extract_ipk(ipk_file, HOME) temp_dir.cleanup() + return ipk -- cgit v1.2.3-70-g09d2