Initial commit: TaskPool React panel
- React frontend with route-level code splitting - Backend rebranded from Baihu to TaskPool - DB brand migration script and local compatibility
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
package depinstall
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/engigu/taskpool/cmd/clibase"
|
||||
"github.com/engigu/taskpool/internal/database"
|
||||
"github.com/engigu/taskpool/internal/models"
|
||||
"github.com/engigu/taskpool/internal/services"
|
||||
"github.com/engigu/taskpool/internal/services/deps"
|
||||
"github.com/engigu/taskpool/internal/utils"
|
||||
)
|
||||
|
||||
// Run 依赖自动补全命令入口
|
||||
func Run(args []string) {
|
||||
if len(args) == 0 {
|
||||
fmt.Println("用法: taskpool depinstall <log_id>")
|
||||
return
|
||||
}
|
||||
|
||||
logID := args[0]
|
||||
fmt.Println(">> 提示: 依赖自动补全功能目前仅支持 Python 和 Node.js 环境,如有其他环境需求请及时反馈。")
|
||||
|
||||
// 初始化基础环境和数据库连接
|
||||
if err := clibase.InitContext(true); err != nil {
|
||||
fmt.Printf(">> 初始化环境失败: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
var log models.TaskLog
|
||||
if err := database.DB.Where("id = ?", logID).First(&log).Error; err != nil {
|
||||
fmt.Printf(">> 未找到指定的任务日志 (ID: %s): %v\n", logID, err)
|
||||
return
|
||||
}
|
||||
|
||||
var task models.Task
|
||||
if err := database.DB.Where("id = ?", log.TaskID).First(&task).Error; err != nil {
|
||||
fmt.Printf(">> 未找到对应的任务 (TaskID: %s): %v\n", log.TaskID, err)
|
||||
return
|
||||
}
|
||||
|
||||
logOutput, err := utils.DecompressFromBase64(string(log.Output))
|
||||
if err != nil {
|
||||
fmt.Printf(">> 解压日志失败: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 找出任务配置的语言
|
||||
taskLangs := task.GetLanguages()
|
||||
if len(taskLangs) == 0 {
|
||||
fmt.Println(">> 提示: 当前任务未配置具体语言环境,请手动指定语言类型(例如 python3, node 等):")
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, _ := reader.ReadString('\n')
|
||||
input = strings.TrimSpace(input)
|
||||
if input == "" {
|
||||
fmt.Println(">> 已取消补全。")
|
||||
return
|
||||
}
|
||||
taskLangs = append(taskLangs, map[string]string{
|
||||
"name": input,
|
||||
"version": "",
|
||||
})
|
||||
}
|
||||
|
||||
var allDetected []string
|
||||
langToPkgMap := make(map[string][]string)
|
||||
|
||||
for _, langMap := range taskLangs {
|
||||
langName := langMap["name"]
|
||||
if langName == "" {
|
||||
continue
|
||||
}
|
||||
detected, found := deps.DetectMissingDependencies(langName, logOutput)
|
||||
if found {
|
||||
langToPkgMap[langName] = detected
|
||||
allDetected = append(allDetected, detected...)
|
||||
}
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
// 如果没有检测到任何缺失的包,允许用户手动输入
|
||||
if len(allDetected) == 0 {
|
||||
fmt.Println(">> 分析完毕: 未从最近一次的任务运行日志中检测到缺失依赖模式。")
|
||||
fmt.Println(">> 您可以手动输入想要安装的依赖包名称(多个包用空格分隔,若不安装请直接回车退出):")
|
||||
input, _ := reader.ReadString('\n')
|
||||
input = strings.TrimSpace(input)
|
||||
if input == "" {
|
||||
fmt.Println(">> 已退出依赖补全。")
|
||||
return
|
||||
}
|
||||
// 默认分配到任务的第一个语言环境
|
||||
defaultLang := taskLangs[0]["name"]
|
||||
langToPkgMap[defaultLang] = strings.Fields(input)
|
||||
allDetected = append(allDetected, langToPkgMap[defaultLang]...)
|
||||
} else {
|
||||
fmt.Println(">> 分析结果: 从运行日志中检测到以下缺失依赖包:")
|
||||
for langName, pkgs := range langToPkgMap {
|
||||
fmt.Printf(" [%s]: %s\n", langName, strings.Join(pkgs, ", "))
|
||||
}
|
||||
fmt.Println(">> 是否确认自动安装上述依赖包?(y/N):")
|
||||
confirm, _ := reader.ReadString('\n')
|
||||
confirm = strings.TrimSpace(strings.ToLower(confirm))
|
||||
if confirm != "y" && confirm != "yes" {
|
||||
fmt.Println(">> 用户已取消安装操作。")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("==================================================================")
|
||||
fmt.Println(">> 开始执行依赖安装,请稍候...")
|
||||
fmt.Println("==================================================================")
|
||||
|
||||
var failedPkgs []string
|
||||
depService := services.NewDependencyService()
|
||||
|
||||
for langName, pkgs := range langToPkgMap {
|
||||
var langVersion string
|
||||
for _, lm := range taskLangs {
|
||||
if lm["name"] == langName {
|
||||
langVersion = lm["version"]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
m := deps.GetManager(langName)
|
||||
if m == nil {
|
||||
fmt.Printf(">> 错误: 不支持的语言类型: %s\n", langName)
|
||||
failedPkgs = append(failedPkgs, pkgs...)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, pkg := range pkgs {
|
||||
dep := &models.Dependency{
|
||||
Name: pkg,
|
||||
Language: langName,
|
||||
LangVersion: langVersion,
|
||||
}
|
||||
|
||||
cmdStr, err := m.GetInstallCommand(dep)
|
||||
if err != nil {
|
||||
fmt.Printf(">> 无法生成 %s 包 [%s] 的安装命令: %v\n", langName, pkg, err)
|
||||
failedPkgs = append(failedPkgs, pkg)
|
||||
continue
|
||||
}
|
||||
|
||||
// 去除命令末尾的 success/failed echo 重定向,因为我们需要捕获退出状态并在控制台展示原始流程
|
||||
if idx := strings.Index(cmdStr, " && echo"); idx != -1 {
|
||||
cmdStr = cmdStr[:idx]
|
||||
}
|
||||
|
||||
fmt.Printf(">> 正在安装 [%s] -> 执行指令: %s\n", pkg, cmdStr)
|
||||
|
||||
execCmd := utils.NewShellCommandCmd(cmdStr)
|
||||
execCmd.Stdout = os.Stdout
|
||||
execCmd.Stderr = os.Stderr
|
||||
execCmd.Stdin = os.Stdin
|
||||
|
||||
runErr := execCmd.Run()
|
||||
if runErr != nil {
|
||||
fmt.Printf(">> 【失败】依赖包 [%s] 安装出错。\n\n", pkg)
|
||||
failedPkgs = append(failedPkgs, pkg)
|
||||
} else {
|
||||
fmt.Printf(">> 【成功】依赖包 [%s] 安装成功!\n\n", pkg)
|
||||
// 成功后记录到依赖表
|
||||
_ = depService.Create(dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("==================================================================")
|
||||
if len(failedPkgs) > 0 {
|
||||
fmt.Printf(">> 依赖补全已结束。其中以下依赖包安装失败,请用户自行判断/手动处理:\n")
|
||||
for _, fp := range failedPkgs {
|
||||
fmt.Printf(" - %s\n", fp)
|
||||
}
|
||||
} else {
|
||||
fmt.Println(">> 恭喜!所有依赖包安装成功!")
|
||||
}
|
||||
fmt.Println("==================================================================")
|
||||
}
|
||||
Reference in New Issue
Block a user