Files
admin e6956aa001 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
2026-07-26 08:43:52 +08:00

203 lines
5.7 KiB
Go

package deps
import (
"errors"
"os/exec"
"strings"
"github.com/engigu/taskpool/internal/logger"
"github.com/engigu/taskpool/internal/models"
"github.com/engigu/taskpool/internal/utils"
)
// Manager 依赖管理器接口
type Manager interface {
Install(dep *models.Dependency) error
Uninstall(dep *models.Dependency) error
GetInstalledPackages(language, langVersion string) ([]models.Dependency, error)
GetInstallCommand(dep *models.Dependency) (string, error)
GetBatchInstallCommand(deps []models.Dependency) (string, error)
GetReinstallAllCommand(deps []models.Dependency) (string, error)
GetVerifyCommand(langVersion string) (string, error)
}
// BaseManager 基础管理器,提供通用方法
type BaseManager struct {
Language string
InstallCmd []string
UninstallCmd []string
ListCmd []string
VerifyCmd []string
Separator string
}
func (m *BaseManager) runMiseCommand(langVersion string, cmdArgs []string) ([]byte, error) {
args := utils.BuildMiseCommandArgsSimple(cmdArgs, m.Language, langVersion)
cmd := exec.Command(args[0], args[1:]...)
return cmd.CombinedOutput()
}
func (m *BaseManager) Install(dep *models.Dependency) error {
var packageSpec string
if dep.Version != "" {
packageSpec = dep.Name + m.Separator + dep.Version
} else {
packageSpec = dep.Name
}
args := append([]string{}, m.InstallCmd...)
args = append(args, packageSpec)
logger.Infof("Installing %s package: %s", m.Language, packageSpec)
output, err := m.runMiseCommand(dep.LangVersion, args)
dep.Log = models.BigText(output)
if err != nil {
logger.Errorf("Install failed: %v, output: %s", err, string(output))
return errors.New("安装失败: " + string(output))
}
logger.Infof("Install success: %s", packageSpec)
return nil
}
func (m *BaseManager) GetInstallCommand(dep *models.Dependency) (string, error) {
var packageSpec string
if dep.Version != "" {
packageSpec = dep.Name + m.Separator + dep.Version
} else {
packageSpec = dep.Name
}
args := append([]string{}, m.InstallCmd...)
args = append(args, packageSpec)
fullCmd := utils.BuildMiseCommandSimple(strings.Join(args, " "), m.Language, dep.LangVersion)
return fullCmd + " && echo \"__INSTALL_SUCCESS__\" || echo \"__INSTALL_FAILED__\"", nil
}
func (m *BaseManager) GetBatchInstallCommand(deps []models.Dependency) (string, error) {
if len(deps) == 0 {
return "echo \"没有需要安装的依赖\"", nil
}
var packageSpecs []string
var langVersion string
var language string
for _, dep := range deps {
language = dep.Language
if dep.LangVersion != "" {
langVersion = dep.LangVersion
}
if dep.Version != "" {
packageSpecs = append(packageSpecs, dep.Name+m.Separator+dep.Version)
} else {
packageSpecs = append(packageSpecs, dep.Name)
}
}
args := append([]string{}, m.InstallCmd...)
args = append(args, packageSpecs...)
fullCmd := utils.BuildMiseCommandSimple(strings.Join(args, " "), language, langVersion)
return fullCmd + " && echo \"__INSTALL_SUCCESS__\" || echo \"__INSTALL_FAILED__\"", nil
}
func (m *BaseManager) GetReinstallAllCommand(deps []models.Dependency) (string, error) {
if len(deps) == 0 {
return "echo \"没有需要安装的依赖\"", nil
}
var packageSpecs []string
var langVersion string
for _, dep := range deps {
if dep.LangVersion != "" {
langVersion = dep.LangVersion
}
if dep.Version != "" {
packageSpecs = append(packageSpecs, dep.Name+m.Separator+dep.Version)
} else {
packageSpecs = append(packageSpecs, dep.Name)
}
}
args := append([]string{}, m.InstallCmd...)
args = append(args, packageSpecs...)
fullCmd := utils.BuildMiseCommandSimple(strings.Join(args, " "), m.Language, langVersion)
return fullCmd + " && echo \"__INSTALL_SUCCESS__\" || echo \"__INSTALL_FAILED__\"", nil
}
func (m *BaseManager) GetVerifyCommand(langVersion string) (string, error) {
var cmd string
if len(m.VerifyCmd) > 0 {
cmd = strings.Join(m.VerifyCmd, " ")
} else {
cmd = m.Language + " --version"
}
return utils.BuildMiseCommandSimple(cmd, m.Language, langVersion), nil
}
func (m *BaseManager) Uninstall(dep *models.Dependency) error {
args := append([]string{}, m.UninstallCmd...)
args = append(args, dep.Name)
logger.Infof("Uninstalling %s package: %s", m.Language, dep.Name)
output, err := m.runMiseCommand(dep.LangVersion, args)
if err != nil {
logger.Errorf("Uninstall failed: %v, output: %s", err, string(output))
return errors.New("卸载失败: " + string(output))
}
return nil
}
// GetManager 根据语言获取对应的管理器
func GetManager(language string) Manager {
lang := strings.ToLower(language)
if strings.Contains(lang, "python") {
return NewPythonManager(language)
}
if strings.Contains(lang, "node") {
return NewNodeManager(language)
}
if strings.Contains(lang, "ruby") {
return NewRubyManager(language)
}
if strings.Contains(lang, "go") {
return NewGoManager(language)
}
if strings.Contains(lang, "rust") {
return NewRustManager(language)
}
if strings.Contains(lang, "bun") {
return NewBunManager(language)
}
if strings.Contains(lang, "php") {
return NewPhpManager(language)
}
if strings.Contains(lang, "deno") {
return NewDenoManager(language)
}
if strings.Contains(lang, "dotnet") {
return NewDotnetManager(language)
}
if strings.Contains(lang, "elixir") || strings.Contains(lang, "erlang") {
return NewElixirManager(language)
}
if strings.Contains(lang, "lua") {
return NewLuaManager(language)
}
if strings.Contains(lang, "nim") {
return NewNimManager(language)
}
if strings.Contains(lang, "dart") || strings.Contains(lang, "flutter") {
return NewDartManager(language)
}
if strings.Contains(lang, "perl") {
return NewPerlManager(language)
}
if strings.Contains(lang, "crystal") {
return NewCrystalManager(language)
}
return nil
}