SPM/dirs.go
2025-02-25 20:15:39 +01:00

144 lines
3.8 KiB
Go

package spm
import (
"fmt"
"math/rand"
"os"
"path/filepath"
"runtime"
"sync"
)
// global sync and variable for generated temp dir
var (
tempDirOnce sync.Once
tempDirPath string
)
// global variables for install dir
var (
installMu sync.Mutex
installedDir string
installEnvVar = "SPITFIRE_INSTALL_DIR"
)
// GetTempDir generates or retrieves a unique temp dir.
func GetTempDir() string {
tempDirOnce.Do(func() {
// Generate a unique temp dir name
tempDirPath = filepath.Join(os.TempDir(), fmt.Sprintf("spm_temp_%d", rand.Intn(1000000)))
// Ensure the dir exists
if err := os.MkdirAll(tempDirPath, os.ModePerm); err != nil {
fmt.Printf("[ERROR] Failed to create temp directory: %v\n", err)
} else {
fmt.Printf("[INFO] Using temp directory: %s\n", tempDirPath)
}
})
return tempDirPath
}
// GetDefaultInstallDir generates the default installation dir
// based on the OS and environment, then also sets it via SetInstallDir.
//
// Please use GetInstallDir() instead of GetDefaultInstallDir() when interacting with spm.
func GetDefaultInstallDir() (string, error) {
var installDir string
switch runtime.GOOS {
case "windows":
// Use C:\Program Files
programFiles := os.Getenv("ProgramFiles")
if programFiles == "" {
return "", fmt.Errorf("unable to determine default install directory on Windows")
}
installDir = filepath.Join(programFiles, "Spitfire")
case "darwin":
// Use ~/Library/Application Support on macOS
homeDir, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("unable to determine home directory on macOS: %w", err)
}
installDir = filepath.Join(homeDir, "Library", "Application Support", "Spitfire")
case "linux":
// Use ~/.local/share/Spitfire on Linux
homeDir, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("unable to determine home directory on Linux: %w", err)
}
installDir = filepath.Join(homeDir, ".local", "share", "Spitfire")
default:
return "", fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
}
// Also store it globally so future calls to GetInstallDir() return the same
SetInstallDir(installDir)
return installDir, nil
}
// SetDownloadFolder ensures customDir exists, returns it
func SetDownloadFolder(customDir string) (string, error) {
if err := os.MkdirAll(customDir, os.ModePerm); err != nil {
return "", err
}
return customDir, nil
}
// SetInstallDir sets the global install dir variable and updates the persistent environment variable.
func SetInstallDir(path string) error {
installMu.Lock()
defer installMu.Unlock()
installedDir = path
// Persist the environment variable on Windows
if runtime.GOOS == "windows" {
err := persistSystemEnvVar(installEnvVar, path)
if err != nil {
return err
}
} else {
// For non-Windows platforms, just set it in the current process environment
err := os.Setenv(installEnvVar, path)
if err != nil {
return err
}
}
return nil
}
// GetInstallDir returns the currently set install dir if available.
// Otherwise, it calls GetDefaultInstallDir() and sets that.
func GetInstallDir() (string, error) {
// If already set, return it
if installedDir != "" {
return installedDir, nil
}
// Check if it's stored in the system environment variable
if envDir := os.Getenv(installEnvVar); envDir != "" {
installedDir = envDir
return installedDir, nil
}
// Compute and store the default dir if not already set
defDir, err := GetDefaultInstallDir()
if err != nil {
return "", err
}
installedDir = defDir
// Persist the default dir as an environment variable on Windows
if runtime.GOOS == "windows" {
_ = persistSystemEnvVar(installEnvVar, defDir)
} else {
_ = os.Setenv(installEnvVar, defDir)
}
return defDir, nil
}