Installer/spm/install.go
partisan 9e5457c2ec
All checks were successful
/ test-on-windows (push) Successful in 9s
/ test-on-alpine (push) Successful in 4s
added SPM
2024-12-25 10:58:31 +01:00

161 lines
3.2 KiB
Go

package spm
import (
"archive/tar"
"compress/gzip"
"io"
"os"
"path/filepath"
)
func DecompressToTemp(filePath string) (string, error) {
UpdateProgress(0, "Decompressing package")
tempDir, err := os.MkdirTemp("", "spm_decompress")
if err != nil {
return "", err
}
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
gzr, err := gzip.NewReader(file)
if err != nil {
return "", err
}
defer gzr.Close()
tarReader := tar.NewReader(gzr)
var totalFiles, processedFiles int
// Count total files
for {
_, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return "", err
}
totalFiles++
}
file.Seek(0, io.SeekStart)
gzr.Reset(file)
tarReader = tar.NewReader(gzr)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return "", err
}
targetPath := filepath.Join(tempDir, header.Name)
switch header.Typeflag {
case tar.TypeDir:
if err := os.MkdirAll(targetPath, os.FileMode(header.Mode)); err != nil {
return "", err
}
case tar.TypeReg:
outFile, err := os.Create(targetPath)
if err != nil {
return "", err
}
if _, err := io.Copy(outFile, tarReader); err != nil {
return "", err
}
outFile.Close()
}
processedFiles++
UpdateProgress(int(float64(processedFiles)/float64(totalFiles)*100), "Decompressing package")
}
UpdateProgress(100, "Package decompressed")
return tempDir, nil
}
func MoveFilesToInstallDir(tempDir, installDir string) error {
// Count total files to copy
var totalFiles, copiedFiles int
err := filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
totalFiles++
}
return nil
})
if err != nil {
return err
}
// Copy files and track progress
err = filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
relPath, err := filepath.Rel(tempDir, path)
if err != nil {
return err
}
targetPath := filepath.Join(installDir, relPath)
if info.IsDir() {
// Create directories in the install directory
if err := os.MkdirAll(targetPath, os.ModePerm); err != nil {
return err
}
} else {
// Copy files to the install directory
if err := copyFile(path, targetPath); err != nil {
return err
}
copiedFiles++
UpdateProgress(int(float64(copiedFiles)/float64(totalFiles)*100), "Copying files to install directory")
}
return nil
})
if err != nil {
return err
}
// Clean up temporary directory
UpdateProgress(100, "Cleaning up temporary files")
return os.RemoveAll(tempDir)
}
// copyFile copies the contents of the source file to the destination file.
func copyFile(src, dst string) error {
sourceFile, err := os.Open(src)
if err != nil {
return err
}
defer sourceFile.Close()
// Create the destination file
destinationFile, err := os.Create(dst)
if err != nil {
return err
}
defer destinationFile.Close()
// Copy the file content
if _, err := io.Copy(destinationFile, sourceFile); err != nil {
return err
}
// Preserve file permissions
info, err := sourceFile.Stat()
if err != nil {
return err
}
return os.Chmod(dst, info.Mode())
}