feat: add automatic node dependency management
This commit is contained in:
parent
94c2e051c1
commit
8a09f790fd
@ -4,7 +4,6 @@
|
|||||||
"""
|
"""
|
||||||
import subprocess
|
import subprocess
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Any, Optional, List
|
from typing import Dict, Any, Optional, List
|
||||||
from jingrow.utils.path import get_jingrow_root
|
from jingrow.utils.path import get_jingrow_root
|
||||||
@ -48,76 +47,6 @@ def discover_nodes_with_dependencies() -> List[str]:
|
|||||||
return sorted(nodes_with_deps)
|
return sorted(nodes_with_deps)
|
||||||
|
|
||||||
|
|
||||||
def update_workspace_members() -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
自动更新 pyproject.toml 中的 workspace members
|
|
||||||
自动发现所有有 pyproject.toml 的节点,更新为具体列表(避免通配符匹配到无 pyproject.toml 的目录)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
更新结果字典
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
jingrow_root = get_jingrow_root()
|
|
||||||
pyproject_path = jingrow_root.parent / "pyproject.toml"
|
|
||||||
|
|
||||||
if not pyproject_path.exists():
|
|
||||||
return {"success": False, "error": "pyproject.toml 不存在"}
|
|
||||||
|
|
||||||
# 发现所有有依赖的节点
|
|
||||||
nodes_with_deps = discover_nodes_with_dependencies()
|
|
||||||
|
|
||||||
# 读取 pyproject.toml
|
|
||||||
with open(pyproject_path, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# 构建新的 members 列表
|
|
||||||
members_lines = []
|
|
||||||
for node_type in nodes_with_deps:
|
|
||||||
members_lines.append(f' "jingrow/ai/nodes/{node_type}",')
|
|
||||||
|
|
||||||
# 如果没有节点,使用空列表
|
|
||||||
if not members_lines:
|
|
||||||
members_lines = []
|
|
||||||
|
|
||||||
# 替换 workspace members 部分
|
|
||||||
# 匹配 [tool.uv.workspace] 到下一个 [ 或文件结尾
|
|
||||||
pattern = r'(\[tool\.uv\.workspace\]\s+members\s*=\s*\[)(.*?)(\]\s*(?:exclude\s*=.*?)?)'
|
|
||||||
|
|
||||||
def replace_workspace(match):
|
|
||||||
if members_lines:
|
|
||||||
return f'{match.group(1)}\n' + '\n'.join(members_lines) + f'\n{match.group(3)}'
|
|
||||||
else:
|
|
||||||
return f'{match.group(1)}\n{match.group(3)}'
|
|
||||||
|
|
||||||
if re.search(pattern, content, re.DOTALL):
|
|
||||||
new_content = re.sub(pattern, replace_workspace, content, flags=re.DOTALL)
|
|
||||||
else:
|
|
||||||
# 如果没有 workspace 配置,添加一个
|
|
||||||
if members_lines:
|
|
||||||
workspace_section = f'\n\n[tool.uv.workspace]\nmembers = [\n' + '\n'.join(members_lines) + '\n]\n'
|
|
||||||
else:
|
|
||||||
workspace_section = '\n\n[tool.uv.workspace]\nmembers = []\n'
|
|
||||||
new_content = content.rstrip() + workspace_section
|
|
||||||
|
|
||||||
# 只在内容有变化时才写入
|
|
||||||
if new_content != content:
|
|
||||||
with open(pyproject_path, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(new_content)
|
|
||||||
return {
|
|
||||||
"success": True,
|
|
||||||
"message": f"已更新 workspace members: {', '.join(nodes_with_deps) if nodes_with_deps else '无'}"
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return {
|
|
||||||
"success": True,
|
|
||||||
"message": "workspace members 无需更新"
|
|
||||||
}
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"更新 workspace members 失败: {str(e)}")
|
|
||||||
return {"success": False, "error": str(e)}
|
|
||||||
|
|
||||||
|
|
||||||
def install_node_dependencies(node_type: str, sync: bool = True) -> Dict[str, Any]:
|
def install_node_dependencies(node_type: str, sync: bool = True) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
安装节点的依赖
|
安装节点的依赖
|
||||||
@ -141,11 +70,6 @@ def install_node_dependencies(node_type: str, sync: bool = True) -> Dict[str, An
|
|||||||
# 节点没有独立依赖,返回成功(使用根依赖)
|
# 节点没有独立依赖,返回成功(使用根依赖)
|
||||||
return {"success": True, "message": "节点使用根依赖,无需安装"}
|
return {"success": True, "message": "节点使用根依赖,无需安装"}
|
||||||
|
|
||||||
# 更新 workspace members(确保节点在 workspace 中)
|
|
||||||
update_result = update_workspace_members()
|
|
||||||
if not update_result.get("success"):
|
|
||||||
logger.warning(f"更新 workspace members 失败: {update_result.get('error')}")
|
|
||||||
|
|
||||||
# 获取项目根目录(apps/jingrow)
|
# 获取项目根目录(apps/jingrow)
|
||||||
project_root = jingrow_root.parent
|
project_root = jingrow_root.parent
|
||||||
|
|
||||||
|
|||||||
@ -19,8 +19,3 @@ dependencies = [
|
|||||||
"Pillow>=10.0.0",
|
"Pillow>=10.0.0",
|
||||||
"Jinja2>=3.1.0",
|
"Jinja2>=3.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.uv.workspace]
|
|
||||||
members = [
|
|
||||||
"jingrow/ai/nodes/web_scrapers",
|
|
||||||
]
|
|
||||||
|
|||||||
2359
apps/jingrow/uv.lock
generated
2359
apps/jingrow/uv.lock
generated
File diff suppressed because it is too large
Load Diff
14
dev.sh
14
dev.sh
@ -136,16 +136,16 @@ check_deps() {
|
|||||||
# 检查后端依赖(优先使用 uv)
|
# 检查后端依赖(优先使用 uv)
|
||||||
info "同步后端依赖 (uv)..."
|
info "同步后端依赖 (uv)..."
|
||||||
if [ -f "apps/jingrow/pyproject.toml" ]; then
|
if [ -f "apps/jingrow/pyproject.toml" ]; then
|
||||||
# 在 uv sync 之前,自动更新 workspace members(包含所有有依赖的节点)
|
# 同步主项目依赖
|
||||||
info "自动更新 workspace members..."
|
(cd apps/jingrow && uv sync) || {
|
||||||
(cd apps/jingrow && uv run python -c "from jingrow.utils.node_dependencies import update_workspace_members; result = update_workspace_members(); print(result.get('message', '更新完成'))" 2>&1) || {
|
|
||||||
warn "更新 workspace members 失败,继续执行 uv sync"
|
|
||||||
}
|
|
||||||
# 使用 --all-packages 确保安装所有 workspace members 的依赖
|
|
||||||
(cd apps/jingrow && uv sync --all-packages) || {
|
|
||||||
error "uv 同步失败"
|
error "uv 同步失败"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
# 安装所有节点的依赖(直接使用 uv pip install,不修改配置文件)
|
||||||
|
info "安装节点依赖..."
|
||||||
|
(cd apps/jingrow && uv run python -c "from jingrow.utils.node_dependencies import discover_nodes_with_dependencies, install_node_dependencies; nodes = discover_nodes_with_dependencies(); [install_node_dependencies(node) for node in nodes]" 2>&1) || {
|
||||||
|
warn "安装节点依赖失败,但继续执行"
|
||||||
|
}
|
||||||
elif [ -f "apps/jingrow/requirements.txt" ]; then
|
elif [ -f "apps/jingrow/requirements.txt" ]; then
|
||||||
warn "未发现 pyproject.toml,使用 requirements.txt 安装"
|
warn "未发现 pyproject.toml,使用 requirements.txt 安装"
|
||||||
(cd apps/jingrow && uv pip install -r requirements.txt) || {
|
(cd apps/jingrow && uv pip install -r requirements.txt) || {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user