diff --git a/pkg/installer/installer.go b/pkg/installer/installer.go index 3ed708e..02b1827 100644 --- a/pkg/installer/installer.go +++ b/pkg/installer/installer.go @@ -26,10 +26,6 @@ var ( buildInstallDir = filepath.Join(paths.BaseDir(), "installed_packages") ) -func logMessage(msg string) { - fmt.Println(msg) -} - func computeChecksum(filePath string) (string, error) { data, err := ioutil.ReadFile(filePath) if err != nil { @@ -40,7 +36,6 @@ func computeChecksum(filePath string) (string, error) { } func downloadFile(url string) (string, error) { - logMessage("Downloading " + url + "...") resp, err := http.Get(url) if err != nil { return "", err @@ -52,17 +47,17 @@ func downloadFile(url string) (string, error) { } _, err = io.Copy(tmpFile, resp.Body) if err != nil { + tmpFile.Close() return "", err } tmpFile.Close() - logMessage("File downloaded to temporary location") return tmpFile.Name(), nil } func unpackPackage(filePath, packageName string) error { destDir := filepath.Join(buildInstallDir, packageName) - logMessage("Unpacking package into " + destDir) - if err := os.MkdirAll(destDir, os.ModePerm); err != nil { + err := os.MkdirAll(destDir, os.ModePerm) + if err != nil { return err } f, err := os.Open(filePath) @@ -87,7 +82,8 @@ func unpackPackage(filePath, packageName string) error { target := filepath.Join(destDir, header.Name) switch header.Typeflag { case tar.TypeDir: - if err := os.MkdirAll(target, os.FileMode(header.Mode)); err != nil { + err := os.MkdirAll(target, os.FileMode(header.Mode)) + if err != nil { return err } case tar.TypeReg: @@ -95,36 +91,34 @@ func unpackPackage(filePath, packageName string) error { if err != nil { return err } - if _, err := io.Copy(outFile, tr); err != nil { + _, err = io.Copy(outFile, tr) + if err != nil { outFile.Close() return err } outFile.Close() } } - logMessage("Unpacking completed") return nil } func executeBuildCommands(commands []string, packageName string) error { packagePath := filepath.Join(buildInstallDir, packageName) for _, commandStr := range commands { - logMessage("Executing build command: " + commandStr) cmd := exec.Command("sh", "-c", commandStr) cmd.Dir = packagePath output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("command '%s' failed: %s", commandStr, string(output)) } - logMessage("Command output: " + string(output)) } return nil } func saveInstalledPackage(name string, m *manifest.Manifest) error { packagePath := filepath.Join(buildInstallDir, name) - logMessage("Saving manifest to " + packagePath) - if err := os.MkdirAll(packagePath, os.ModePerm); err != nil { + err := os.MkdirAll(packagePath, os.ModePerm) + if err != nil { return err } jsonData, err := json.MarshalIndent(m, "", " ") @@ -135,31 +129,30 @@ func saveInstalledPackage(name string, m *manifest.Manifest) error { } func InstallPackage(name string) error { - logMessage("Fetching manifest for package " + name) m, err := manifest.FetchManifest(name) if err != nil { return fmt.Errorf("failed to fetch manifest: %w", err) } if strings.ToLower(m.Mode) == "bin" { - logMessage("Installing in binary mode") platformKey := runtime.GOOS + "_" + runtime.GOARCH - binaryURL, ok := m.Binaries[platformKey] + binaryInfo, ok := m.Binaries[platformKey] if !ok { return fmt.Errorf("no binary available for platform %s", platformKey) } - packageFile, err := downloadFile(binaryURL) + packageFile, err := downloadFile(binaryInfo.URL) if err != nil { return fmt.Errorf("failed to download binary: %w", err) } defer os.Remove(packageFile) - checksum, err := computeChecksum(packageFile) + computedChecksum, err := computeChecksum(packageFile) if err != nil { return fmt.Errorf("failed to compute checksum: %w", err) } - if checksum != m.Checksum { - return fmt.Errorf("checksum mismatch: expected %s, got %s", m.Checksum, checksum) + if computedChecksum != binaryInfo.Checksum { + return fmt.Errorf("checksum mismatch: expected %s, got %s", binaryInfo.Checksum, computedChecksum) } - if err := os.MkdirAll(binInstallDir, os.ModePerm); err != nil { + err = os.MkdirAll(binInstallDir, os.ModePerm) + if err != nil { return err } destPath := filepath.Join(binInstallDir, m.Name) @@ -167,37 +160,58 @@ func InstallPackage(name string) error { if err != nil { return err } - if err := ioutil.WriteFile(destPath, data, 0755); err != nil { + err = ioutil.WriteFile(destPath, data, 0755) + if err != nil { return err } - logMessage("Binary package " + m.Name + " installed to " + destPath) + fmt.Printf("Binary package %s installed in %s\n", m.Name, destPath) return nil } else if strings.ToLower(m.Mode) == "build" { - logMessage("Installing in build mode") packageFile, err := downloadFile(m.Source) if err != nil { return fmt.Errorf("failed to download package: %w", err) } defer os.Remove(packageFile) - checksum, err := computeChecksum(packageFile) + computedChecksum, err := computeChecksum(packageFile) if err != nil { return fmt.Errorf("failed to compute checksum: %w", err) } - if checksum != m.Checksum { - return fmt.Errorf("checksum mismatch: expected %s, got %s", m.Checksum, checksum) + if computedChecksum != m.Checksum { + return fmt.Errorf("checksum mismatch: expected %s, got %s", m.Checksum, computedChecksum) } - if err := unpackPackage(packageFile, name); err != nil { + err = unpackPackage(packageFile, name) + if err != nil { return fmt.Errorf("failed to unpack package: %w", err) } if len(m.Build) > 0 { - if err := executeBuildCommands(m.Build, name); err != nil { + err = executeBuildCommands(m.Build, name) + if err != nil { return fmt.Errorf("build command error: %w", err) } } - if err := saveInstalledPackage(name, m); err != nil { + err = saveInstalledPackage(name, m) + if err != nil { return fmt.Errorf("failed to save manifest: %w", err) } - logMessage("Build package " + m.Name + " installed successfully") + if name == "choochoo-build" { + destDir := filepath.Join(paths.BaseDir(), "bin") + err = os.MkdirAll(destDir, os.ModePerm) + if err != nil { + return err + } + srcBinary := filepath.Join(buildInstallDir, name, "choochoo") + targetBinary := filepath.Join(destDir, "choochoo") + data, err := ioutil.ReadFile(srcBinary) + if err != nil { + return fmt.Errorf("failed to read built binary: %w", err) + } + err = ioutil.WriteFile(targetBinary, data, 0755) + if err != nil { + return fmt.Errorf("failed to write binary to %s: %w", targetBinary, err) + } + fmt.Printf("Binary choochoo installed in %s\n", targetBinary) + } + fmt.Printf("Build package %s installed successfully\n", m.Name) return nil } return errors.New("unknown package mode") @@ -205,26 +219,25 @@ func InstallPackage(name string) error { func RemovePackage(name string) error { packagePath := filepath.Join(buildInstallDir, name) - logMessage("Removing package " + name + " from " + packagePath) if _, err := os.Stat(packagePath); os.IsNotExist(err) { return errors.New("package not found") } - if err := os.RemoveAll(packagePath); err != nil { + err := os.RemoveAll(packagePath) + if err != nil { return fmt.Errorf("failed to remove package: %w", err) } - logMessage("Package " + name + " removed successfully") return nil } func UpdatePackage(name string) error { - logMessage("Updating package " + name) - if err := RemovePackage(name); err != nil { + err := RemovePackage(name) + if err != nil { return fmt.Errorf("failed to remove package for update: %w", err) } - if err := InstallPackage(name); err != nil { - return fmt.Errorf("failed to install package during update: %w", err) + err = InstallPackage(name) + if err != nil { + return fmt.Errorf("failed to install package: %w", err) } - logMessage("Package " + name + " updated successfully") return nil } diff --git a/pkg/manifest/.DS_Store b/pkg/manifest/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/pkg/manifest/.DS_Store differ diff --git a/pkg/manifest/manifest.go b/pkg/manifest/manifest.go index 107d10f..4977f4a 100644 --- a/pkg/manifest/manifest.go +++ b/pkg/manifest/manifest.go @@ -9,15 +9,20 @@ import ( "train/pkg/config" ) +type BinaryInfo struct { + URL string `json:"url"` + Checksum string `json:"checksum"` +} + type Manifest struct { - Name string `json:"name"` - Version string `json:"version"` - Mode string `json:"mode"` - Source string `json:"source"` - Checksum string `json:"checksum"` - Dependencies []string `json:"dependencies"` - Build []string `json:"build"` - Binaries map[string]string `json:"binaries"` + Name string `json:"name"` + Version string `json:"version"` + Mode string `json:"mode"` + Source string `json:"source"` + Checksum string `json:"checksum"` + Dependencies []string `json:"dependencies"` + Build []string `json:"build"` + Binaries map[string]BinaryInfo `json:"binaries"` } func FetchManifest(name string) (*Manifest, error) {