Compare commits

..

5 commits
v0.1.0 ... main

Author SHA1 Message Date
af129cb59d Update go.mod 2025-03-28 09:33:36 +00:00
b31ea5f3cc Update go.sum 2025-03-28 09:33:17 +00:00
c84170d615 Fix RunAndWait() process detection
Fixed incorrect browser exit detection in RunAndWait() which could lead to Browser file corruption due to incomplete updates.
2025-03-28 09:21:38 +00:00
partisan
f34f335206 Reverted changes bcs of './installer.go:115:13: spm.RegisterApp() (no value) used as value' 2025-03-02 10:09:18 +01:00
partisan
f3a78f4bd6 Fixed error loops 2025-03-02 09:59:00 +01:00
6 changed files with 45 additions and 32 deletions

View file

@ -78,7 +78,6 @@ func main() {
spm.Run() spm.Run()
} }
``` ```
*Functions, and specifically their names, are subject to change as I really don't like "AutoDownloadSpecified," but I don't want to make it "DownloadSpecified" yet, as there are still many functions in SPM used for manual downloads, installs, etc.*
<p align="center" style="font-size: 32px;"> <p align="center" style="font-size: 32px;">
<strong>License</strong> <strong>License</strong>

33
auto.go
View file

@ -196,23 +196,22 @@ func DownloadSpecified(specs []AppIndexEntry) error {
} }
fmt.Printf("[INFO] Found matching APPINDEX entry: %+v\n", *matchingEntry) fmt.Printf("[INFO] Found matching APPINDEX entry: %+v\n", *matchingEntry)
// // Check if an update is needed updateNeeded, err := IsUpdateNeeded(
// updateNeeded, err := IsUpdateNeeded( installDir,
// installDir, matchingEntry.Name,
// matchingEntry.Name, matchingEntry.Release,
// matchingEntry.Release, matchingEntry.Version,
// matchingEntry.Version, matchingEntry.Arch,
// matchingEntry.Arch, matchingEntry.OS,
// matchingEntry.OS, )
// ) if err != nil {
// if err != nil { return fmt.Errorf("[ERROR] Failed to check if update is needed for %s: %w", matchingEntry.Name, err)
// return fmt.Errorf("[ERROR] Failed to check if update is needed for %s: %w", matchingEntry.Name, err) }
// }
// if !updateNeeded { if !updateNeeded {
// fmt.Printf("[INFO] No update needed for package '%s'\n", matchingEntry.Name) fmt.Printf("[INFO] No update needed for package '%s'\n", matchingEntry.Name)
// continue continue
// } }
// 5) Download the package // 5) Download the package
downloadDir := GetTempDir() downloadDir := GetTempDir()
@ -243,7 +242,7 @@ func DownloadSpecified(specs []AppIndexEntry) error {
} }
fmt.Printf("[INFO] Package '%s' decompressed successfully to: %s\n", matchingEntry.Name, tempDir) fmt.Printf("[INFO] Package '%s' decompressed successfully to: %s\n", matchingEntry.Name, tempDir)
// 7) Store in pendingUpdates for InstallUpdates // Add to pendingUpdates for InstallUpdates
fmt.Printf("[INFO] Adding '%s' to pending updates\n", matchingEntry.Name) fmt.Printf("[INFO] Adding '%s' to pending updates\n", matchingEntry.Name)
pendingUpdates = append(pendingUpdates, *matchingEntry) pendingUpdates = append(pendingUpdates, *matchingEntry)
} }

9
go.mod
View file

@ -1,7 +1,12 @@
module weforge.xyz/Spitfire/SPM module weforge.xyz/Spitfire/SPM
go 1.21 go 1.23.0
require gopkg.in/ini.v1 v1.67.0 toolchain go1.24.1
require (
golang.org/x/sys v0.31.0
gopkg.in/ini.v1 v1.67.0
)
require github.com/stretchr/testify v1.10.0 // indirect require github.com/stretchr/testify v1.10.0 // indirect

2
go.sum
View file

@ -4,6 +4,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -12,12 +12,12 @@ import (
// RegisterApp is not supported on non-Windows platforms. // RegisterApp is not supported on non-Windows platforms.
func RegisterApp() error { func RegisterApp() error {
return fmt.Errorf("RegisterApp is only available on Windows") return fmt.Errorf("[WARN] RegisterApp() is only available on Windows")
} }
// UnregisterApp is not supported on non-Windows platforms. // UnregisterApp is not supported on non-Windows platforms.
func UnregisterApp() error { func UnregisterApp() error {
return fmt.Errorf("UnregisterApp is only available on Windows") return fmt.Errorf("[WARN] UnregisterApp() is only available on Windows")
} }
// IsRegistered returns true if the application is detected as installed. // IsRegistered returns true if the application is detected as installed.

View file

@ -9,7 +9,10 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"syscall" "strings"
"time"
"golang.org/x/sys/windows"
) )
// Run locates and starts the installed Spitfire browser without waiting for it to exit. // Run locates and starts the installed Spitfire browser without waiting for it to exit.
@ -33,7 +36,6 @@ func RunAndWait() error {
return fmt.Errorf("failed to get install directory: %w", err) return fmt.Errorf("failed to get install directory: %w", err)
} }
// Construct the browser executable path
exePath := filepath.Join(installDir, "browser", "spitfire.exe") exePath := filepath.Join(installDir, "browser", "spitfire.exe")
if _, err := os.Stat(exePath); err != nil { if _, err := os.Stat(exePath); err != nil {
return fmt.Errorf("browser executable not found at %s: %w", exePath, err) return fmt.Errorf("browser executable not found at %s: %w", exePath, err)
@ -42,23 +44,29 @@ func RunAndWait() error {
cmd := exec.Command(exePath) cmd := exec.Command(exePath)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
cmd.Dir = filepath.Join(installDir, "browser")
// Use CREATE_NEW_PROCESS_GROUP flag for Windows // Create job object starting the process
cmd.SysProcAttr = &syscall.SysProcAttr{ job, err := windows.CreateJobObject(nil, nil)
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP, if err != nil {
return fmt.Errorf("failed to create job object: %w", err)
} }
defer windows.CloseHandle(job)
fmt.Printf("Starting browser: %s\n", exePath) fmt.Printf("Starting browser: %s\n", exePath)
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
return fmt.Errorf("failed to start browser: %w", err) return fmt.Errorf("failed to start browser: %w", err)
} }
fmt.Printf("Browser process started with PID %d\n", cmd.Process.Pid) for {
cmd := exec.Command("tasklist", "/FI", "IMAGENAME eq spitfire.exe")
if err := cmd.Wait(); err != nil { output, _ := cmd.Output()
return fmt.Errorf("browser exited with error: %w", err) if !strings.Contains(string(output), "spitfire.exe") {
break
}
time.Sleep(1 * time.Second)
} }
fmt.Println("Browser exited successfully.") fmt.Println("Browser exited.")
return nil return nil
} }