Improve logging #2
							
								
								
									
										19
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								main.go
									
									
									
									
									
								
							| @@ -1,21 +1,16 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"epochsilicon/pkg/service" | ||||
| 	"epochsilicon/pkg/ui" | ||||
| 	"epochsilicon/pkg/utils" | ||||
| 	"fyne.io/fyne/v2" | ||||
| 	"fyne.io/fyne/v2/app" | ||||
| 	"github.com/rs/zerolog" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| const appVersion = "1.0.0" | ||||
|  | ||||
| func init() { | ||||
| 	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix | ||||
| } | ||||
| const appVersion = "1.0.1" | ||||
|  | ||||
| func main() { | ||||
| 	PEApp := app.NewWithID("com.burkey.epochsilicon") | ||||
| @@ -27,21 +22,21 @@ func main() { | ||||
| 		prefs, _ := utils.LoadPrefs() | ||||
| 		updateInfo, updateAvailable, err := utils.CheckForUpdateWithAssets(appVersion) | ||||
| 		if err != nil { | ||||
| 			log.Debug().Msgf("Failed to check for updates: %v", err) | ||||
| 			log.Debugf("Failed to check for updates: %v", err) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if !updateAvailable { | ||||
| 			log.Debug().Msgf("No updates available") | ||||
| 			log.Debugf("No updates available") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		latestVersion := strings.TrimPrefix(updateInfo.TagName, "v") | ||||
| 		log.Debug().Msgf("Update available: current=%s, latest=%s", appVersion, latestVersion) | ||||
| 		log.Debugf("Update available: current=%s, latest=%s", appVersion, latestVersion) | ||||
|  | ||||
| 		// Skip if user has suppressed this version | ||||
| 		if prefs.SuppressedUpdateVersion == latestVersion { | ||||
| 			log.Debug().Msgf("Update suppressed by user: %s", latestVersion) | ||||
| 			log.Debugf("Update suppressed by user: %s", latestVersion) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| @@ -54,7 +49,7 @@ func main() { | ||||
|  | ||||
| 	// Set up cleanup when window closes | ||||
| 	PEWindow.SetCloseIntercept(func() { | ||||
| 		log.Debug().Msg("Application closing, cleaning up RosettaX87 service...") | ||||
| 		log.Debug("Application closing, cleaning up RosettaX87 service...") | ||||
| 		service.CleanupService() | ||||
| 		PEApp.Quit() | ||||
| 	}) | ||||
|   | ||||
| @@ -41,7 +41,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { | ||||
|  | ||||
| 	// Parse the shell command to extract components | ||||
| 	// The shellCmd format is: cd <path> && <envVars> <rosettaExec> <wineloader> <wowExe> | ||||
| 	log.Debug().Msgf("Parsing shell command: %s", shellCmd) | ||||
| 	log.Debugf("Parsing shell command: %s", shellCmd) | ||||
|  | ||||
| 	// Create the command without context cancellation | ||||
| 	cmd := exec.Command("sh", "-c", shellCmd) | ||||
| @@ -71,7 +71,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { | ||||
| 		scanner := bufio.NewScanner(stdout) | ||||
| 		for scanner.Scan() { | ||||
| 			line := scanner.Text() | ||||
| 			log.Debug().Msgf("GAME STDOUT: %s", line) | ||||
| 			log.Debugf("GAME STDOUT: %s", line) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| @@ -79,7 +79,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { | ||||
| 		scanner := bufio.NewScanner(stderr) | ||||
| 		for scanner.Scan() { | ||||
| 			line := scanner.Text() | ||||
| 			log.Debug().Msgf("GAME STDERR: %s", line) | ||||
| 			log.Debugf("GAME STDERR: %s", line) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| @@ -93,9 +93,9 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { | ||||
| 		}() | ||||
|  | ||||
| 		if err := cmd.Wait(); err != nil { | ||||
| 			log.Debug().Msgf("Game process ended with error: %v", err) | ||||
| 			log.Debugf("Game process ended with error: %v", err) | ||||
| 		} else { | ||||
| 			log.Debug().Msg("Game process ended successfully") | ||||
| 			log.Debug("Game process ended successfully") | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| @@ -103,7 +103,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { | ||||
| } | ||||
|  | ||||
| func LaunchGame(myWindow fyne.Window) { | ||||
| 	log.Debug().Msg("Launch Game button clicked") | ||||
| 	log.Debug("Launch Game button clicked") | ||||
|  | ||||
| 	if paths.CrossoverPath == "" { | ||||
| 		dialog.ShowError(fmt.Errorf("CrossOver path not set. Please set it in the patcher."), myWindow) | ||||
| @@ -132,7 +132,7 @@ func LaunchGame(myWindow fyne.Window) { | ||||
| 	} | ||||
| 	gameMutex.Unlock() | ||||
|  | ||||
| 	log.Debug().Msg("Preparing to launch EpochSilicon...") | ||||
| 	log.Debug("Preparing to launch EpochSilicon...") | ||||
|  | ||||
| 	wowExePath := filepath.Join(paths.EpochPath, "Project-Epoch.exe") | ||||
|  | ||||
| @@ -163,20 +163,20 @@ func continueLaunch(myWindow fyne.Window, wowExePath string) { | ||||
| 	if AutoDeleteWdb { | ||||
| 		wdbPath := filepath.Join(paths.EpochPath, "WDB") | ||||
| 		if utils.DirExists(wdbPath) { | ||||
| 			log.Debug().Msgf("Auto-deleting WDB directory: %s", wdbPath) | ||||
| 			log.Debugf("Auto-deleting WDB directory: %s", wdbPath) | ||||
| 			if err := os.RemoveAll(wdbPath); err != nil { | ||||
| 				log.Debug().Msgf("Warning: failed to auto-delete WDB directory: %v", err) | ||||
| 				log.Debugf("Warning: failed to auto-delete WDB directory: %v", err) | ||||
| 				// Don't block the launch, just log the error | ||||
| 			} else { | ||||
| 				log.Debug().Msgf("Successfully auto-deleted WDB directory") | ||||
| 				log.Debugf("Successfully auto-deleted WDB directory") | ||||
| 			} | ||||
| 		} else { | ||||
| 			log.Debug().Msgf("WDB directory not found, nothing to delete") | ||||
| 			log.Debugf("WDB directory not found, nothing to delete") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Since RosettaX87 service is already running, we can directly launch WoW | ||||
| 	log.Debug().Msg("RosettaX87 service is running. Proceeding to launch WoW.") | ||||
| 	log.Debug("RosettaX87 service is running. Proceeding to launch WoW.") | ||||
|  | ||||
| 	if paths.CrossoverPath == "" || paths.EpochPath == "" { | ||||
| 		dialog.ShowError(fmt.Errorf("CrossOver path or Epoch path is not set. Cannot launch WoW."), myWindow) | ||||
| @@ -209,21 +209,21 @@ func continueLaunch(myWindow fyne.Window, wowExePath string) { | ||||
| 		escapedShellCmd := utils.EscapeStringForAppleScript(shellCmd) | ||||
| 		cmd2Script := fmt.Sprintf("tell application \"Terminal\" to do script \"%s\"", escapedShellCmd) | ||||
|  | ||||
| 		log.Debug().Msg("Executing WoW launch command via AppleScript...") | ||||
| 		log.Debug("Executing WoW launch command via AppleScript...") | ||||
| 		if !utils.RunOsascript(cmd2Script, myWindow) { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		log.Debug().Msg("Launch command executed. Check the new terminal window.") | ||||
| 		log.Debug("Launch command executed. Check the new terminal window.") | ||||
| 	} else { | ||||
| 		// Use integrated terminal | ||||
| 		log.Debug().Msgf("Shell command for integrated terminal: %s", shellCmd) | ||||
| 		log.Debug().Msg("Executing WoW launch command with integrated terminal...") | ||||
| 		log.Debugf("Shell command for integrated terminal: %s", shellCmd) | ||||
| 		log.Debug("Executing WoW launch command with integrated terminal...") | ||||
| 		if err := runGameIntegrated(myWindow, shellCmd); err != nil { | ||||
| 			dialog.ShowError(fmt.Errorf("failed to launch game: %v", err), myWindow) | ||||
| 			return | ||||
| 		} | ||||
| 		log.Debug().Msg("Game launched with integrated terminal. Check the application logs for output.") | ||||
| 		log.Debug("Game launched with integrated terminal. Check the application logs for output.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -25,20 +25,20 @@ var RecommendedSettings = map[string]string{ | ||||
| // Returns true if all settings are correctly applied, false otherwise | ||||
| func CheckRecommendedSettings() bool { | ||||
| 	if paths.EpochPath == "" { | ||||
| 		log.Debug().Msgf("Epoch path not set, cannot check Config.wtf") | ||||
| 		log.Debugf("Epoch path not set, cannot check Config.wtf") | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	configPath := filepath.Join(paths.EpochPath, "WTF", "Config.wtf") | ||||
|  | ||||
| 	if _, err := os.Stat(configPath); os.IsNotExist(err) { | ||||
| 		log.Debug().Msgf("Config.wtf not found at %s", configPath) | ||||
| 		log.Debugf("Config.wtf not found at %s", configPath) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	content, err := os.ReadFile(configPath) | ||||
| 	if err != nil { | ||||
| 		log.Debug().Msgf("Failed to read Config.wtf: %v", err) | ||||
| 		log.Debugf("Failed to read Config.wtf: %v", err) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| @@ -47,12 +47,12 @@ func CheckRecommendedSettings() bool { | ||||
| 	// Check each recommended setting | ||||
| 	for setting, expectedValue := range RecommendedSettings { | ||||
| 		if !isSettingCorrect(configText, setting, expectedValue) { | ||||
| 			log.Debug().Msgf("Setting %s not found or incorrect in Config.wtf", setting) | ||||
| 			log.Debugf("Setting %s not found or incorrect in Config.wtf", setting) | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("All recommended settings are correctly applied") | ||||
| 	log.Debugf("All recommended settings are correctly applied") | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| @@ -91,7 +91,7 @@ func ApplyRecommendedSettings() error { | ||||
| 	if content, err := os.ReadFile(configPath); err == nil { | ||||
| 		configText = string(content) | ||||
| 	} else { | ||||
| 		log.Debug().Msgf("Config.wtf not found, creating new file") | ||||
| 		log.Debugf("Config.wtf not found, creating new file") | ||||
| 		configText = "" | ||||
| 	} | ||||
|  | ||||
| @@ -105,7 +105,7 @@ func ApplyRecommendedSettings() error { | ||||
| 		return fmt.Errorf("failed to write Config.wtf: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Successfully applied recommended settings to Config.wtf") | ||||
| 	log.Debugf("Successfully applied recommended settings to Config.wtf") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -120,14 +120,14 @@ func updateOrAddSetting(configText, setting, value string) string { | ||||
| 	if re.MatchString(configText) { | ||||
| 		// Replace existing setting | ||||
| 		configText = re.ReplaceAllString(configText, newSetting) | ||||
| 		log.Debug().Msgf("Updated setting %s to %s", setting, value) | ||||
| 		log.Debugf("Updated setting %s to %s", setting, value) | ||||
| 	} else { | ||||
| 		// Add new setting | ||||
| 		if configText != "" && !strings.HasSuffix(configText, "\n") { | ||||
| 			configText += "\n" | ||||
| 		} | ||||
| 		configText += newSetting + "\n" | ||||
| 		log.Debug().Msgf("Added new setting %s with value %s", setting, value) | ||||
| 		log.Debugf("Added new setting %s with value %s", setting, value) | ||||
| 	} | ||||
|  | ||||
| 	return configText | ||||
|   | ||||
							
								
								
									
										62
									
								
								pkg/log/logging.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								pkg/log/logging.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| package log | ||||
|  | ||||
| import ( | ||||
| 	"github.com/rs/zerolog" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| var logger zerolog.Logger | ||||
|  | ||||
| func init() { | ||||
| 	zerolog.TimeFieldFormat = zerolog.TimeFormatUnix | ||||
| 	zerolog.SetGlobalLevel(zerolog.InfoLevel) | ||||
| 	logger = zerolog.New(os.Stdout).With().Timestamp().Logger() | ||||
| } | ||||
|  | ||||
| func Debug(msg string) { | ||||
| 	logger.Debug().Msg(msg) | ||||
| } | ||||
|  | ||||
| func Debugf(format string, args ...interface{}) { | ||||
| 	logger.Debug().Msgf(format, args...) | ||||
| } | ||||
|  | ||||
| func Info(msg string) { | ||||
| 	logger.Info().Msg(msg) | ||||
| } | ||||
|  | ||||
| func Infof(format string, args ...interface{}) { | ||||
| 	logger.Info().Msgf(format, args...) | ||||
| } | ||||
|  | ||||
| func Warn(msg string) { | ||||
| 	logger.Warn().Msg(msg) | ||||
| } | ||||
|  | ||||
| func Warnf(format string, args ...interface{}) { | ||||
| 	logger.Warn().Msgf(format, args...) | ||||
| } | ||||
|  | ||||
| func Error(msg string) { | ||||
| 	logger.Error().Msg(msg) | ||||
| } | ||||
|  | ||||
| func Errorf(format string, args ...interface{}) { | ||||
| 	logger.Error().Msgf(format, args...) | ||||
| } | ||||
|  | ||||
| func Fatal(msg string) { | ||||
| 	logger.Fatal().Msg(msg) | ||||
| } | ||||
|  | ||||
| func Fatalf(format string, args ...interface{}) { | ||||
| 	logger.Fatal().Msgf(format, args...) | ||||
| } | ||||
|  | ||||
| func Panic(msg string) { | ||||
| 	logger.Panic().Msg(msg) | ||||
| } | ||||
|  | ||||
| func Panicf(format string, args ...interface{}) { | ||||
| 	logger.Panic().Msgf(format, args...) | ||||
| } | ||||
| @@ -2,10 +2,10 @@ package patching | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"git.burkey.co/eburk/epochcli/pkg/epoch" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| @@ -21,7 +21,7 @@ import ( | ||||
| ) | ||||
|  | ||||
| func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	log.Debug().Msg("Patch Epoch clicked") | ||||
| 	log.Debug("Patch Epoch clicked") | ||||
| 	if paths.EpochPath == "" { | ||||
| 		dialog.ShowError(fmt.Errorf("Epoch path not set. Please set it first."), myWindow) | ||||
| 		return | ||||
| @@ -37,25 +37,25 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	} | ||||
|  | ||||
| 	for resourceName, destPath := range filesToCopy { | ||||
| 		log.Debug().Msgf("Processing resource: %s to %s", resourceName, destPath) | ||||
| 		log.Debugf("Processing resource: %s to %s", resourceName, destPath) | ||||
|  | ||||
| 		// Check if file already exists and has correct size | ||||
| 		if utils.PathExists(destPath) && utils.CompareFileWithBundledResource(destPath, resourceName) { | ||||
| 			log.Debug().Msgf("File %s already exists with correct size, skipping copy", destPath) | ||||
| 			log.Debugf("File %s already exists with correct size, skipping copy", destPath) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if utils.PathExists(destPath) { | ||||
| 			log.Debug().Msgf("File %s exists but has incorrect size, updating...", destPath) | ||||
| 			log.Debugf("File %s exists but has incorrect size, updating...", destPath) | ||||
| 		} else { | ||||
| 			log.Debug().Msgf("File %s does not exist, creating...", destPath) | ||||
| 			log.Debugf("File %s does not exist, creating...", destPath) | ||||
| 		} | ||||
|  | ||||
| 		resource, err := fyne.LoadResourceFromPath(resourceName) | ||||
| 		if err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to open bundled resource %s: %v", resourceName, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 			paths.PatchesAppliedEpoch = false | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| @@ -65,7 +65,7 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		if err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to create destination file %s: %v", destPath, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 			paths.PatchesAppliedEpoch = false | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| @@ -76,22 +76,22 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		if err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to copy bundled resource %s to %s: %v", resourceName, destPath, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 			paths.PatchesAppliedEpoch = false | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| 		} | ||||
| 		log.Debug().Msgf("Successfully copied %s to %s", resourceName, destPath) | ||||
| 		log.Debugf("Successfully copied %s to %s", resourceName, destPath) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Preparing rosettax87 directory at: %s", targetRosettaX87Dir) | ||||
| 	log.Debugf("Preparing rosettax87 directory at: %s", targetRosettaX87Dir) | ||||
| 	if err := os.RemoveAll(targetRosettaX87Dir); err != nil { | ||||
| 		log.Debug().Msgf("Warning: could not remove existing rosettax87 folder '%s': %v", targetRosettaX87Dir, err) | ||||
| 		log.Debugf("Warning: could not remove existing rosettax87 folder '%s': %v", targetRosettaX87Dir, err) | ||||
| 	} | ||||
| 	if err := os.MkdirAll(targetRosettaX87Dir, 0755); err != nil { | ||||
| 		errMsg := fmt.Sprintf("failed to create directory %s: %v", targetRosettaX87Dir, err) | ||||
| 		dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 		log.Debug().Msg(errMsg) | ||||
| 		log.Debug(errMsg) | ||||
| 		paths.PatchesAppliedEpoch = false | ||||
| 		updateAllStatuses() | ||||
| 		return | ||||
| @@ -103,12 +103,12 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	} | ||||
|  | ||||
| 	for resourceName, destPath := range rosettaFilesToCopy { | ||||
| 		log.Debug().Msgf("Processing rosetta resource: %s to %s", resourceName, destPath) | ||||
| 		log.Debugf("Processing rosetta resource: %s to %s", resourceName, destPath) | ||||
| 		resource, err := fyne.LoadResourceFromPath(resourceName) | ||||
| 		if err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to open bundled resource %s: %v", resourceName, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 			paths.PatchesAppliedEpoch = false | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| @@ -118,7 +118,7 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		if err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to create destination file %s: %v", destPath, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 			paths.PatchesAppliedEpoch = false | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| @@ -129,7 +129,7 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 			destinationFile.Close() | ||||
| 			errMsg := fmt.Sprintf("failed to copy bundled resource %s to %s: %v", resourceName, destPath, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 			paths.PatchesAppliedEpoch = false | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| @@ -137,31 +137,31 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		destinationFile.Close() | ||||
|  | ||||
| 		if filepath.Base(destPath) == "rosettax87" { | ||||
| 			log.Debug().Msgf("Setting execute permission for %s", destPath) | ||||
| 			log.Debugf("Setting execute permission for %s", destPath) | ||||
| 			if err := os.Chmod(destPath, 0755); err != nil { | ||||
| 				errMsg := fmt.Sprintf("failed to set execute permission for %s: %v", destPath, err) | ||||
| 				dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 				log.Debug().Msg(errMsg) | ||||
| 				log.Debug(errMsg) | ||||
| 				paths.PatchesAppliedEpoch = false | ||||
| 				updateAllStatuses() | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 		log.Debug().Msgf("Successfully copied %s to %s", resourceName, destPath) | ||||
| 		log.Debugf("Successfully copied %s to %s", resourceName, destPath) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Checking dlls.txt file at: %s", dllsTextFile) | ||||
| 	log.Debugf("Checking dlls.txt file at: %s", dllsTextFile) | ||||
| 	winerosettaEntry := "winerosetta.dll" | ||||
| 	needsWinerosettaUpdate := true | ||||
|  | ||||
| 	if fileContentBytes, err := os.ReadFile(dllsTextFile); err == nil { | ||||
| 		fileContent := string(fileContentBytes) | ||||
| 		if strings.Contains(fileContent, winerosettaEntry) { | ||||
| 			log.Debug().Msgf("dlls.txt already contains %s", winerosettaEntry) | ||||
| 			log.Debugf("dlls.txt already contains %s", winerosettaEntry) | ||||
| 			needsWinerosettaUpdate = false | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Debug().Msgf("dlls.txt not found, will create a new one") | ||||
| 		log.Debugf("dlls.txt not found, will create a new one") | ||||
| 	} | ||||
|  | ||||
| 	if needsWinerosettaUpdate { | ||||
| @@ -172,7 +172,7 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 			if err != nil { | ||||
| 				errMsg := fmt.Sprintf("failed to read dlls.txt for update: %v", err) | ||||
| 				dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 				log.Debug().Msg(errMsg) | ||||
| 				log.Debug(errMsg) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -186,20 +186,20 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		if needsWinerosettaUpdate { | ||||
| 			if !strings.Contains(updatedContent, winerosettaEntry+"\n") { | ||||
| 				updatedContent += winerosettaEntry + "\n" | ||||
| 				log.Debug().Msgf("Adding %s to dlls.txt", winerosettaEntry) | ||||
| 				log.Debugf("Adding %s to dlls.txt", winerosettaEntry) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err := os.WriteFile(dllsTextFile, []byte(updatedContent), 0644); err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to update dlls.txt: %v", err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 		} else { | ||||
| 			log.Debug().Msgf("Successfully updated dlls.txt") | ||||
| 			log.Debugf("Successfully updated dlls.txt") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msg("Downloading updates from Project Epoch servers.") | ||||
| 	log.Debug("Downloading updates from Project Epoch servers.") | ||||
|  | ||||
| 	// TODO: Change from dialog to pulsing animation | ||||
| 	dialog.ShowInformation("Downloading patches", "Downloading patches for Project Epoch, this will take some time. Please wait until the status changes to \"Patched\"", myWindow) | ||||
| @@ -212,10 +212,10 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 				dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			}) | ||||
| 			paths.DownloadingPatches = false | ||||
| 			log.Error().Msg(errMsg) | ||||
| 			log.Error(errMsg) | ||||
| 		} | ||||
| 		log.Info().Msgf("Successfully updated %d Epoch files", stats.Updated) | ||||
| 		log.Debug().Msg("Epoch patching with bundled resources completed successfully.") | ||||
| 		log.Infof("Successfully updated %d Epoch files", stats.Updated) | ||||
| 		log.Debug("Epoch patching with bundled resources completed successfully.") | ||||
| 		fyne.Do(func() { | ||||
| 			dialog.ShowInformation("Success", "Epoch patching process completed.", myWindow) | ||||
| 		}) | ||||
| @@ -228,7 +228,7 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| } | ||||
|  | ||||
| func PatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	log.Debug().Msg("Patch CrossOver clicked") | ||||
| 	log.Debug("Patch CrossOver clicked") | ||||
| 	if paths.CrossoverPath == "" { | ||||
| 		dialog.ShowError(fmt.Errorf("CrossOver path not set. Please set it first."), myWindow) | ||||
| 		return | ||||
| @@ -245,7 +245,7 @@ func PatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Copying %s to %s", wineloaderOrig, wineloaderCopy) | ||||
| 	log.Debugf("Copying %s to %s", wineloaderOrig, wineloaderCopy) | ||||
| 	if err := utils.CopyFile(wineloaderOrig, wineloaderCopy); err != nil { | ||||
| 		errMsg := fmt.Sprintf("failed to copy wineloader: %v", err) | ||||
| 		if strings.Contains(err.Error(), "operation not permitted") { | ||||
| @@ -257,40 +257,40 @@ func PatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Executing: codesign --remove-signature %s", wineloaderCopy) | ||||
| 	log.Debugf("Executing: codesign --remove-signature %s", wineloaderCopy) | ||||
| 	cmd := exec.Command("codesign", "--remove-signature", wineloaderCopy) | ||||
| 	combinedOutput, err := cmd.CombinedOutput() | ||||
| 	if err != nil { | ||||
| 		derrMsg := fmt.Sprintf("failed to remove signature from %s: %v\nOutput: %s", wineloaderCopy, err, string(combinedOutput)) | ||||
| 		dialog.ShowError(errors.New(derrMsg), myWindow) | ||||
| 		log.Debug().Msg(derrMsg) | ||||
| 		log.Debug(derrMsg) | ||||
| 		paths.PatchesAppliedCrossOver = false | ||||
| 		if err := os.Remove(wineloaderCopy); err != nil { | ||||
| 			log.Debug().Msgf("Warning: failed to cleanup wineloader2 after codesign failure: %v", err) | ||||
| 			log.Debugf("Warning: failed to cleanup wineloader2 after codesign failure: %v", err) | ||||
| 		} | ||||
| 		updateAllStatuses() | ||||
| 		return | ||||
| 	} | ||||
| 	log.Debug().Msgf("codesign output: %s", string(combinedOutput)) | ||||
| 	log.Debugf("codesign output: %s", string(combinedOutput)) | ||||
|  | ||||
| 	log.Debug().Msgf("Setting execute permissions for %s", wineloaderCopy) | ||||
| 	log.Debugf("Setting execute permissions for %s", wineloaderCopy) | ||||
| 	if err := os.Chmod(wineloaderCopy, 0755); err != nil { | ||||
| 		errMsg := fmt.Sprintf("failed to set executable permissions for %s: %v", wineloaderCopy, err) | ||||
| 		dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 		log.Debug().Msg(errMsg) | ||||
| 		log.Debug(errMsg) | ||||
| 		paths.PatchesAppliedCrossOver = false | ||||
| 		updateAllStatuses() | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msg("CrossOver patching completed successfully.") | ||||
| 	log.Debug("CrossOver patching completed successfully.") | ||||
| 	paths.PatchesAppliedCrossOver = true | ||||
| 	dialog.ShowInformation("Success", "CrossOver patching process completed.", myWindow) | ||||
| 	updateAllStatuses() | ||||
| } | ||||
|  | ||||
| func UnpatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	log.Debug().Msg("Unpatch Epoch clicked") | ||||
| 	log.Debug("Unpatch Epoch clicked") | ||||
| 	if paths.EpochPath == "" { | ||||
| 		dialog.ShowError(fmt.Errorf("Epoch path not set. Please set it first."), myWindow) | ||||
| 		return | ||||
| @@ -304,13 +304,13 @@ func UnpatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
|  | ||||
| 	// Remove the rosettaX87 directory | ||||
| 	if utils.DirExists(rosettaX87DirPath) { | ||||
| 		log.Debug().Msgf("Removing directory: %s", rosettaX87DirPath) | ||||
| 		log.Debugf("Removing directory: %s", rosettaX87DirPath) | ||||
| 		if err := os.RemoveAll(rosettaX87DirPath); err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to remove directory %s: %v", rosettaX87DirPath, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 		} else { | ||||
| 			log.Debug().Msgf("Successfully removed directory: %s", rosettaX87DirPath) | ||||
| 			log.Debugf("Successfully removed directory: %s", rosettaX87DirPath) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -318,25 +318,25 @@ func UnpatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	filesToRemove := []string{winerosettaDllPath, d3d9DllPath} | ||||
| 	for _, file := range filesToRemove { | ||||
| 		if utils.PathExists(file) { | ||||
| 			log.Debug().Msgf("Removing file: %s", file) | ||||
| 			log.Debugf("Removing file: %s", file) | ||||
| 			if err := os.Remove(file); err != nil { | ||||
| 				errMsg := fmt.Sprintf("failed to remove file %s: %v", file, err) | ||||
| 				dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 				log.Debug().Msg(errMsg) | ||||
| 				log.Debug(errMsg) | ||||
| 			} else { | ||||
| 				log.Debug().Msgf("Successfully removed file: %s", file) | ||||
| 				log.Debugf("Successfully removed file: %s", file) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Update dlls.txt file - remove winerosetta.dll | ||||
| 	if utils.PathExists(dllsTextFile) { | ||||
| 		log.Debug().Msgf("Updating dlls.txt file: %s", dllsTextFile) | ||||
| 		log.Debugf("Updating dlls.txt file: %s", dllsTextFile) | ||||
| 		content, err := os.ReadFile(dllsTextFile) | ||||
| 		if err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to read dlls.txt file: %v", err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 		} else { | ||||
| 			lines := strings.Split(string(content), "\n") | ||||
| 			filteredLines := make([]string, 0, len(lines)) | ||||
| @@ -352,21 +352,21 @@ func UnpatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 			if err := os.WriteFile(dllsTextFile, []byte(updatedContent), 0644); err != nil { | ||||
| 				errMsg := fmt.Sprintf("failed to update dlls.txt file: %v", err) | ||||
| 				dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 				log.Debug().Msg(errMsg) | ||||
| 				log.Debug(errMsg) | ||||
| 			} else { | ||||
| 				log.Debug().Msgf("Successfully updated dlls.txt file") | ||||
| 				log.Debugf("Successfully updated dlls.txt file") | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msg("Epoch unpatching completed successfully.") | ||||
| 	log.Debug("Epoch unpatching completed successfully.") | ||||
| 	paths.PatchesAppliedEpoch = false | ||||
| 	dialog.ShowInformation("Success", "Epoch unpatching process completed.", myWindow) | ||||
| 	updateAllStatuses() | ||||
| } | ||||
|  | ||||
| func UnpatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	log.Debug().Msg("Unpatch CrossOver clicked") | ||||
| 	log.Debug("Unpatch CrossOver clicked") | ||||
| 	if paths.CrossoverPath == "" { | ||||
| 		dialog.ShowError(fmt.Errorf("CrossOver path not set. Please set it first."), myWindow) | ||||
| 		return | ||||
| @@ -375,21 +375,21 @@ func UnpatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	wineloaderCopy := filepath.Join(paths.CrossoverPath, "Contents", "SharedSupport", "CrossOver", "CrossOver-Hosted Application", "wineloader2") | ||||
|  | ||||
| 	if utils.PathExists(wineloaderCopy) { | ||||
| 		log.Debug().Msgf("Removing file: %s", wineloaderCopy) | ||||
| 		log.Debugf("Removing file: %s", wineloaderCopy) | ||||
| 		if err := os.Remove(wineloaderCopy); err != nil { | ||||
| 			errMsg := fmt.Sprintf("failed to remove file %s: %v", wineloaderCopy, err) | ||||
| 			dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 			log.Debug().Msg(errMsg) | ||||
| 			log.Debug(errMsg) | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| 		} else { | ||||
| 			log.Debug().Msgf("Successfully removed file: %s", wineloaderCopy) | ||||
| 			log.Debugf("Successfully removed file: %s", wineloaderCopy) | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Debug().Msgf("File not found to remove: %s", wineloaderCopy) | ||||
| 		log.Debugf("File not found to remove: %s", wineloaderCopy) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msg("CrossOver unpatching completed successfully.") | ||||
| 	log.Debug("CrossOver unpatching completed successfully.") | ||||
| 	paths.PatchesAppliedCrossOver = false | ||||
| 	dialog.ShowInformation("Success", "CrossOver unpatching process completed.", myWindow) | ||||
| 	updateAllStatuses() | ||||
| @@ -406,14 +406,14 @@ func updateOrAddConfigSetting(configText, setting, value string) string { | ||||
| 	if re.MatchString(configText) { | ||||
| 		// Replace existing setting | ||||
| 		configText = re.ReplaceAllString(configText, newSetting) | ||||
| 		log.Debug().Msgf("Updated setting %s to %s", setting, value) | ||||
| 		log.Debugf("Updated setting %s to %s", setting, value) | ||||
| 	} else { | ||||
| 		// Add new setting | ||||
| 		if configText != "" && !strings.HasSuffix(configText, "\n") { | ||||
| 			configText += "\n" | ||||
| 		} | ||||
| 		configText += newSetting + "\n" | ||||
| 		log.Debug().Msgf("Added new setting %s with value %s", setting, value) | ||||
| 		log.Debugf("Added new setting %s with value %s", setting, value) | ||||
| 	} | ||||
|  | ||||
| 	return configText | ||||
| @@ -427,7 +427,7 @@ func removeConfigSetting(configText, setting string) string { | ||||
|  | ||||
| 	if re.MatchString(configText) { | ||||
| 		configText = re.ReplaceAllString(configText, "") | ||||
| 		log.Debug().Msgf("Removed setting %s from config", setting) | ||||
| 		log.Debugf("Removed setting %s from config", setting) | ||||
| 	} | ||||
|  | ||||
| 	return configText | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| package paths | ||||
|  | ||||
| import ( | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"epochsilicon/pkg/utils" | ||||
| 	"github.com/rs/zerolog/log" | ||||
|  | ||||
| 	"fyne.io/fyne/v2" | ||||
| 	"fyne.io/fyne/v2/dialog" | ||||
| @@ -33,7 +33,7 @@ func SelectCrossOverPath(myWindow fyne.Window, crossoverPathLabel *widget.RichTe | ||||
| 			return | ||||
| 		} | ||||
| 		if uri == nil { | ||||
| 			log.Info().Msg("CrossOver path selection cancelled.") | ||||
| 			log.Info("CrossOver path selection cancelled.") | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| 		} | ||||
| @@ -41,14 +41,14 @@ func SelectCrossOverPath(myWindow fyne.Window, crossoverPathLabel *widget.RichTe | ||||
| 		if filepath.Ext(selectedPath) == ".app" && utils.DirExists(selectedPath) { | ||||
| 			CrossoverPath = selectedPath | ||||
| 			PatchesAppliedCrossOver = false | ||||
| 			log.Info().Msgf("CrossOver path set to:", CrossoverPath) | ||||
| 			log.Infof("CrossOver path set to:", CrossoverPath) | ||||
| 			// Save to prefs | ||||
| 			prefs, _ := utils.LoadPrefs() | ||||
| 			prefs.CrossOverPath = selectedPath | ||||
| 			utils.SavePrefs(prefs) | ||||
| 		} else { | ||||
| 			dialog.ShowError(fmt.Errorf("invalid selection: '%s'. Please select a valid .app bundle", selectedPath), myWindow) | ||||
| 			log.Info().Msgf("Invalid CrossOver path selected:", selectedPath) | ||||
| 			log.Infof("Invalid CrossOver path selected:", selectedPath) | ||||
| 		} | ||||
| 		updateAllStatuses() | ||||
| 	}, myWindow) | ||||
| @@ -61,7 +61,7 @@ func SelectEpochPath(myWindow fyne.Window, epochPathLabel *widget.RichText, upda | ||||
| 			return | ||||
| 		} | ||||
| 		if uri == nil { | ||||
| 			log.Info().Msg("Epoch path selection cancelled.") | ||||
| 			log.Info("Epoch path selection cancelled.") | ||||
| 			updateAllStatuses() | ||||
| 			return | ||||
| 		} | ||||
| @@ -69,14 +69,14 @@ func SelectEpochPath(myWindow fyne.Window, epochPathLabel *widget.RichText, upda | ||||
| 		if utils.DirExists(selectedPath) { | ||||
| 			EpochPath = selectedPath | ||||
| 			PatchesAppliedEpoch = false | ||||
| 			log.Info().Msgf("Epoch path set to:", EpochPath) | ||||
| 			log.Infof("Epoch path set to:", EpochPath) | ||||
| 			// Save to prefs | ||||
| 			prefs, _ := utils.LoadPrefs() | ||||
| 			prefs.EpochPath = selectedPath | ||||
| 			utils.SavePrefs(prefs) | ||||
| 		} else { | ||||
| 			dialog.ShowError(fmt.Errorf("invalid selection: '%s' is not a valid directory", selectedPath), myWindow) | ||||
| 			log.Info().Msgf("Invalid Epoch path selected:", selectedPath) | ||||
| 			log.Infof("Invalid Epoch path selected:", selectedPath) | ||||
| 		} | ||||
| 		updateAllStatuses() | ||||
| 	}, myWindow) | ||||
| @@ -102,7 +102,7 @@ func CheckDefaultCrossOverPath() { | ||||
| 	if CrossoverPath == "" { | ||||
| 		if info, err := os.Stat(DefaultCrossOverPath); err == nil && info.IsDir() { | ||||
| 			CrossoverPath = DefaultCrossOverPath | ||||
| 			log.Info().Msgf("Pre-set CrossOver to default:", DefaultCrossOverPath) | ||||
| 			log.Infof("Pre-set CrossOver to default:", DefaultCrossOverPath) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -2,8 +2,8 @@ package service | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"fmt" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| @@ -27,7 +27,7 @@ var ( | ||||
|  | ||||
| // CleanupExistingServices kills any existing rosettax87 processes | ||||
| func CleanupExistingServices() error { | ||||
| 	log.Info().Msg("Cleaning up any existing rosettax87 processes...") | ||||
| 	log.Info("Cleaning up any existing rosettax87 processes...") | ||||
|  | ||||
| 	// Find all rosettax87 processes | ||||
| 	cmd := exec.Command("pgrep", "-f", "rosettax87") | ||||
| @@ -49,16 +49,16 @@ func CleanupExistingServices() error { | ||||
| 		err := killCmd.Run() | ||||
| 		if err != nil { | ||||
| 			// If regular kill fails, try with sudo (but this might fail too) | ||||
| 			log.Info().Msgf("Regular kill failed for process %s, trying sudo: %v", pid, err) | ||||
| 			log.Infof("Regular kill failed for process %s, trying sudo: %v", pid, err) | ||||
| 			sudoKillCmd := exec.Command("sudo", "kill", "-9", pid) | ||||
| 			err2 := sudoKillCmd.Run() | ||||
| 			if err2 != nil { | ||||
| 				log.Info().Msgf("Failed to kill process %s with sudo: %v", pid, err2) | ||||
| 				log.Infof("Failed to kill process %s with sudo: %v", pid, err2) | ||||
| 			} else { | ||||
| 				log.Info().Msgf("Killed existing rosettax87 process with sudo: %s", pid) | ||||
| 				log.Infof("Killed existing rosettax87 process with sudo: %s", pid) | ||||
| 			} | ||||
| 		} else { | ||||
| 			log.Info().Msgf("Killed existing rosettax87 process: %s", pid) | ||||
| 			log.Infof("Killed existing rosettax87 process: %s", pid) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -77,7 +77,7 @@ func isRosettaSocketActive() bool { | ||||
|  | ||||
| // StartRosettaX87Service starts the RosettaX87 service with sudo privileges | ||||
| func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	log.Info().Msg("Starting RosettaX87 service...") | ||||
| 	log.Info("Starting RosettaX87 service...") | ||||
|  | ||||
| 	if paths.EpochPath == "" { | ||||
| 		dialog.ShowError(fmt.Errorf("Epoch path not set. Please set it first"), myWindow) | ||||
| @@ -103,7 +103,7 @@ func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	// Load user preferences | ||||
| 	prefs, err := utils.LoadPrefs() | ||||
| 	if err != nil { | ||||
| 		log.Info().Msgf("Failed to load preferences: %v", err) | ||||
| 		log.Infof("Failed to load preferences: %v", err) | ||||
| 		prefs = &utils.UserPrefs{} // Use default prefs | ||||
| 	} | ||||
|  | ||||
| @@ -163,7 +163,7 @@ func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		if shouldSavePassword { | ||||
| 			// Save password to keychain | ||||
| 			if err := utils.SaveSudoPassword(password); err != nil { | ||||
| 				log.Info().Msgf("Failed to save password to keychain: %v", err) | ||||
| 				log.Infof("Failed to save password to keychain: %v", err) | ||||
| 				// Don't block the service start, just log the error | ||||
| 			} | ||||
| 		} else { | ||||
| @@ -174,7 +174,7 @@ func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		// Update preferences | ||||
| 		prefs.SaveSudoPassword = shouldSavePassword | ||||
| 		if err := utils.SavePrefs(prefs); err != nil { | ||||
| 			log.Info().Msgf("Failed to save preferences: %v", err) | ||||
| 			log.Infof("Failed to save preferences: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		// Close the dialog | ||||
| @@ -191,13 +191,13 @@ func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 			err := startServiceWithPassword(rosettaX87Dir, rosettaX87Exe, password) | ||||
| 			paths.ServiceStarting = false | ||||
| 			if err != nil { | ||||
| 				log.Info().Msgf("Failed to start RosettaX87 service: %v", err) | ||||
| 				log.Infof("Failed to start RosettaX87 service: %v", err) | ||||
| 				fyne.Do(func() { | ||||
| 					dialog.ShowError(fmt.Errorf("failed to start RosettaX87 service: %v", err), myWindow) | ||||
| 				}) | ||||
| 				ServiceRunning = false | ||||
| 			} else { | ||||
| 				log.Info().Msg("RosettaX87 service started successfully") | ||||
| 				log.Info("RosettaX87 service started successfully") | ||||
| 				ServiceRunning = true | ||||
| 			} | ||||
| 			fyne.Do(func() { | ||||
| @@ -215,7 +215,7 @@ func StartRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		passwordContainer, | ||||
| 		func(confirmed bool) { | ||||
| 			if !confirmed { | ||||
| 				log.Info().Msg("Service start cancelled by user") | ||||
| 				log.Info("Service start cancelled by user") | ||||
| 				return | ||||
| 			} | ||||
| 			confirmFunc() | ||||
| @@ -263,7 +263,7 @@ func startServiceWithPassword(workingDir, executable, password string) error { | ||||
| 	stderrOutput := stderr.String() | ||||
| 	stdoutOutput := stdout.String() | ||||
|  | ||||
| 	log.Info().Msgf("Password test - Exit code: %v, Stderr: %q, Stdout: %q", err, stderrOutput, stdoutOutput) | ||||
| 	log.Infof("Password test - Exit code: %v, Stderr: %q, Stdout: %q", err, stderrOutput, stdoutOutput) | ||||
|  | ||||
| 	// Check for authentication failure indicators | ||||
| 	if strings.Contains(stderrOutput, "Sorry, try again") || | ||||
| @@ -283,7 +283,7 @@ func startServiceWithPassword(workingDir, executable, password string) error { | ||||
| 	} | ||||
|  | ||||
| 	// If we get here, the password is correct, now start the actual service | ||||
| 	log.Info().Msg("Password validated successfully, starting rosettax87 service...") | ||||
| 	log.Info("Password validated successfully, starting rosettax87 service...") | ||||
|  | ||||
| 	cmd := exec.Command("sudo", "-S", executable) | ||||
| 	cmd.Dir = workingDir | ||||
| @@ -325,25 +325,25 @@ func startServiceWithPassword(workingDir, executable, password string) error { | ||||
| 	if cmd.ProcessState != nil && cmd.ProcessState.Exited() { | ||||
| 		stderrOutput := stderr.String() | ||||
| 		stdoutOutput := stdout.String() | ||||
| 		log.Info().Msgf("Process exited - Stdout: %q, Stderr: %q", stdoutOutput, stderrOutput) | ||||
| 		log.Infof("Process exited - Stdout: %q, Stderr: %q", stdoutOutput, stderrOutput) | ||||
| 		return fmt.Errorf("process exited prematurely with code: %d. Stderr: %s", cmd.ProcessState.ExitCode(), stderrOutput) | ||||
| 	} | ||||
|  | ||||
| 	// Verify the service is actually listening | ||||
| 	time.Sleep(1 * time.Second) | ||||
| 	if !isRosettaSocketActive() { | ||||
| 		log.Info().Msgf("Service started but socket not active - Stdout: %q, Stderr: %q", stdout.String(), stderr.String()) | ||||
| 		log.Infof("Service started but socket not active - Stdout: %q, Stderr: %q", stdout.String(), stderr.String()) | ||||
| 		cmd.Process.Kill() | ||||
| 		return fmt.Errorf("service started but is not listening on socket") | ||||
| 	} | ||||
|  | ||||
| 	log.Info().Msgf("RosettaX87 service started successfully with PID: %d", servicePID) | ||||
| 	log.Infof("RosettaX87 service started successfully with PID: %d", servicePID) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // StopRosettaX87Service stops the running RosettaX87 service | ||||
| func StopRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 	log.Info().Msg("Stopping RosettaX87 service...") | ||||
| 	log.Info("Stopping RosettaX87 service...") | ||||
|  | ||||
| 	if !ServiceRunning { | ||||
| 		dialog.ShowInformation("Service Status", "RosettaX87 service is not running.", myWindow) | ||||
| @@ -354,11 +354,11 @@ func StopRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 		// Send SIGTERM to gracefully stop the process | ||||
| 		err := serviceCmd.Process.Signal(syscall.SIGTERM) | ||||
| 		if err != nil { | ||||
| 			log.Info().Msgf("Failed to send SIGTERM to process: %v", err) | ||||
| 			log.Infof("Failed to send SIGTERM to process: %v", err) | ||||
| 			// Try SIGKILL as fallback | ||||
| 			err = serviceCmd.Process.Kill() | ||||
| 			if err != nil { | ||||
| 				log.Info().Msgf("Failed to kill process: %v", err) | ||||
| 				log.Infof("Failed to kill process: %v", err) | ||||
| 				dialog.ShowError(fmt.Errorf("failed to stop service: %v", err), myWindow) | ||||
| 				return | ||||
| 			} | ||||
| @@ -370,7 +370,7 @@ func StopRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { | ||||
| 			ServiceRunning = false | ||||
| 			serviceCmd = nil | ||||
| 			servicePID = 0 | ||||
| 			log.Info().Msg("RosettaX87 service stopped") | ||||
| 			log.Info("RosettaX87 service stopped") | ||||
| 			fyne.Do(func() { | ||||
| 				dialog.ShowInformation("Service Stopped", "RosettaX87 service has been stopped.", myWindow) | ||||
| 				updateAllStatuses() | ||||
| @@ -407,7 +407,7 @@ func IsServiceRunning() bool { | ||||
|  | ||||
| // CleanupService ensures the service is stopped when the application exits | ||||
| func CleanupService() { | ||||
| 	log.Info().Msg("Cleaning up RosettaX87 service on application exit...") | ||||
| 	log.Info("Cleaning up RosettaX87 service on application exit...") | ||||
| 	CleanupExistingServices() | ||||
| 	ServiceRunning = false | ||||
| 	serviceCmd = nil | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| package ui | ||||
|  | ||||
| import ( | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| @@ -27,7 +27,7 @@ func createOptionsComponents() { | ||||
| 		prefs, _ := utils.LoadPrefs() | ||||
| 		prefs.EnableMetalHud = checked | ||||
| 		utils.SavePrefs(prefs) | ||||
| 		log.Debug().Msgf("Metal HUD enabled: %v", launcher.EnableMetalHud) | ||||
| 		log.Debugf("Metal HUD enabled: %v", launcher.EnableMetalHud) | ||||
| 	}) | ||||
| 	metalHudCheckbox.SetChecked(prefs.EnableMetalHud) | ||||
| 	launcher.EnableMetalHud = prefs.EnableMetalHud | ||||
| @@ -37,7 +37,7 @@ func createOptionsComponents() { | ||||
| 		prefs, _ := utils.LoadPrefs() | ||||
| 		prefs.ShowTerminalNormally = checked | ||||
| 		utils.SavePrefs(prefs) | ||||
| 		log.Debug().Msgf("Show terminal normally: %v", checked) | ||||
| 		log.Debugf("Show terminal normally: %v", checked) | ||||
| 	}) | ||||
| 	showTerminalCheckbox.SetChecked(prefs.ShowTerminalNormally) | ||||
|  | ||||
| @@ -47,7 +47,7 @@ func createOptionsComponents() { | ||||
| 		prefs, _ := utils.LoadPrefs() | ||||
| 		prefs.AutoDeleteWdb = checked | ||||
| 		utils.SavePrefs(prefs) | ||||
| 		log.Debug().Msgf("Auto-delete WDB enabled: %v", launcher.AutoDeleteWdb) | ||||
| 		log.Debugf("Auto-delete WDB enabled: %v", launcher.AutoDeleteWdb) | ||||
| 	}) | ||||
| 	autoDeleteWdbCheckbox.SetChecked(prefs.AutoDeleteWdb) | ||||
| 	launcher.AutoDeleteWdb = prefs.AutoDeleteWdb | ||||
| @@ -69,7 +69,7 @@ func createOptionsComponents() { | ||||
| 		prefs, _ := utils.LoadPrefs() | ||||
| 		prefs.EnvironmentVariables = text | ||||
| 		utils.SavePrefs(prefs) | ||||
| 		log.Debug().Msgf("Environment variables updated: %v", launcher.CustomEnvVars) | ||||
| 		log.Debugf("Environment variables updated: %v", launcher.CustomEnvVars) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -126,7 +126,7 @@ func createBottomBar(myWindow fyne.Window) fyne.CanvasObject { | ||||
| 		githubURL := "https://git.burkey.co/eburk/epochsilicon" | ||||
| 		parsedURL, err := url.Parse(githubURL) | ||||
| 		if err != nil { | ||||
| 			log.Debug().Msgf("Error parsing git URL: %v", err) | ||||
| 			log.Debugf("Error parsing git URL: %v", err) | ||||
| 			return | ||||
| 		} | ||||
| 		fyne.CurrentApp().OpenURL(parsedURL) | ||||
| @@ -198,7 +198,7 @@ func createWineRegistryComponents() { | ||||
| 			}() | ||||
|  | ||||
| 			if err := utils.SetOptionAsAltEnabled(true); err != nil { | ||||
| 				log.Debug().Msgf("Failed to enable Option-as-Alt mapping: %v", err) | ||||
| 				log.Debugf("Failed to enable Option-as-Alt mapping: %v", err) | ||||
| 				// Update UI on main thread | ||||
| 				fyne.Do(func() { | ||||
| 					stopPulsingEffect() | ||||
| @@ -206,7 +206,7 @@ func createWineRegistryComponents() { | ||||
| 				}) | ||||
| 				time.Sleep(2 * time.Second) // Show error briefly | ||||
| 			} else { | ||||
| 				log.Debug().Msgf("Successfully enabled Option-as-Alt mapping") | ||||
| 				log.Debugf("Successfully enabled Option-as-Alt mapping") | ||||
| 				// Update preferences | ||||
| 				prefs, _ := utils.LoadPrefs() | ||||
| 				prefs.RemapOptionAsAlt = true | ||||
| @@ -240,7 +240,7 @@ func createWineRegistryComponents() { | ||||
| 			}() | ||||
|  | ||||
| 			if err := utils.SetOptionAsAltEnabled(false); err != nil { | ||||
| 				log.Debug().Msgf("Failed to disable Option-as-Alt mapping: %v", err) | ||||
| 				log.Debugf("Failed to disable Option-as-Alt mapping: %v", err) | ||||
| 				// Update UI on main thread | ||||
| 				fyne.Do(func() { | ||||
| 					stopPulsingEffect() | ||||
| @@ -248,7 +248,7 @@ func createWineRegistryComponents() { | ||||
| 				}) | ||||
| 				time.Sleep(2 * time.Second) // Show error briefly | ||||
| 			} else { | ||||
| 				log.Debug().Msgf("Successfully disabled Option-as-Alt mapping") | ||||
| 				log.Debugf("Successfully disabled Option-as-Alt mapping") | ||||
| 				// Update preferences | ||||
| 				prefs, _ := utils.LoadPrefs() | ||||
| 				prefs.RemapOptionAsAlt = false | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package ui | ||||
|  | ||||
| import ( | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"epochsilicon/pkg/paths" | ||||
| 	"github.com/rs/zerolog/log" | ||||
|  | ||||
| 	"fyne.io/fyne/v2" | ||||
| 	"fyne.io/fyne/v2/canvas" | ||||
| @@ -34,7 +34,7 @@ func createLogoContainer() fyne.CanvasObject { | ||||
| 	// Load the application logo | ||||
| 	logoResource, err := fyne.LoadResourceFromPath("Icon.png") | ||||
| 	if err != nil { | ||||
| 		log.Debug().Msgf("Warning: could not load logo: %v", err) | ||||
| 		log.Debugf("Warning: could not load logo: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Create the logo image with a smaller fixed size since we have a header now | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package ui | ||||
|  | ||||
| import ( | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"git.burkey.co/eburk/epochcli/pkg/epoch" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| @@ -110,10 +110,10 @@ func updateEpochStatus() { | ||||
| 		epochPatchesApplied := false | ||||
| 		stats, err := epoch.Update(paths.EpochPath, false, true, true) | ||||
| 		if err != nil { | ||||
| 			log.Debug().Msgf("Failed to get download Epoch patches: %v", err) | ||||
| 			log.Debugf("Failed to get download Epoch patches: %v", err) | ||||
| 		} | ||||
| 		if stats.Outdated == 0 { | ||||
| 			log.Debug().Msg("Nothing is outdated") | ||||
| 			log.Debug("Nothing is outdated") | ||||
| 			epochPatchesApplied = true | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package ui | ||||
|  | ||||
| import ( | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"fmt" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| @@ -105,7 +105,7 @@ func ShowUpdateDialog(updateInfo *utils.UpdateInfo, currentVersion string, myWin | ||||
|  | ||||
| 			if err != nil { | ||||
| 				progressLabel.SetText(fmt.Sprintf("Download failed: %v", err)) | ||||
| 				log.Debug().Msgf("Download failed: %v", err) | ||||
| 				log.Debugf("Download failed: %v", err) | ||||
|  | ||||
| 				// Re-enable close button | ||||
| 				d.SetButtons([]fyne.CanvasObject{ | ||||
| @@ -123,7 +123,7 @@ func ShowUpdateDialog(updateInfo *utils.UpdateInfo, currentVersion string, myWin | ||||
| 			err = utils.InstallUpdate(downloadPath) | ||||
| 			if err != nil { | ||||
| 				progressLabel.SetText(fmt.Sprintf("Installation failed: %v", err)) | ||||
| 				log.Debug().Msgf("Installation failed: %v", err) | ||||
| 				log.Debugf("Installation failed: %v", err) | ||||
|  | ||||
| 				// Re-enable close button | ||||
| 				fyne.DoAndWait(func() { | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| package utils | ||||
|  | ||||
| import ( | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"github.com/zalando/go-keyring" | ||||
| ) | ||||
|  | ||||
| @@ -23,7 +23,7 @@ func SaveSudoPassword(password string) error { | ||||
| 		return fmt.Errorf("failed to save password to keychain: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	log.Info().Msg("Password saved securely to keychain") | ||||
| 	log.Info("Password saved securely to keychain") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -52,7 +52,7 @@ func DeleteSudoPassword() error { | ||||
| 		return fmt.Errorf("failed to delete password from keychain: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	log.Info().Msg("Password removed from keychain") | ||||
| 	log.Info("Password removed from keychain") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,9 +2,9 @@ package utils | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| @@ -103,16 +103,16 @@ func CopyDir(src string, dst string) error { | ||||
|  | ||||
| // RunOsascript runs an AppleScript command using osascript. | ||||
| func RunOsascript(scriptString string, myWindow fyne.Window) bool { | ||||
| 	log.Debug().Msgf("Executing AppleScript: %s", scriptString) | ||||
| 	log.Debugf("Executing AppleScript: %s", scriptString) | ||||
| 	cmd := exec.Command("osascript", "-e", scriptString) | ||||
| 	output, err := cmd.CombinedOutput() | ||||
| 	if err != nil { | ||||
| 		errMsg := fmt.Sprintf("AppleScript failed: %v\nOutput: %s", err, string(output)) | ||||
| 		dialog.ShowError(errors.New(errMsg), myWindow) | ||||
| 		log.Debug().Msg(errMsg) | ||||
| 		log.Debug(errMsg) | ||||
| 		return false | ||||
| 	} | ||||
| 	log.Debug().Msgf("osascript output: %s", string(output)) | ||||
| 	log.Debugf("osascript output: %s", string(output)) | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| @@ -263,14 +263,14 @@ func InstallUpdate(dmgPath string) error { | ||||
| 	} | ||||
|  | ||||
| 	// Mount the DMG and parse the mount point from plist output | ||||
| 	log.Debug().Msgf("Mounting DMG: %s", dmgPath) | ||||
| 	log.Debugf("Mounting DMG: %s", dmgPath) | ||||
| 	mountCmd := exec.Command("hdiutil", "attach", dmgPath, "-nobrowse", "-plist") | ||||
| 	mountOutput, err := mountCmd.CombinedOutput() | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to mount DMG: %v, output: %s", err, string(mountOutput)) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Mount output: %s", string(mountOutput)) | ||||
| 	log.Debugf("Mount output: %s", string(mountOutput)) | ||||
|  | ||||
| 	mountPoint := "" | ||||
|  | ||||
| @@ -291,7 +291,7 @@ func InstallUpdate(dmgPath string) error { | ||||
| 				end := strings.Index(nextLine, "</string>") | ||||
| 				if start >= 8 && end > start { | ||||
| 					mountPoint = nextLine[start:end] | ||||
| 					log.Debug().Msgf("Found mount point in plist: %s", mountPoint) | ||||
| 					log.Debugf("Found mount point in plist: %s", mountPoint) | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| @@ -300,7 +300,7 @@ func InstallUpdate(dmgPath string) error { | ||||
|  | ||||
| 	// Fallback: try without -plist flag for simpler output | ||||
| 	if mountPoint == "" { | ||||
| 		log.Debug().Msgf("Plist parsing failed, trying simple mount") | ||||
| 		log.Debugf("Plist parsing failed, trying simple mount") | ||||
| 		// Unmount first if something was mounted | ||||
| 		exec.Command("hdiutil", "detach", dmgPath, "-force").Run() | ||||
|  | ||||
| @@ -320,7 +320,7 @@ func InstallUpdate(dmgPath string) error { | ||||
| 				for i := len(parts) - 1; i >= 0; i-- { | ||||
| 					if strings.HasPrefix(parts[i], "/Volumes/") { | ||||
| 						mountPoint = parts[i] | ||||
| 						log.Debug().Msgf("Found mount point in simple output: %s", mountPoint) | ||||
| 						log.Debugf("Found mount point in simple output: %s", mountPoint) | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| @@ -335,11 +335,11 @@ func InstallUpdate(dmgPath string) error { | ||||
| 		return fmt.Errorf("could not find mount point. Mount output: %s", string(mountOutput)) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Using mount point: %s", mountPoint) | ||||
| 	log.Debugf("Using mount point: %s", mountPoint) | ||||
|  | ||||
| 	defer func() { | ||||
| 		// Unmount the DMG | ||||
| 		log.Debug().Msgf("Unmounting DMG from: %s", mountPoint) | ||||
| 		log.Debugf("Unmounting DMG from: %s", mountPoint) | ||||
| 		unmountCmd := exec.Command("hdiutil", "detach", mountPoint, "-force") | ||||
| 		unmountCmd.Run() | ||||
| 	}() | ||||
| @@ -353,7 +353,7 @@ func InstallUpdate(dmgPath string) error { | ||||
| 		newAppPath = exactPath | ||||
| 	} else { | ||||
| 		// Search for any .app bundle in the mount point | ||||
| 		log.Debug().Msgf("EpochSilicon.app not found at exact path, searching for .app bundles") | ||||
| 		log.Debugf("EpochSilicon.app not found at exact path, searching for .app bundles") | ||||
| 		entries, err := os.ReadDir(mountPoint) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("failed to read DMG contents: %v", err) | ||||
| @@ -362,7 +362,7 @@ func InstallUpdate(dmgPath string) error { | ||||
| 		for _, entry := range entries { | ||||
| 			if entry.IsDir() && strings.HasSuffix(entry.Name(), ".app") { | ||||
| 				candidatePath := filepath.Join(mountPoint, entry.Name()) | ||||
| 				log.Debug().Msgf("Found .app bundle: %s", candidatePath) | ||||
| 				log.Debugf("Found .app bundle: %s", candidatePath) | ||||
| 				newAppPath = candidatePath | ||||
| 				break | ||||
| 			} | ||||
| @@ -373,11 +373,11 @@ func InstallUpdate(dmgPath string) error { | ||||
| 		return fmt.Errorf("no .app bundle found in DMG at %s", mountPoint) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Found app to install: %s", newAppPath) | ||||
| 	log.Debugf("Found app to install: %s", newAppPath) | ||||
|  | ||||
| 	// Create backup of current app | ||||
| 	backupPath := currentAppPath + ".backup" | ||||
| 	log.Debug().Msgf("Creating backup: %s -> %s", currentAppPath, backupPath) | ||||
| 	log.Debugf("Creating backup: %s -> %s", currentAppPath, backupPath) | ||||
|  | ||||
| 	// Remove old backup if it exists | ||||
| 	if PathExists(backupPath) { | ||||
| @@ -389,16 +389,16 @@ func InstallUpdate(dmgPath string) error { | ||||
| 	} | ||||
|  | ||||
| 	// Remove current app | ||||
| 	log.Debug().Msgf("Removing current app: %s", currentAppPath) | ||||
| 	log.Debugf("Removing current app: %s", currentAppPath) | ||||
| 	if err := os.RemoveAll(currentAppPath); err != nil { | ||||
| 		return fmt.Errorf("failed to remove current app: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Copy new app | ||||
| 	log.Debug().Msgf("Installing new app: %s -> %s", newAppPath, currentAppPath) | ||||
| 	log.Debugf("Installing new app: %s -> %s", newAppPath, currentAppPath) | ||||
| 	if err := CopyDir(newAppPath, currentAppPath); err != nil { | ||||
| 		// Try to restore backup on failure | ||||
| 		log.Debug().Msgf("Installation failed, restoring backup") | ||||
| 		log.Debugf("Installation failed, restoring backup") | ||||
| 		os.RemoveAll(currentAppPath) | ||||
| 		CopyDir(backupPath, currentAppPath) | ||||
| 		return fmt.Errorf("failed to install new app: %v", err) | ||||
| @@ -407,25 +407,25 @@ func InstallUpdate(dmgPath string) error { | ||||
| 	// Fix executable permissions for the main binary | ||||
| 	executablePath := filepath.Join(currentAppPath, "Contents", "MacOS", "epochsilicon") | ||||
| 	if PathExists(executablePath) { | ||||
| 		log.Debug().Msgf("Setting executable permissions for: %s", executablePath) | ||||
| 		log.Debugf("Setting executable permissions for: %s", executablePath) | ||||
| 		if err := os.Chmod(executablePath, 0755); err != nil { | ||||
| 			log.Debug().Msgf("Warning: failed to set executable permissions: %v", err) | ||||
| 			log.Debugf("Warning: failed to set executable permissions: %v", err) | ||||
| 			// Don't fail the entire update for this, but log it | ||||
| 		} | ||||
| 	} else { | ||||
| 		log.Debug().Msgf("Warning: executable not found at expected path: %s", executablePath) | ||||
| 		log.Debugf("Warning: executable not found at expected path: %s", executablePath) | ||||
| 	} | ||||
|  | ||||
| 	// Remove backup on success | ||||
| 	os.RemoveAll(backupPath) | ||||
|  | ||||
| 	log.Debug().Msgf("Update installed successfully") | ||||
| 	log.Debugf("Update installed successfully") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // TestDMGMount tests DMG mounting and returns mount point and app path for debugging | ||||
| func TestDMGMount(dmgPath string) (string, string, error) { | ||||
| 	log.Debug().Msgf("Testing DMG mount: %s", dmgPath) | ||||
| 	log.Debugf("Testing DMG mount: %s", dmgPath) | ||||
|  | ||||
| 	// Mount the DMG with verbose output to better parse mount point | ||||
| 	mountCmd := exec.Command("hdiutil", "attach", dmgPath, "-nobrowse", "-plist") | ||||
| @@ -434,7 +434,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { | ||||
| 		return "", "", fmt.Errorf("failed to mount DMG: %v, output: %s", err, string(mountOutput)) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Mount output: %s", string(mountOutput)) | ||||
| 	log.Debugf("Mount output: %s", string(mountOutput)) | ||||
|  | ||||
| 	// Parse mount output to get mount point | ||||
| 	mountPoint := "" | ||||
| @@ -459,7 +459,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { | ||||
|  | ||||
| 	// Second try: use hdiutil info to get mount points if first method failed | ||||
| 	if mountPoint == "" { | ||||
| 		log.Debug().Msgf("First mount point detection failed, trying hdiutil info") | ||||
| 		log.Debugf("First mount point detection failed, trying hdiutil info") | ||||
| 		infoCmd := exec.Command("hdiutil", "info", "-plist") | ||||
| 		infoOutput, infoErr := infoCmd.CombinedOutput() | ||||
| 		if infoErr == nil { | ||||
| @@ -480,7 +480,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { | ||||
| 		return "", "", fmt.Errorf("could not find mount point. Mount output: %s", string(mountOutput)) | ||||
| 	} | ||||
|  | ||||
| 	log.Debug().Msgf("Using mount point: %s", mountPoint) | ||||
| 	log.Debugf("Using mount point: %s", mountPoint) | ||||
|  | ||||
| 	// Find the app in the mounted DMG | ||||
| 	var newAppPath string | ||||
| @@ -491,7 +491,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { | ||||
| 		newAppPath = exactPath | ||||
| 	} else { | ||||
| 		// Search for any .app bundle in the mount point | ||||
| 		log.Debug().Msgf("EpochSilicon.app not found at exact path, searching for .app bundles") | ||||
| 		log.Debugf("EpochSilicon.app not found at exact path, searching for .app bundles") | ||||
| 		entries, err := os.ReadDir(mountPoint) | ||||
| 		if err != nil { | ||||
| 			// Unmount before returning error | ||||
| @@ -502,7 +502,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { | ||||
| 		for _, entry := range entries { | ||||
| 			if entry.IsDir() && strings.HasSuffix(entry.Name(), ".app") { | ||||
| 				candidatePath := filepath.Join(mountPoint, entry.Name()) | ||||
| 				log.Debug().Msgf("Found .app bundle: %s", candidatePath) | ||||
| 				log.Debugf("Found .app bundle: %s", candidatePath) | ||||
| 				newAppPath = candidatePath | ||||
| 				break | ||||
| 			} | ||||
| @@ -510,7 +510,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { | ||||
| 	} | ||||
|  | ||||
| 	// Unmount after testing | ||||
| 	log.Debug().Msgf("Unmounting test DMG from: %s", mountPoint) | ||||
| 	log.Debugf("Unmounting test DMG from: %s", mountPoint) | ||||
| 	exec.Command("hdiutil", "detach", mountPoint, "-force").Run() | ||||
|  | ||||
| 	if newAppPath == "" { | ||||
| @@ -530,14 +530,14 @@ func CompareFileWithBundledResource(filePath, resourceName string) bool { | ||||
| 	// Get file info for the existing file | ||||
| 	fileInfo, err := os.Stat(filePath) | ||||
| 	if err != nil { | ||||
| 		log.Debug().Msgf("Failed to stat file %s: %v", filePath, err) | ||||
| 		log.Debugf("Failed to stat file %s: %v", filePath, err) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// Load the bundled resource | ||||
| 	resource, err := fyne.LoadResourceFromPath(resourceName) | ||||
| 	if err != nil { | ||||
| 		log.Debug().Msgf("Failed to load bundled resource %s: %v", resourceName, err) | ||||
| 		log.Debugf("Failed to load bundled resource %s: %v", resourceName, err) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| @@ -545,7 +545,7 @@ func CompareFileWithBundledResource(filePath, resourceName string) bool { | ||||
| 	fileSize := fileInfo.Size() | ||||
| 	resourceSize := int64(len(resource.Content())) | ||||
|  | ||||
| 	log.Debug().Msgf("Comparing file sizes - %s: %d bytes vs bundled %s: %d bytes", | ||||
| 	log.Debugf("Comparing file sizes - %s: %d bytes vs bundled %s: %d bytes", | ||||
| 		filePath, fileSize, resourceName, resourceSize) | ||||
|  | ||||
| 	return fileSize == resourceSize | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package utils | ||||
|  | ||||
| import ( | ||||
| 	"epochsilicon/pkg/log" | ||||
| 	"fmt" | ||||
| 	"github.com/rs/zerolog/log" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| @@ -74,7 +74,7 @@ reg add "%s" /v "RightOptionIsAlt" /t REG_SZ /d "Y" /f | ||||
| 		return fmt.Errorf("batch registry add failed: %v, output: %s", err, string(output)) | ||||
| 	} | ||||
|  | ||||
| 	log.Info().Msgf("Successfully enabled Option-as-Alt mapping in Wine registry (optimized)") | ||||
| 	log.Infof("Successfully enabled Option-as-Alt mapping in Wine registry (optimized)") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -102,7 +102,7 @@ reg delete "%s" /v "RightOptionIsAlt" /f 2>nul | ||||
| 		return fmt.Errorf("batch registry delete failed: %v, output: %s", err, string(output)) | ||||
| 	} | ||||
|  | ||||
| 	log.Info().Msgf("Successfully disabled Option-as-Alt mapping in Wine registry (optimized)") | ||||
| 	log.Infof("Successfully disabled Option-as-Alt mapping in Wine registry (optimized)") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -110,7 +110,7 @@ reg delete "%s" /v "RightOptionIsAlt" /f 2>nul | ||||
| func CheckOptionAsAltEnabled() bool { | ||||
| 	homeDir, err := os.UserHomeDir() | ||||
| 	if err != nil { | ||||
| 		log.Info().Msgf("Failed to get user home directory: %v", err) | ||||
| 		log.Infof("Failed to get user home directory: %v", err) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| @@ -118,7 +118,7 @@ func CheckOptionAsAltEnabled() bool { | ||||
|  | ||||
| 	// Check if CrossOver wine loader exists | ||||
| 	if !PathExists(wineLoaderPath) { | ||||
| 		log.Info().Msgf("CrossOver wine loader not found at: %s", wineLoaderPath) | ||||
| 		log.Infof("CrossOver wine loader not found at: %s", wineLoaderPath) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| @@ -133,18 +133,18 @@ func CheckOptionAsAltEnabled() bool { | ||||
| func CheckOptionAsAltEnabledFast() bool { | ||||
| 	regPath, err := GetWineUserRegPath() | ||||
| 	if err != nil { | ||||
| 		log.Info().Msgf("Failed to get Wine registry path: %v", err) | ||||
| 		log.Infof("Failed to get Wine registry path: %v", err) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	if !PathExists(regPath) { | ||||
| 		log.Info().Msgf("Wine user.reg file not found at: %s", regPath) | ||||
| 		log.Infof("Wine user.reg file not found at: %s", regPath) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	content, err := os.ReadFile(regPath) | ||||
| 	if err != nil { | ||||
| 		log.Info().Msgf("Failed to read Wine registry file: %v", err) | ||||
| 		log.Infof("Failed to read Wine registry file: %v", err) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| @@ -191,12 +191,12 @@ func SetOptionAsAltEnabled(enabled bool) error { | ||||
| 	} else { | ||||
| 		err := setRegistryValuesOptimized(winePrefix, false) | ||||
| 		if err != nil { | ||||
| 			log.Info().Msgf("Wine registry disable failed: %v", err) | ||||
| 			log.Infof("Wine registry disable failed: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		err2 := setRegistryValuesFast(false) | ||||
| 		if err2 != nil { | ||||
| 			log.Info().Msgf("File-based cleanup failed: %v", err2) | ||||
| 			log.Infof("File-based cleanup failed: %v", err2) | ||||
| 		} | ||||
|  | ||||
| 		if err != nil { | ||||
| @@ -334,7 +334,7 @@ func addOptionAsAltSettingsFast(regPath string, lines []string) error { | ||||
| 		return fmt.Errorf("failed to write registry file: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	log.Info().Msgf("Successfully enabled Option-as-Alt mapping in Wine registry (fast method)") | ||||
| 	log.Infof("Successfully enabled Option-as-Alt mapping in Wine registry (fast method)") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -342,7 +342,7 @@ func addOptionAsAltSettingsFast(regPath string, lines []string) error { | ||||
| func removeOptionAsAltSettingsFast(regPath string, lines []string) error { | ||||
| 	if !PathExists(regPath) { | ||||
| 		// File doesn't exist, nothing to remove | ||||
| 		log.Info().Msgf("Successfully disabled Option-as-Alt mapping in Wine registry (no file to modify)") | ||||
| 		log.Infof("Successfully disabled Option-as-Alt mapping in Wine registry (no file to modify)") | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| @@ -369,7 +369,7 @@ func removeOptionAsAltSettingsFast(regPath string, lines []string) error { | ||||
| 		return fmt.Errorf("failed to write registry file: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	log.Info().Msgf("Successfully disabled Option-as-Alt mapping in Wine registry (fast method)") | ||||
| 	log.Infof("Successfully disabled Option-as-Alt mapping in Wine registry (fast method)") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user