refactor(system): add setenv_group and write_file task helpers
1. 为setenv和which函数添加正确的返回类型注解 2. 新增setenv_group批量设置环境变量的任务组 3. 新增write_file写入文件的任务工具函数 4. 更新__all__导出所有新增的工具函数 feat(cli/envdev): rewrite envdev cli with proper config and args 1. 重构环境开发CLI脚本,使用argparse替换原有TypedDict配置 2. 新增Python和Conda镜像源选择参数 3. 自动生成并写入Python pip和Conda配置文件 4. 优化任务依赖和命名,统一使用系统工具函数
This commit is contained in:
+126
-26
@@ -1,54 +1,101 @@
|
|||||||
from typing import TypedDict
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Literal, get_args
|
||||||
|
|
||||||
import pyflowx as px
|
import pyflowx as px
|
||||||
|
from pyflowx.tasks.system import Constants, setenv_group, write_file
|
||||||
|
|
||||||
class EnvConfig(TypedDict):
|
|
||||||
"""环境配置项."""
|
|
||||||
|
|
||||||
name: str
|
|
||||||
value: str
|
|
||||||
description: str
|
|
||||||
|
|
||||||
|
|
||||||
PIP_INDEX_URL_CONFIG: EnvConfig = {
|
|
||||||
"name": "PIP_INDEX_URL",
|
|
||||||
"value": "https://pypi.tuna.tsinghua.edu.cn/simple",
|
|
||||||
"description": "PIP索引URL",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# 配置
|
# Mirror 配置
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
DOWNLOAD_MIRROR_SCRIPT: str = "curl -sSL https://linuxmirrors.cn/main.sh -o /tmp/linuxmirrors.sh"
|
||||||
|
INSTALL_MIRROR_SCRIPT: str = "sudo bash /tmp/linuxmirrors.sh"
|
||||||
|
|
||||||
PIP_INDEX_URLS: dict[str, str] = {
|
# ============================================================================
|
||||||
|
# Python 配置
|
||||||
|
# ============================================================================
|
||||||
|
PyMirrorType = Literal["tsinghua", "aliyun"]
|
||||||
|
|
||||||
|
PIP_INDEX_URLS: dict[PyMirrorType, str] = {
|
||||||
"tsinghua": "https://pypi.tuna.tsinghua.edu.cn/simple",
|
"tsinghua": "https://pypi.tuna.tsinghua.edu.cn/simple",
|
||||||
"aliyun": "https://mirrors.aliyun.com/pypi/simple/",
|
"aliyun": "https://mirrors.aliyun.com/pypi/simple/",
|
||||||
}
|
}
|
||||||
|
|
||||||
PIP_TRUSTED_HOSTS: dict[str, str] = {
|
PIP_TRUSTED_HOSTS: dict[PyMirrorType, str] = {
|
||||||
"tsinghua": "pypi.tuna.tsinghua.edu.cn",
|
"tsinghua": "pypi.tuna.tsinghua.edu.cn",
|
||||||
"aliyun": "mirrors.aliyun.com",
|
"aliyun": "mirrors.aliyun.com",
|
||||||
}
|
}
|
||||||
|
PIP_CONFIG_PATH = Path.home() / ".pip" / "pip.conf" if not Constants.IS_WINDOWS else Path.home() / "pip" / "pip.ini"
|
||||||
|
|
||||||
UV_INDEX_URL: str = "https://mirrors.aliyun.com/pypi/simple/"
|
UV_INDEX_URLS: dict[PyMirrorType, str] = {
|
||||||
|
"tsinghua": "https://pypi.tuna.tsinghua.edu.cn/simple",
|
||||||
|
"aliyun": "https://mirrors.aliyun.com/pypi/simple/",
|
||||||
|
}
|
||||||
UV_PYTHON_INSTALL_MIRROR: str = "https://registry.npmmirror.com/-/binary/python-build-standalone"
|
UV_PYTHON_INSTALL_MIRROR: str = "https://registry.npmmirror.com/-/binary/python-build-standalone"
|
||||||
|
|
||||||
CONDA_MIRROR_URLS: dict[str, list[str]] = {
|
# ============================================================================
|
||||||
|
# Conda 配置
|
||||||
|
# ============================================================================
|
||||||
|
CondaMirrorType = Literal["tsinghua", "ustc", "bsfu", "aliyun"]
|
||||||
|
|
||||||
|
CONDA_MIRROR_URLS: dict[CondaMirrorType, list[str]] = {
|
||||||
"tsinghua": [
|
"tsinghua": [
|
||||||
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/",
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/",
|
||||||
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/",
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/",
|
||||||
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/",
|
||||||
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2/",
|
||||||
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro/",
|
||||||
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/",
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/",
|
||||||
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/",
|
||||||
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/menpo/",
|
||||||
|
"https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/",
|
||||||
|
],
|
||||||
|
"ustc": [
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/pkgs/main/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/pkgs/free/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/pkgs/r/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/pkgs/msys2/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/pkgs/pro/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/pkgs/dev/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/cloud/bioconda/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/cloud/menpo/",
|
||||||
|
"https://mirrors.ustc.edu.cn/anaconda/cloud/pytorch/",
|
||||||
|
],
|
||||||
|
"bsfu": [
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/main/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/free/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/r/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/msys2/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/pro/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/pkgs/dev/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/cloud/conda-forge/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/cloud/bioconda/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/cloud/menpo/",
|
||||||
|
"https://mirrors.bsfu.edu.cn/anaconda/cloud/pytorch/",
|
||||||
],
|
],
|
||||||
"aliyun": [
|
"aliyun": [
|
||||||
"https://mirrors.aliyun.com/anaconda/pkgs/main/",
|
"https://mirrors.aliyun.com/anaconda/pkgs/main/",
|
||||||
"https://mirrors.aliyun.com/anaconda/pkgs/free/",
|
"https://mirrors.aliyun.com/anaconda/pkgs/free/",
|
||||||
|
"https://mirrors.aliyun.com/anaconda/pkgs/r/",
|
||||||
|
"https://mirrors.aliyun.com/anaconda/pkgs/msys2/",
|
||||||
|
"https://mirrors.aliyun.com/anaconda/pkgs/pro/",
|
||||||
|
"https://mirrors.aliyun.com/anaconda/pkgs/dev/",
|
||||||
"https://mirrors.aliyun.com/anaconda/cloud/conda-forge/",
|
"https://mirrors.aliyun.com/anaconda/cloud/conda-forge/",
|
||||||
|
"https://mirrors.aliyun.com/anaconda/cloud/bioconda/",
|
||||||
|
"https://mirrors.aliyun.com/anaconda/cloud/menpo/",
|
||||||
|
"https://mirrors.aliyun.com/anaconda/cloud/pytorch/",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
CONDA_CONFIG_PATH = Path.home() / ".condarc"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Qt 配置
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
QT_LIBS: list[str] = [
|
QT_LIBS: list[str] = [
|
||||||
"build-essential",
|
"build-essential",
|
||||||
"libgl1",
|
"libgl1",
|
||||||
@@ -79,19 +126,72 @@ CHINESE_FONTS: list[str] = [
|
|||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
"""主函数."""
|
"""主函数."""
|
||||||
|
parser = argparse.ArgumentParser(description="环境开发工具")
|
||||||
|
parser.add_argument(
|
||||||
|
"--python-mirror",
|
||||||
|
nargs="?",
|
||||||
|
type=str,
|
||||||
|
default="tsinghua",
|
||||||
|
choices=get_args(PyMirrorType),
|
||||||
|
help="Python 镜像源",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--conda-mirror",
|
||||||
|
nargs="?",
|
||||||
|
type=str,
|
||||||
|
default="tsinghua",
|
||||||
|
choices=get_args(CondaMirrorType),
|
||||||
|
help="Conda 镜镜像源",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
python_mirror = args.python_mirror
|
||||||
|
python_envs: dict[str, str] = {
|
||||||
|
"PIP_INDEX_URL": PIP_INDEX_URLS[python_mirror],
|
||||||
|
"PIP_TRUSTED_HOSTS": PIP_TRUSTED_HOSTS[python_mirror],
|
||||||
|
"UV_INDEX_URL": UV_INDEX_URLS[python_mirror],
|
||||||
|
"UV_PYTHON_INSTALL_MIRROR": UV_PYTHON_INSTALL_MIRROR,
|
||||||
|
"UV_HTTP_TIMEOUT": "600",
|
||||||
|
"UV_LINK_MODE": "copy",
|
||||||
|
}
|
||||||
|
|
||||||
|
conda_mirror_urls = CONDA_MIRROR_URLS[args.conda_mirror]
|
||||||
|
|
||||||
|
# 确保配置文件目录存在
|
||||||
|
PIP_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
CONDA_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# 使用更安全的分步执行方式,便于调试和捕获错误
|
# 使用更安全的分步执行方式,便于调试和捕获错误
|
||||||
graph = px.Graph.from_specs([
|
graph = px.Graph.from_specs([
|
||||||
# 下载镜像
|
# 下载镜像
|
||||||
px.TaskSpec("download", cmd="curl -sSL https://linuxmirrors.cn/main.sh -o /tmp/linuxmirrors.sh", verbose=True),
|
px.TaskSpec("download_mirror", cmd=DOWNLOAD_MIRROR_SCRIPT, verbose=True),
|
||||||
# 安装镜像
|
# 安装镜像
|
||||||
px.TaskSpec("install", cmd="sudo bash /tmp/linuxmirrors.sh", verbose=True, depends_on=("download",)),
|
px.TaskSpec("install_mirror", cmd=INSTALL_MIRROR_SCRIPT, verbose=True, depends_on=("download_mirror",)),
|
||||||
# 安装 PyQt 相关依赖
|
# 安装 PyQt 相关依赖
|
||||||
px.TaskSpec(
|
px.TaskSpec(
|
||||||
"envqt_install", cmd=["sudo", "apt", "install", "-y", *QT_LIBS], verbose=True, depends_on=("install",)
|
"install_qt_libs",
|
||||||
|
cmd=["sudo", "apt", "install", "-y", *QT_LIBS],
|
||||||
|
verbose=True,
|
||||||
|
depends_on=("install_mirror",),
|
||||||
),
|
),
|
||||||
# 安装中文字体
|
# 安装中文字体
|
||||||
px.TaskSpec(
|
px.TaskSpec(
|
||||||
"envqt_fonts", cmd=["sudo", "apt", "install", "-y", *CHINESE_FONTS], verbose=True, depends_on=("install",)
|
"install_fonts",
|
||||||
|
cmd=["sudo", "apt", "install", "-y", *CHINESE_FONTS],
|
||||||
|
verbose=True,
|
||||||
|
depends_on=("install_mirror",),
|
||||||
|
),
|
||||||
|
# 设置 Python 环境变量
|
||||||
|
*setenv_group(python_envs),
|
||||||
|
# 写入 Python 配置
|
||||||
|
write_file(
|
||||||
|
str(PIP_CONFIG_PATH),
|
||||||
|
f"[global]\nindex-url = {PIP_INDEX_URLS[python_mirror]}\ntrusted-host = {PIP_TRUSTED_HOSTS[python_mirror]}",
|
||||||
|
),
|
||||||
|
# 写入 Conda 配置
|
||||||
|
write_file(
|
||||||
|
str(CONDA_CONFIG_PATH),
|
||||||
|
"show_channel_urls: true\nchannels:" + "\n".join(conda_mirror_urls) + "\n - defaults",
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
px.run(graph, strategy="thread", verbose=True)
|
px.run(graph, strategy="thread", verbose=True)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ def reset_icon_cache() -> list[px.TaskSpec]:
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def setenv(name: str, value: str, default: bool = False):
|
def setenv(name: str, value: str, default: bool = False) -> px.TaskSpec:
|
||||||
"""设置环境变量任务."""
|
"""设置环境变量任务."""
|
||||||
|
|
||||||
def set_env():
|
def set_env():
|
||||||
@@ -78,7 +78,12 @@ def setenv(name: str, value: str, default: bool = False):
|
|||||||
return px.TaskSpec(f"setenv_{name.lower()}", fn=set_env, verbose=True)
|
return px.TaskSpec(f"setenv_{name.lower()}", fn=set_env, verbose=True)
|
||||||
|
|
||||||
|
|
||||||
def which(cmd: str):
|
def setenv_group(envs: dict[str, str], default: bool = False) -> list[px.TaskSpec]:
|
||||||
|
"""设置环境变量组任务."""
|
||||||
|
return [setenv(name, value, default) for name, value in envs.items()]
|
||||||
|
|
||||||
|
|
||||||
|
def which(cmd: str) -> px.TaskSpec:
|
||||||
"""查找命令路径任务."""
|
"""查找命令路径任务."""
|
||||||
which_cmd = "where" if Constants.IS_WINDOWS else "which"
|
which_cmd = "where" if Constants.IS_WINDOWS else "which"
|
||||||
|
|
||||||
@@ -95,4 +100,17 @@ def which(cmd: str):
|
|||||||
return px.TaskSpec(f"which_{cmd}", fn=find_command)
|
return px.TaskSpec(f"which_{cmd}", fn=find_command)
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["clr", "setenv", "which"]
|
def write_file(path: str, content: str, encoding: str = "utf-8") -> px.TaskSpec:
|
||||||
|
"""写入文件任务."""
|
||||||
|
|
||||||
|
def write():
|
||||||
|
try:
|
||||||
|
with open(path, "w", encoding=encoding) as f:
|
||||||
|
f.write(content)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"写入文件 {path} 失败: {e}")
|
||||||
|
|
||||||
|
return px.TaskSpec(f"write_file_{path}", fn=write, verbose=True)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["clr", "reset_icon_cache", "setenv", "setenv_group", "which", "write_file"]
|
||||||
|
|||||||
Reference in New Issue
Block a user