Skip to content

Commit

Permalink
feat(api): add remove and add cli
Browse files Browse the repository at this point in the history
  • Loading branch information
fu050409 committed Mar 8, 2024
1 parent 46a82e2 commit d2c3057
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 79 deletions.
71 changes: 29 additions & 42 deletions src/ipm/__main__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from pathlib import Path
from . import api
from .exceptions import IPMException
from .logging import status, error, tada
from ipm import api
from ipm.exceptions import IPMException
from ipm.logging import status, error, tada

import typer

status.start()
Expand Down Expand Up @@ -98,8 +99,8 @@ def build(package: str = typer.Argument(".", help="Infini 项目路径")):
)


@yggdrasil.command()
def add(
@yggdrasil.command("add")
def yggdrasil_add(
name: str = typer.Argument(help="世界树名称"),
index: str = typer.Argument(help="世界树地址"),
):
Expand Down Expand Up @@ -127,18 +128,6 @@ def add(
# status.stop()


# @main.command()
# def uninstall(package: str = typer.Argument(help="Infini 项目路径")):
# """卸载 Infini 规则包"""
# try:
# if api.uninstall(package, echo=True):
# tada()
# except IpmException as err:
# error(str(err), echo=True)
# finally:
# status.stop()


@main.command()
def require(
name: str = typer.Argument(help="Infini 包名"),
Expand Down Expand Up @@ -175,36 +164,34 @@ def unrequire(name: str = typer.Argument(help="Infini 包名")):
status.stop()


# @main.command()
# def add(
# name: str = typer.Argument(help="Infini 包名"),
# index: str = typer.Option(None, help="世界树服务器地址"),
# ):
# """新增环境依赖"""
# try:
# if api.add(name, index=index, echo=True):
# tada()
# except IpmException as err:
# error(str(err), echo=True)
# finally:
# status.stop()
@main.command()
def add(name: str = typer.Argument(help="Infini 包名")):
"""新增环境依赖"""
try:
if api.add(Path.cwd(), name, echo=True):
tada()
except IPMException as err:
error(str(err), echo=True)
finally:
status.stop()


# @main.command()
# def remove(name: str = typer.Argument(help="Infini 包名")):
# """删除环境依赖"""
# try:
# if api.remove(name, echo=True):
# tada()
# except IpmException as err:
# error(str(err), echo=True)
# finally:
# status.stop()
@main.command()
def remove(name: str = typer.Argument(help="Infini 包名")):
"""删除环境依赖"""
try:
if api.remove(Path.cwd(), name, echo=True):
tada()
except IPMException as err:
error(str(err), echo=True)
finally:
status.stop()


# TODO
@main.command()
def update(): ...
def update():
"""更新 Infini 依赖"""
raise NotImplementedError


main.add_typer(yggdrasil)
Expand Down
111 changes: 74 additions & 37 deletions src/ipm/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@
from ipm.project.env import new_virtualenv
from ipm.project.toml_file import add_yggdrasil, init_infini, init_pyproject
from ipm.typing import StrPath
from ipm.utils import freeze, urlparser, loader
from ipm.const import GITIGNORE, INDEX, INDEX_PATH, STORAGE, SRC_HOME
from ipm.logging import status, update, info, success, warning, error, confirm, ask
from ipm.utils import freeze
from ipm.logging import status, update, info, success, warning, error, ask
from ipm.exceptions import (
FileTypeMismatch,
EnvironmentError,
TomlLoadFailed,
FileNotFoundError,
PackageExsitsError,
NameError,
RuntimeError,
)
from ipm.utils.version import require_update
from ipm.models.ipk import InfiniProject, InfiniFrozenPackage

# from ipm.models.lock import PackageLock, ProjectLock
from ipm.models.index import Yggdrasil

import tomlkit
import shutil
import os
import re
import subprocess
import configparser


Expand Down Expand Up @@ -236,36 +234,75 @@ def unrequire(target_path: StrPath, name: str, echo: bool = False):
return True


# def add(name: str, index: str = "", echo: bool = False) -> None:
# info("检查环境中...", echo)
# pkg_lock = PackageLock()
# lock = ProjectLock()
# ipk = InfiniProject()
# info("环境检查完毕.", echo)

# splited_name = name.split("==") # TODO 支持 >= <= > < 标识
# name = splited_name[0]

# if len(splited_name) > 1:
# version = splited_name[1]
# else:
# version = None
def add(target_path, name: str, echo: bool = False) -> bool:
info(f"新增环境依赖项: [bold green]{name}[/bold green]", echo)
status.start()
status.update("检查环境中...")
if not (
match := re.match(r"^((?:[a-zA-Z_-]|\d)+)(?:([>=<]+\d+(?:[.]\d+)*))?$", name)
):
raise NameError(f"版本号 [bold red]{name}[/] 不合法.")
if not (toml_path := Path(target_path).joinpath("infini.toml")).exists():
raise FileNotFoundError(
f"文件 [green]infini.toml[/green] 尚未被初始化, 你可以使用[bold green]`ipm init`[/bold green]来初始化项目."
)
project = InfiniProject(toml_path.parent)
if not shutil.which("pdm"):
raise EnvironmentError(
"IPM 未能在环境中找到 [bold green]PDM[/] 安装, 请确保 PDM 在环境中被正确安装. "
"你可以使用`[bold green]pipx install pdm[/]`来安装此包管理器."
)
success("环境检查完毕.", echo)

# if not pkg_lock.has_package(name):
# # TODO pip 环境安装
# ...
status.update("安装依赖中...")

name = match.group(1)
version = match.group(2)
project.add(name, version or "*")
if (
result := subprocess.run(
["pdm", "add", name],
cwd=target_path,
capture_output=True,
text=True,
)
).returncode != 0:
error(result.stderr.strip("\n"), echo)
raise RuntimeError("PDM 异常退出, 指令忽略.")

# info("处理 Infini 项目依赖锁...", echo)
# ipk.add(name, version, dump=True)
# lock.add(name, version, dump=True)
# success("环境依赖新增完成.", echo)
project.dump()
success("项目文件写入完成.", echo)
return True


# def remove(name: str, echo: bool = False):
# info("处理 Infini 项目依赖锁...", echo)
# ipk = InfiniProject()
# lock = ProjectLock()
def remove(target_path: StrPath, name: str, echo: bool = False):
info(f"删除环境依赖项: [bold green]{name}[/bold green]", echo)
status.start()
status.update("检查环境中...")
if not (toml_path := Path(target_path).joinpath("infini.toml")).exists():
raise FileNotFoundError(
f"文件 [green]infini.toml[/green] 尚未被初始化, 你可以使用[bold green]`ipm init`[/bold green]来初始化项目."
)
project = InfiniProject(toml_path.parent)
if not shutil.which("pdm"):
raise EnvironmentError(
"IPM 未能在环境中找到 [bold green]PDM[/] 安装, 请确保 PDM 在环境中被正确安装. "
"你可以使用`[bold green]pipx install pdm[/]`来安装此包管理器."
)
success("环境检查完毕.", echo)
project.remove(name)

if (
result := subprocess.run(
["pdm", "remove", name],
cwd=target_path,
capture_output=True,
text=True,
)
).returncode != 0:
error(result.stderr.strip("\n"), echo)
raise RuntimeError("PDM 异常退出, 指令忽略.")

# ipk.remove(name, dump=True)
# lock.remove(name, dump=True)
# success("环境依赖删除完成.", echo)
project.dump()
success("项目文件写入完成.", echo)
return True
12 changes: 12 additions & 0 deletions src/ipm/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@ class FileTypeMismatch(IPMException):

class PackageExsitsError(IPMException):
"""Package already installed"""


class EnvironmentError(IPMException):
"""Raises when environment is not valid"""


class RuntimeError(IPMException, RuntimeError):
"""An error occured when calling subprocess"""


class NameError(IPMException):
"""Provided name is not valid"""

0 comments on commit d2c3057

Please sign in to comment.