This commit is contained in:
wheelchairy 2025-02-04 18:57:51 +03:00
parent b4f0aa3fb4
commit ca822b5f38
2 changed files with 38 additions and 23 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
installed* installed*
repo repo
train train
pkg/*/*.save

View File

@ -17,7 +17,6 @@ import (
"runtime" "runtime"
"strings" "strings"
// "train/pkg/config"
"train/pkg/manifest" "train/pkg/manifest"
"train/pkg/paths" "train/pkg/paths"
) )
@ -27,6 +26,10 @@ var (
buildInstallDir = filepath.Join(paths.BaseDir(), "installed_packages") buildInstallDir = filepath.Join(paths.BaseDir(), "installed_packages")
) )
func logMessage(msg string) {
fmt.Println(msg)
}
func computeChecksum(filePath string) (string, error) { func computeChecksum(filePath string) (string, error) {
data, err := ioutil.ReadFile(filePath) data, err := ioutil.ReadFile(filePath)
if err != nil { if err != nil {
@ -37,6 +40,7 @@ func computeChecksum(filePath string) (string, error) {
} }
func downloadFile(url string) (string, error) { func downloadFile(url string) (string, error) {
logMessage("Downloading " + url + "...")
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return "", err return "", err
@ -51,11 +55,13 @@ func downloadFile(url string) (string, error) {
return "", err return "", err
} }
tmpFile.Close() tmpFile.Close()
logMessage("File downloaded to temporary location")
return tmpFile.Name(), nil return tmpFile.Name(), nil
} }
func unpackPackage(filePath, packageName string) error { func unpackPackage(filePath, packageName string) error {
destDir := filepath.Join(buildInstallDir, packageName) destDir := filepath.Join(buildInstallDir, packageName)
logMessage("Unpacking package into " + destDir)
if err := os.MkdirAll(destDir, os.ModePerm); err != nil { if err := os.MkdirAll(destDir, os.ModePerm); err != nil {
return err return err
} }
@ -96,24 +102,28 @@ func unpackPackage(filePath, packageName string) error {
outFile.Close() outFile.Close()
} }
} }
logMessage("Unpacking completed")
return nil return nil
} }
func executeBuildCommands(commands []string, packageName string) error { func executeBuildCommands(commands []string, packageName string) error {
packagePath := filepath.Join(buildInstallDir, packageName) packagePath := filepath.Join(buildInstallDir, packageName)
for _, commandStr := range commands { for _, commandStr := range commands {
logMessage("Executing build command: " + commandStr)
cmd := exec.Command("sh", "-c", commandStr) cmd := exec.Command("sh", "-c", commandStr)
cmd.Dir = packagePath cmd.Dir = packagePath
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return fmt.Errorf("команда '%s' завершилась с ошибкой: %s", commandStr, string(output)) return fmt.Errorf("command '%s' failed: %s", commandStr, string(output))
} }
logMessage("Command output: " + string(output))
} }
return nil return nil
} }
func saveInstalledPackage(name string, m *manifest.Manifest) error { func saveInstalledPackage(name string, m *manifest.Manifest) error {
packagePath := filepath.Join(buildInstallDir, name) packagePath := filepath.Join(buildInstallDir, name)
logMessage("Saving manifest to " + packagePath)
if err := os.MkdirAll(packagePath, os.ModePerm); err != nil { if err := os.MkdirAll(packagePath, os.ModePerm); err != nil {
return err return err
} }
@ -124,31 +134,30 @@ func saveInstalledPackage(name string, m *manifest.Manifest) error {
return ioutil.WriteFile(filepath.Join(packagePath, "manifest.json"), jsonData, 0644) return ioutil.WriteFile(filepath.Join(packagePath, "manifest.json"), jsonData, 0644)
} }
func removeInstalledPackageRecord(name string) {
}
func InstallPackage(name string) error { func InstallPackage(name string) error {
logMessage("Fetching manifest for package " + name)
m, err := manifest.FetchManifest(name) m, err := manifest.FetchManifest(name)
if err != nil { if err != nil {
return fmt.Errorf("не удалось получить манифест: %w", err) return fmt.Errorf("failed to fetch manifest: %w", err)
} }
if strings.ToLower(m.Mode) == "bin" { if strings.ToLower(m.Mode) == "bin" {
logMessage("Installing in binary mode")
platformKey := runtime.GOOS + "_" + runtime.GOARCH platformKey := runtime.GOOS + "_" + runtime.GOARCH
binaryURL, ok := m.Binaries[platformKey] binaryURL, ok := m.Binaries[platformKey]
if !ok { if !ok {
return fmt.Errorf("нет бинарного файла для платформы %s", platformKey) return fmt.Errorf("no binary available for platform %s", platformKey)
} }
packageFile, err := downloadFile(binaryURL) packageFile, err := downloadFile(binaryURL)
if err != nil { if err != nil {
return fmt.Errorf("не удалось скачать бинарник: %w", err) return fmt.Errorf("failed to download binary: %w", err)
} }
defer os.Remove(packageFile) defer os.Remove(packageFile)
checksum, err := computeChecksum(packageFile) checksum, err := computeChecksum(packageFile)
if err != nil { if err != nil {
return fmt.Errorf("не удалось вычислить контрольную сумму: %w", err) return fmt.Errorf("failed to compute checksum: %w", err)
} }
if checksum != m.Checksum { if checksum != m.Checksum {
return fmt.Errorf("контрольная сумма не совпадает, ожидалось %s, получено %s", m.Checksum, checksum) return fmt.Errorf("checksum mismatch: expected %s, got %s", m.Checksum, checksum)
} }
if err := os.MkdirAll(binInstallDir, os.ModePerm); err != nil { if err := os.MkdirAll(binInstallDir, os.ModePerm); err != nil {
return err return err
@ -161,56 +170,61 @@ func InstallPackage(name string) error {
if err := ioutil.WriteFile(destPath, data, 0755); err != nil { if err := ioutil.WriteFile(destPath, data, 0755); err != nil {
return err return err
} }
fmt.Printf("Бинарный пакет %s установлен в %s\n", m.Name, destPath) logMessage("Binary package " + m.Name + " installed to " + destPath)
return nil return nil
} else if strings.ToLower(m.Mode) == "build" { } else if strings.ToLower(m.Mode) == "build" {
logMessage("Installing in build mode")
packageFile, err := downloadFile(m.Source) packageFile, err := downloadFile(m.Source)
if err != nil { if err != nil {
return fmt.Errorf("не удалось скачать пакет: %w", err) return fmt.Errorf("failed to download package: %w", err)
} }
defer os.Remove(packageFile) defer os.Remove(packageFile)
checksum, err := computeChecksum(packageFile) checksum, err := computeChecksum(packageFile)
if err != nil { if err != nil {
return fmt.Errorf("не удалось вычислить контрольную сумму: %w", err) return fmt.Errorf("failed to compute checksum: %w", err)
} }
if checksum != m.Checksum { if checksum != m.Checksum {
return fmt.Errorf("контрольная сумма не совпадает, ожидалось %s, получено %s", m.Checksum, checksum) return fmt.Errorf("checksum mismatch: expected %s, got %s", m.Checksum, checksum)
} }
if err := unpackPackage(packageFile, name); err != nil { if err := unpackPackage(packageFile, name); err != nil {
return fmt.Errorf("не удалось распаковать пакет: %w", err) return fmt.Errorf("failed to unpack package: %w", err)
} }
if len(m.Build) > 0 { if len(m.Build) > 0 {
if err := executeBuildCommands(m.Build, name); err != nil { if err := executeBuildCommands(m.Build, name); err != nil {
return fmt.Errorf("ошибка выполнения команд сборки: %w", err) return fmt.Errorf("build command error: %w", err)
} }
} }
if err := saveInstalledPackage(name, m); err != nil { if err := saveInstalledPackage(name, m); err != nil {
return fmt.Errorf("не удалось сохранить информацию об установленном пакете: %w", err) return fmt.Errorf("failed to save manifest: %w", err)
} }
logMessage("Build package " + m.Name + " installed successfully")
return nil return nil
} }
return errors.New("неизвестный режим пакета") return errors.New("unknown package mode")
} }
func RemovePackage(name string) error { func RemovePackage(name string) error {
packagePath := filepath.Join(buildInstallDir, name) packagePath := filepath.Join(buildInstallDir, name)
logMessage("Removing package " + name + " from " + packagePath)
if _, err := os.Stat(packagePath); os.IsNotExist(err) { if _, err := os.Stat(packagePath); os.IsNotExist(err) {
return errors.New("пакет не найден") return errors.New("package not found")
} }
if err := os.RemoveAll(packagePath); err != nil { if err := os.RemoveAll(packagePath); err != nil {
return fmt.Errorf("не удалось удалить пакет: %w", err) return fmt.Errorf("failed to remove package: %w", err)
} }
removeInstalledPackageRecord(name) logMessage("Package " + name + " removed successfully")
return nil return nil
} }
func UpdatePackage(name string) error { func UpdatePackage(name string) error {
logMessage("Updating package " + name)
if err := RemovePackage(name); err != nil { if err := RemovePackage(name); err != nil {
return fmt.Errorf("не удалось удалить пакет для обновления: %w", err) return fmt.Errorf("failed to remove package for update: %w", err)
} }
if err := InstallPackage(name); err != nil { if err := InstallPackage(name); err != nil {
return fmt.Errorf("не удалось установить пакет: %w", err) return fmt.Errorf("failed to install package during update: %w", err)
} }
logMessage("Package " + name + " updated successfully")
return nil return nil
} }