From 8b5be228fe40872a6dbda1830db72a943aa55749 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Wed, 23 Jul 2025 08:46:53 -0700 Subject: [PATCH 1/6] change to zerolog --- go.mod | 3 + go.sum | 23 +++++++ main.go | 17 +++-- pkg/debug/debug.go | 15 ----- pkg/debug/debug_release.go | 13 ---- pkg/launcher/launcher.go | 36 +++++------ pkg/launcher/recommended.go | 20 +++--- pkg/patching/patching.go | 123 ++++++++++++++++++------------------ pkg/paths/paths.go | 16 ++--- pkg/service/service.go | 46 +++++++------- pkg/ui/components.go | 20 +++--- pkg/ui/layout.go | 4 +- pkg/ui/status.go | 6 +- pkg/ui/updater.go | 6 +- pkg/utils/keychain.go | 6 +- pkg/utils/utils.go | 65 ++++++++++--------- pkg/utils/wine_registry.go | 26 ++++---- 17 files changed, 223 insertions(+), 222 deletions(-) delete mode 100644 pkg/debug/debug.go delete mode 100644 pkg/debug/debug_release.go diff --git a/go.mod b/go.mod index 84b1d4f..28b06a7 100644 --- a/go.mod +++ b/go.mod @@ -33,9 +33,12 @@ require ( github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/rymdport/portal v0.4.2 // indirect github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect diff --git a/go.sum b/go.sum index 97e4fe1..feb5a61 100644 --- a/go.sum +++ b/go.sum @@ -16,9 +16,11 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0 github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= @@ -55,6 +57,7 @@ github.com/go-text/typesetting v0.3.0 h1:OWCgYpp8njoxSRpwrdd1bQOxdjOXDj9Rqart9ML github.com/go-text/typesetting v0.3.0/go.mod h1:qjZLkhRgOEYMhU9eHBr3AR4sfnGJvOXNLt8yRAySFuY= github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC+94v2xrb1PoS4NIDe7DGYtLnU2wWiQe9a1B1c0= github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y= @@ -76,6 +79,13 @@ github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe9 github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD0D1vHk= @@ -84,20 +94,28 @@ github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpM github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/rymdport/portal v0.4.1 h1:2dnZhjf5uEaeDjeF/yBIeeRo6pNI2QAKm7kq1w/kbnA= github.com/rymdport/portal v0.4.1/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4= github.com/rymdport/portal v0.4.2 h1:7jKRSemwlTyVHHrTGgQg7gmNPJs88xkbKcIL3NlcmSU= github.com/rymdport/portal v0.4.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE= github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= @@ -114,6 +132,10 @@ golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= @@ -126,6 +148,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= diff --git a/main.go b/main.go index 03a090e..14a9e41 100644 --- a/main.go +++ b/main.go @@ -1,17 +1,22 @@ package main import ( - "epochsilicon/pkg/debug" "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 +} + func main() { PEApp := app.NewWithID("com.burkey.epochsilicon") PEWindow := PEApp.NewWindow("EpochSilicon v" + appVersion) @@ -22,21 +27,21 @@ func main() { prefs, _ := utils.LoadPrefs() updateInfo, updateAvailable, err := utils.CheckForUpdateWithAssets(appVersion) if err != nil { - debug.Printf("Failed to check for updates: %v", err) + log.Debug().Msgf("Failed to check for updates: %v", err) return } if !updateAvailable { - debug.Printf("No updates available") + log.Debug().Msgf("No updates available") return } latestVersion := strings.TrimPrefix(updateInfo.TagName, "v") - debug.Printf("Update available: current=%s, latest=%s", appVersion, latestVersion) + log.Debug().Msgf("Update available: current=%s, latest=%s", appVersion, latestVersion) // Skip if user has suppressed this version if prefs.SuppressedUpdateVersion == latestVersion { - debug.Printf("Update suppressed by user: %s", latestVersion) + log.Debug().Msgf("Update suppressed by user: %s", latestVersion) return } @@ -49,7 +54,7 @@ func main() { // Set up cleanup when window closes PEWindow.SetCloseIntercept(func() { - debug.Println("Application closing, cleaning up RosettaX87 service...") + log.Debug().Msg("Application closing, cleaning up RosettaX87 service...") service.CleanupService() PEApp.Quit() }) diff --git a/pkg/debug/debug.go b/pkg/debug/debug.go deleted file mode 100644 index c9268f7..0000000 --- a/pkg/debug/debug.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !release - -package debug - -import "log" - -// Printf logs with fmt.Printf style formatting in debug builds -func Printf(format string, v ...interface{}) { - log.Printf(format, v...) -} - -// Println logs with fmt.Println style in debug builds -func Println(v ...interface{}) { - log.Println(v...) -} diff --git a/pkg/debug/debug_release.go b/pkg/debug/debug_release.go deleted file mode 100644 index ffd3d54..0000000 --- a/pkg/debug/debug_release.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build release - -package debug - -// Printf is a no-op in release builds -func Printf(format string, v ...interface{}) { - // No-op in release builds to reduce binary size -} - -// Println is a no-op in release builds -func Println(v ...interface{}) { - // No-op in release builds to reduce binary size -} diff --git a/pkg/launcher/launcher.go b/pkg/launcher/launcher.go index d356c8a..e12baee 100644 --- a/pkg/launcher/launcher.go +++ b/pkg/launcher/launcher.go @@ -3,12 +3,12 @@ package launcher import ( "bufio" "fmt" + "github.com/rs/zerolog/log" "os" "os/exec" "path/filepath" "sync" - "epochsilicon/pkg/debug" "epochsilicon/pkg/paths" // Corrected import path "epochsilicon/pkg/utils" // Corrected import path @@ -41,7 +41,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { // Parse the shell command to extract components // The shellCmd format is: cd && - debug.Printf("Parsing shell command: %s", shellCmd) + log.Debug().Msgf("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() - debug.Printf("GAME STDOUT: %s", line) + log.Debug().Msgf("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() - debug.Printf("GAME STDERR: %s", line) + log.Debug().Msgf("GAME STDERR: %s", line) } }() @@ -93,9 +93,9 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { }() if err := cmd.Wait(); err != nil { - debug.Printf("Game process ended with error: %v", err) + log.Debug().Msgf("Game process ended with error: %v", err) } else { - debug.Println("Game process ended successfully") + log.Debug().Msg("Game process ended successfully") } }() @@ -103,7 +103,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { } func LaunchGame(myWindow fyne.Window) { - debug.Println("Launch Game button clicked") + log.Debug().Msg("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() - debug.Println("Preparing to launch EpochSilicon...") + log.Debug().Msg("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) { - debug.Printf("Auto-deleting WDB directory: %s", wdbPath) + log.Debug().Msgf("Auto-deleting WDB directory: %s", wdbPath) if err := os.RemoveAll(wdbPath); err != nil { - debug.Printf("Warning: failed to auto-delete WDB directory: %v", err) + log.Debug().Msgf("Warning: failed to auto-delete WDB directory: %v", err) // Don't block the launch, just log the error } else { - debug.Printf("Successfully auto-deleted WDB directory") + log.Debug().Msgf("Successfully auto-deleted WDB directory") } } else { - debug.Printf("WDB directory not found, nothing to delete") + log.Debug().Msgf("WDB directory not found, nothing to delete") } } // Since RosettaX87 service is already running, we can directly launch WoW - debug.Println("RosettaX87 service is running. Proceeding to launch WoW.") + log.Debug().Msg("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) - debug.Println("Executing WoW launch command via AppleScript...") + log.Debug().Msg("Executing WoW launch command via AppleScript...") if !utils.RunOsascript(cmd2Script, myWindow) { return } - debug.Println("Launch command executed. Check the new terminal window.") + log.Debug().Msg("Launch command executed. Check the new terminal window.") } else { // Use integrated terminal - debug.Printf("Shell command for integrated terminal: %s", shellCmd) - debug.Println("Executing WoW launch command with integrated terminal...") + log.Debug().Msgf("Shell command for integrated terminal: %s", shellCmd) + log.Debug().Msg("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 } - debug.Println("Game launched with integrated terminal. Check the application logs for output.") + log.Debug().Msg("Game launched with integrated terminal. Check the application logs for output.") } } diff --git a/pkg/launcher/recommended.go b/pkg/launcher/recommended.go index cd2a7e2..b434326 100644 --- a/pkg/launcher/recommended.go +++ b/pkg/launcher/recommended.go @@ -2,12 +2,12 @@ package launcher import ( "fmt" + "github.com/rs/zerolog/log" "os" "path/filepath" "regexp" "strings" - "epochsilicon/pkg/debug" "epochsilicon/pkg/paths" ) @@ -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 == "" { - debug.Printf("Epoch path not set, cannot check Config.wtf") + log.Debug().Msgf("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) { - debug.Printf("Config.wtf not found at %s", configPath) + log.Debug().Msgf("Config.wtf not found at %s", configPath) return false } content, err := os.ReadFile(configPath) if err != nil { - debug.Printf("Failed to read Config.wtf: %v", err) + log.Debug().Msgf("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) { - debug.Printf("Setting %s not found or incorrect in Config.wtf", setting) + log.Debug().Msgf("Setting %s not found or incorrect in Config.wtf", setting) return false } } - debug.Printf("All recommended settings are correctly applied") + log.Debug().Msgf("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 { - debug.Printf("Config.wtf not found, creating new file") + log.Debug().Msgf("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) } - debug.Printf("Successfully applied recommended settings to Config.wtf") + log.Debug().Msgf("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) - debug.Printf("Updated setting %s to %s", setting, value) + log.Debug().Msgf("Updated setting %s to %s", setting, value) } else { // Add new setting if configText != "" && !strings.HasSuffix(configText, "\n") { configText += "\n" } configText += newSetting + "\n" - debug.Printf("Added new setting %s with value %s", setting, value) + log.Debug().Msgf("Added new setting %s with value %s", setting, value) } return configText diff --git a/pkg/patching/patching.go b/pkg/patching/patching.go index 57f76f1..766d623 100644 --- a/pkg/patching/patching.go +++ b/pkg/patching/patching.go @@ -5,15 +5,14 @@ import ( "errors" "fmt" "git.burkey.co/eburk/epochcli/pkg/epoch" + "github.com/rs/zerolog/log" "io" - "log" "os" "os/exec" "path/filepath" "regexp" "strings" - "epochsilicon/pkg/debug" "epochsilicon/pkg/paths" // Corrected import path "epochsilicon/pkg/utils" // Corrected import path @@ -22,7 +21,7 @@ import ( ) func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { - debug.Println("Patch Epoch clicked") + log.Debug().Msg("Patch Epoch clicked") if paths.EpochPath == "" { dialog.ShowError(fmt.Errorf("Epoch path not set. Please set it first."), myWindow) return @@ -38,25 +37,25 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { } for resourceName, destPath := range filesToCopy { - debug.Printf("Processing resource: %s to %s", resourceName, destPath) + log.Debug().Msgf("Processing resource: %s to %s", resourceName, destPath) // Check if file already exists and has correct size if utils.PathExists(destPath) && utils.CompareFileWithBundledResource(destPath, resourceName) { - debug.Printf("File %s already exists with correct size, skipping copy", destPath) + log.Debug().Msgf("File %s already exists with correct size, skipping copy", destPath) continue } if utils.PathExists(destPath) { - debug.Printf("File %s exists but has incorrect size, updating...", destPath) + log.Debug().Msgf("File %s exists but has incorrect size, updating...", destPath) } else { - debug.Printf("File %s does not exist, creating...", destPath) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return @@ -66,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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return @@ -77,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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return } - debug.Printf("Successfully copied %s to %s", resourceName, destPath) + log.Debug().Msgf("Successfully copied %s to %s", resourceName, destPath) } - debug.Printf("Preparing rosettax87 directory at: %s", targetRosettaX87Dir) + log.Debug().Msgf("Preparing rosettax87 directory at: %s", targetRosettaX87Dir) if err := os.RemoveAll(targetRosettaX87Dir); err != nil { - debug.Printf("Warning: could not remove existing rosettax87 folder '%s': %v", targetRosettaX87Dir, err) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return @@ -104,12 +103,12 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { } for resourceName, destPath := range rosettaFilesToCopy { - debug.Printf("Processing rosetta resource: %s to %s", resourceName, destPath) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return @@ -119,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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return @@ -130,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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return @@ -138,31 +137,31 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { destinationFile.Close() if filepath.Base(destPath) == "rosettax87" { - debug.Printf("Setting execute permission for %s", destPath) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedEpoch = false updateAllStatuses() return } } - debug.Printf("Successfully copied %s to %s", resourceName, destPath) + log.Debug().Msgf("Successfully copied %s to %s", resourceName, destPath) } - debug.Printf("Checking dlls.txt file at: %s", dllsTextFile) + log.Debug().Msgf("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) { - debug.Printf("dlls.txt already contains %s", winerosettaEntry) + log.Debug().Msgf("dlls.txt already contains %s", winerosettaEntry) needsWinerosettaUpdate = false } } else { - debug.Printf("dlls.txt not found, will create a new one") + log.Debug().Msgf("dlls.txt not found, will create a new one") } if needsWinerosettaUpdate { @@ -173,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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) } } @@ -187,20 +186,20 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { if needsWinerosettaUpdate { if !strings.Contains(updatedContent, winerosettaEntry+"\n") { updatedContent += winerosettaEntry + "\n" - debug.Printf("Adding %s to dlls.txt", winerosettaEntry) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) } else { - debug.Printf("Successfully updated dlls.txt") + log.Debug().Msgf("Successfully updated dlls.txt") } } - debug.Println("Downloading updates from Project Epoch servers.") + log.Debug().Msg("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) @@ -213,10 +212,10 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { dialog.ShowError(errors.New(errMsg), myWindow) }) paths.DownloadingPatches = false - log.Println(errMsg) + log.Error().Msg(errMsg) } - log.Printf("Successfully updated %d Epoch files", stats.Updated) - debug.Println("Epoch patching with bundled resources completed successfully.") + log.Info().Msgf("Successfully updated %d Epoch files", stats.Updated) + log.Debug().Msg("Epoch patching with bundled resources completed successfully.") fyne.Do(func() { dialog.ShowInformation("Success", "Epoch patching process completed.", myWindow) }) @@ -229,7 +228,7 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { } func PatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { - debug.Println("Patch CrossOver clicked") + log.Debug().Msg("Patch CrossOver clicked") if paths.CrossoverPath == "" { dialog.ShowError(fmt.Errorf("CrossOver path not set. Please set it first."), myWindow) return @@ -246,7 +245,7 @@ func PatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { return } - debug.Printf("Copying %s to %s", wineloaderOrig, wineloaderCopy) + log.Debug().Msgf("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") { @@ -258,40 +257,40 @@ func PatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { return } - debug.Printf("Executing: codesign --remove-signature %s", wineloaderCopy) + log.Debug().Msgf("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) - debug.Println(derrMsg) + log.Debug().Msg(derrMsg) paths.PatchesAppliedCrossOver = false if err := os.Remove(wineloaderCopy); err != nil { - debug.Printf("Warning: failed to cleanup wineloader2 after codesign failure: %v", err) + log.Debug().Msgf("Warning: failed to cleanup wineloader2 after codesign failure: %v", err) } updateAllStatuses() return } - debug.Printf("codesign output: %s", string(combinedOutput)) + log.Debug().Msgf("codesign output: %s", string(combinedOutput)) - debug.Printf("Setting execute permissions for %s", wineloaderCopy) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) paths.PatchesAppliedCrossOver = false updateAllStatuses() return } - debug.Println("CrossOver patching completed successfully.") + log.Debug().Msg("CrossOver patching completed successfully.") paths.PatchesAppliedCrossOver = true dialog.ShowInformation("Success", "CrossOver patching process completed.", myWindow) updateAllStatuses() } func UnpatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { - debug.Println("Unpatch Epoch clicked") + log.Debug().Msg("Unpatch Epoch clicked") if paths.EpochPath == "" { dialog.ShowError(fmt.Errorf("Epoch path not set. Please set it first."), myWindow) return @@ -305,13 +304,13 @@ func UnpatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { // Remove the rosettaX87 directory if utils.DirExists(rosettaX87DirPath) { - debug.Printf("Removing directory: %s", rosettaX87DirPath) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) } else { - debug.Printf("Successfully removed directory: %s", rosettaX87DirPath) + log.Debug().Msgf("Successfully removed directory: %s", rosettaX87DirPath) } } @@ -319,25 +318,25 @@ func UnpatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { filesToRemove := []string{winerosettaDllPath, d3d9DllPath} for _, file := range filesToRemove { if utils.PathExists(file) { - debug.Printf("Removing file: %s", file) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) } else { - debug.Printf("Successfully removed file: %s", file) + log.Debug().Msgf("Successfully removed file: %s", file) } } } // Update dlls.txt file - remove winerosetta.dll if utils.PathExists(dllsTextFile) { - debug.Printf("Updating dlls.txt file: %s", dllsTextFile) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) } else { lines := strings.Split(string(content), "\n") filteredLines := make([]string, 0, len(lines)) @@ -353,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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) } else { - debug.Printf("Successfully updated dlls.txt file") + log.Debug().Msgf("Successfully updated dlls.txt file") } } } - debug.Println("Epoch unpatching completed successfully.") + log.Debug().Msg("Epoch unpatching completed successfully.") paths.PatchesAppliedEpoch = false dialog.ShowInformation("Success", "Epoch unpatching process completed.", myWindow) updateAllStatuses() } func UnpatchCrossOver(myWindow fyne.Window, updateAllStatuses func()) { - debug.Println("Unpatch CrossOver clicked") + log.Debug().Msg("Unpatch CrossOver clicked") if paths.CrossoverPath == "" { dialog.ShowError(fmt.Errorf("CrossOver path not set. Please set it first."), myWindow) return @@ -376,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) { - debug.Printf("Removing file: %s", wineloaderCopy) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) updateAllStatuses() return } else { - debug.Printf("Successfully removed file: %s", wineloaderCopy) + log.Debug().Msgf("Successfully removed file: %s", wineloaderCopy) } } else { - debug.Printf("File not found to remove: %s", wineloaderCopy) + log.Debug().Msgf("File not found to remove: %s", wineloaderCopy) } - debug.Println("CrossOver unpatching completed successfully.") + log.Debug().Msg("CrossOver unpatching completed successfully.") paths.PatchesAppliedCrossOver = false dialog.ShowInformation("Success", "CrossOver unpatching process completed.", myWindow) updateAllStatuses() @@ -407,14 +406,14 @@ func updateOrAddConfigSetting(configText, setting, value string) string { if re.MatchString(configText) { // Replace existing setting configText = re.ReplaceAllString(configText, newSetting) - debug.Printf("Updated setting %s to %s", setting, value) + log.Debug().Msgf("Updated setting %s to %s", setting, value) } else { // Add new setting if configText != "" && !strings.HasSuffix(configText, "\n") { configText += "\n" } configText += newSetting + "\n" - debug.Printf("Added new setting %s with value %s", setting, value) + log.Debug().Msgf("Added new setting %s with value %s", setting, value) } return configText @@ -428,7 +427,7 @@ func removeConfigSetting(configText, setting string) string { if re.MatchString(configText) { configText = re.ReplaceAllString(configText, "") - debug.Printf("Removed setting %s from config", setting) + log.Debug().Msgf("Removed setting %s from config", setting) } return configText diff --git a/pkg/paths/paths.go b/pkg/paths/paths.go index b3380c9..4be230d 100644 --- a/pkg/paths/paths.go +++ b/pkg/paths/paths.go @@ -2,11 +2,11 @@ package paths import ( "fmt" - "log" "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.Println("CrossOver path selection cancelled.") + log.Info().Msg("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.Println("CrossOver path set to:", CrossoverPath) + log.Info().Msgf("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.Println("Invalid CrossOver path selected:", selectedPath) + log.Info().Msgf("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.Println("Epoch path selection cancelled.") + log.Info().Msg("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.Println("Epoch path set to:", EpochPath) + log.Info().Msgf("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.Println("Invalid Epoch path selected:", selectedPath) + log.Info().Msgf("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.Println("Pre-set CrossOver to default:", DefaultCrossOverPath) + log.Info().Msgf("Pre-set CrossOver to default:", DefaultCrossOverPath) } } } diff --git a/pkg/service/service.go b/pkg/service/service.go index b4fce04..b547cb6 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -3,7 +3,7 @@ package service import ( "bytes" "fmt" - "log" + "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.Println("Cleaning up any existing rosettax87 processes...") + log.Info().Msg("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.Printf("Regular kill failed for process %s, trying sudo: %v", pid, err) + log.Info().Msgf("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.Printf("Failed to kill process %s with sudo: %v", pid, err2) + log.Info().Msgf("Failed to kill process %s with sudo: %v", pid, err2) } else { - log.Printf("Killed existing rosettax87 process with sudo: %s", pid) + log.Info().Msgf("Killed existing rosettax87 process with sudo: %s", pid) } } else { - log.Printf("Killed existing rosettax87 process: %s", pid) + log.Info().Msgf("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.Println("Starting RosettaX87 service...") + log.Info().Msg("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.Printf("Failed to load preferences: %v", err) + log.Info().Msgf("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.Printf("Failed to save password to keychain: %v", err) + log.Info().Msgf("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.Printf("Failed to save preferences: %v", err) + log.Info().Msgf("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.Printf("Failed to start RosettaX87 service: %v", err) + log.Info().Msgf("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.Println("RosettaX87 service started successfully") + log.Info().Msg("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.Println("Service start cancelled by user") + log.Info().Msg("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.Printf("Password test - Exit code: %v, Stderr: %q, Stdout: %q", err, stderrOutput, stdoutOutput) + log.Info().Msgf("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.Println("Password validated successfully, starting rosettax87 service...") + log.Info().Msg("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.Printf("Process exited - Stdout: %q, Stderr: %q", stdoutOutput, stderrOutput) + log.Info().Msgf("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.Printf("Service started but socket not active - Stdout: %q, Stderr: %q", stdout.String(), stderr.String()) + log.Info().Msgf("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.Printf("RosettaX87 service started successfully with PID: %d", servicePID) + log.Info().Msgf("RosettaX87 service started successfully with PID: %d", servicePID) return nil } // StopRosettaX87Service stops the running RosettaX87 service func StopRosettaX87Service(myWindow fyne.Window, updateAllStatuses func()) { - log.Println("Stopping RosettaX87 service...") + log.Info().Msg("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.Printf("Failed to send SIGTERM to process: %v", err) + log.Info().Msgf("Failed to send SIGTERM to process: %v", err) // Try SIGKILL as fallback err = serviceCmd.Process.Kill() if err != nil { - log.Printf("Failed to kill process: %v", err) + log.Info().Msgf("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.Println("RosettaX87 service stopped") + log.Info().Msg("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.Println("Cleaning up RosettaX87 service on application exit...") + log.Info().Msg("Cleaning up RosettaX87 service on application exit...") CleanupExistingServices() ServiceRunning = false serviceCmd = nil diff --git a/pkg/ui/components.go b/pkg/ui/components.go index 5464c2e..cf3578b 100644 --- a/pkg/ui/components.go +++ b/pkg/ui/components.go @@ -1,11 +1,11 @@ package ui import ( + "github.com/rs/zerolog/log" "net/url" "strings" "time" - "epochsilicon/pkg/debug" "epochsilicon/pkg/launcher" "epochsilicon/pkg/patching" "epochsilicon/pkg/service" @@ -27,7 +27,7 @@ func createOptionsComponents() { prefs, _ := utils.LoadPrefs() prefs.EnableMetalHud = checked utils.SavePrefs(prefs) - debug.Printf("Metal HUD enabled: %v", launcher.EnableMetalHud) + log.Debug().Msgf("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) - debug.Printf("Show terminal normally: %v", checked) + log.Debug().Msgf("Show terminal normally: %v", checked) }) showTerminalCheckbox.SetChecked(prefs.ShowTerminalNormally) @@ -47,7 +47,7 @@ func createOptionsComponents() { prefs, _ := utils.LoadPrefs() prefs.AutoDeleteWdb = checked utils.SavePrefs(prefs) - debug.Printf("Auto-delete WDB enabled: %v", launcher.AutoDeleteWdb) + log.Debug().Msgf("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) - debug.Printf("Environment variables updated: %v", launcher.CustomEnvVars) + log.Debug().Msgf("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 { - debug.Printf("Error parsing git URL: %v", err) + log.Debug().Msgf("Error parsing git URL: %v", err) return } fyne.CurrentApp().OpenURL(parsedURL) @@ -198,7 +198,7 @@ func createWineRegistryComponents() { }() if err := utils.SetOptionAsAltEnabled(true); err != nil { - debug.Printf("Failed to enable Option-as-Alt mapping: %v", err) + log.Debug().Msgf("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 { - debug.Printf("Successfully enabled Option-as-Alt mapping") + log.Debug().Msgf("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 { - debug.Printf("Failed to disable Option-as-Alt mapping: %v", err) + log.Debug().Msgf("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 { - debug.Printf("Successfully disabled Option-as-Alt mapping") + log.Debug().Msgf("Successfully disabled Option-as-Alt mapping") // Update preferences prefs, _ := utils.LoadPrefs() prefs.RemapOptionAsAlt = false diff --git a/pkg/ui/layout.go b/pkg/ui/layout.go index 1b753f9..4f1319f 100644 --- a/pkg/ui/layout.go +++ b/pkg/ui/layout.go @@ -1,8 +1,8 @@ package ui import ( - "epochsilicon/pkg/debug" "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 { - debug.Printf("Warning: could not load logo: %v", err) + log.Debug().Msgf("Warning: could not load logo: %v", err) } // Create the logo image with a smaller fixed size since we have a header now diff --git a/pkg/ui/status.go b/pkg/ui/status.go index 693a525..6a23c9f 100644 --- a/pkg/ui/status.go +++ b/pkg/ui/status.go @@ -1,8 +1,8 @@ package ui import ( - "epochsilicon/pkg/debug" "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 { - debug.Printf("Failed to get download Epoch patches: %v", err) + log.Debug().Msgf("Failed to get download Epoch patches: %v", err) } if stats.Outdated == 0 { - debug.Println("Nothing is outdated") + log.Debug().Msg("Nothing is outdated") epochPatchesApplied = true } diff --git a/pkg/ui/updater.go b/pkg/ui/updater.go index 4f5c0c8..9d186c2 100644 --- a/pkg/ui/updater.go +++ b/pkg/ui/updater.go @@ -2,10 +2,10 @@ package ui import ( "fmt" + "github.com/rs/zerolog/log" "strings" "time" - "epochsilicon/pkg/debug" "epochsilicon/pkg/utils" "fyne.io/fyne/v2" @@ -105,7 +105,7 @@ func ShowUpdateDialog(updateInfo *utils.UpdateInfo, currentVersion string, myWin if err != nil { progressLabel.SetText(fmt.Sprintf("Download failed: %v", err)) - debug.Printf("Download failed: %v", err) + log.Debug().Msgf("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)) - debug.Printf("Installation failed: %v", err) + log.Debug().Msgf("Installation failed: %v", err) // Re-enable close button fyne.DoAndWait(func() { diff --git a/pkg/utils/keychain.go b/pkg/utils/keychain.go index 76f3259..d2bf5cd 100644 --- a/pkg/utils/keychain.go +++ b/pkg/utils/keychain.go @@ -2,8 +2,8 @@ package utils import ( "fmt" - "log" + "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.Println("Password saved securely to keychain") + log.Info().Msg("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.Println("Password removed from keychain") + log.Info().Msg("Password removed from keychain") return nil } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 177cbb9..974706d 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/rs/zerolog/log" "io" "net/http" "os" @@ -11,8 +12,6 @@ import ( "path/filepath" "strings" - "epochsilicon/pkg/debug" - "fyne.io/fyne/v2" "fyne.io/fyne/v2/dialog" ) @@ -104,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 { - debug.Printf("Executing AppleScript: %s", scriptString) + log.Debug().Msgf("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) - debug.Println(errMsg) + log.Debug().Msg(errMsg) return false } - debug.Printf("osascript output: %s", string(output)) + log.Debug().Msgf("osascript output: %s", string(output)) return true } @@ -264,14 +263,14 @@ func InstallUpdate(dmgPath string) error { } // Mount the DMG and parse the mount point from plist output - debug.Printf("Mounting DMG: %s", dmgPath) + log.Debug().Msgf("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)) } - debug.Printf("Mount output: %s", string(mountOutput)) + log.Debug().Msgf("Mount output: %s", string(mountOutput)) mountPoint := "" @@ -292,7 +291,7 @@ func InstallUpdate(dmgPath string) error { end := strings.Index(nextLine, "") if start >= 8 && end > start { mountPoint = nextLine[start:end] - debug.Printf("Found mount point in plist: %s", mountPoint) + log.Debug().Msgf("Found mount point in plist: %s", mountPoint) break } } @@ -301,7 +300,7 @@ func InstallUpdate(dmgPath string) error { // Fallback: try without -plist flag for simpler output if mountPoint == "" { - debug.Printf("Plist parsing failed, trying simple mount") + log.Debug().Msgf("Plist parsing failed, trying simple mount") // Unmount first if something was mounted exec.Command("hdiutil", "detach", dmgPath, "-force").Run() @@ -321,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] - debug.Printf("Found mount point in simple output: %s", mountPoint) + log.Debug().Msgf("Found mount point in simple output: %s", mountPoint) break } } @@ -336,11 +335,11 @@ func InstallUpdate(dmgPath string) error { return fmt.Errorf("could not find mount point. Mount output: %s", string(mountOutput)) } - debug.Printf("Using mount point: %s", mountPoint) + log.Debug().Msgf("Using mount point: %s", mountPoint) defer func() { // Unmount the DMG - debug.Printf("Unmounting DMG from: %s", mountPoint) + log.Debug().Msgf("Unmounting DMG from: %s", mountPoint) unmountCmd := exec.Command("hdiutil", "detach", mountPoint, "-force") unmountCmd.Run() }() @@ -354,7 +353,7 @@ func InstallUpdate(dmgPath string) error { newAppPath = exactPath } else { // Search for any .app bundle in the mount point - debug.Printf("EpochSilicon.app not found at exact path, searching for .app bundles") + log.Debug().Msgf("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) @@ -363,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()) - debug.Printf("Found .app bundle: %s", candidatePath) + log.Debug().Msgf("Found .app bundle: %s", candidatePath) newAppPath = candidatePath break } @@ -374,11 +373,11 @@ func InstallUpdate(dmgPath string) error { return fmt.Errorf("no .app bundle found in DMG at %s", mountPoint) } - debug.Printf("Found app to install: %s", newAppPath) + log.Debug().Msgf("Found app to install: %s", newAppPath) // Create backup of current app backupPath := currentAppPath + ".backup" - debug.Printf("Creating backup: %s -> %s", currentAppPath, backupPath) + log.Debug().Msgf("Creating backup: %s -> %s", currentAppPath, backupPath) // Remove old backup if it exists if PathExists(backupPath) { @@ -390,16 +389,16 @@ func InstallUpdate(dmgPath string) error { } // Remove current app - debug.Printf("Removing current app: %s", currentAppPath) + log.Debug().Msgf("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 - debug.Printf("Installing new app: %s -> %s", newAppPath, currentAppPath) + log.Debug().Msgf("Installing new app: %s -> %s", newAppPath, currentAppPath) if err := CopyDir(newAppPath, currentAppPath); err != nil { // Try to restore backup on failure - debug.Printf("Installation failed, restoring backup") + log.Debug().Msgf("Installation failed, restoring backup") os.RemoveAll(currentAppPath) CopyDir(backupPath, currentAppPath) return fmt.Errorf("failed to install new app: %v", err) @@ -408,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) { - debug.Printf("Setting executable permissions for: %s", executablePath) + log.Debug().Msgf("Setting executable permissions for: %s", executablePath) if err := os.Chmod(executablePath, 0755); err != nil { - debug.Printf("Warning: failed to set executable permissions: %v", err) + log.Debug().Msgf("Warning: failed to set executable permissions: %v", err) // Don't fail the entire update for this, but log it } } else { - debug.Printf("Warning: executable not found at expected path: %s", executablePath) + log.Debug().Msgf("Warning: executable not found at expected path: %s", executablePath) } // Remove backup on success os.RemoveAll(backupPath) - debug.Printf("Update installed successfully") + log.Debug().Msgf("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) { - debug.Printf("Testing DMG mount: %s", dmgPath) + log.Debug().Msgf("Testing DMG mount: %s", dmgPath) // Mount the DMG with verbose output to better parse mount point mountCmd := exec.Command("hdiutil", "attach", dmgPath, "-nobrowse", "-plist") @@ -435,7 +434,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { return "", "", fmt.Errorf("failed to mount DMG: %v, output: %s", err, string(mountOutput)) } - debug.Printf("Mount output: %s", string(mountOutput)) + log.Debug().Msgf("Mount output: %s", string(mountOutput)) // Parse mount output to get mount point mountPoint := "" @@ -460,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 == "" { - debug.Printf("First mount point detection failed, trying hdiutil info") + log.Debug().Msgf("First mount point detection failed, trying hdiutil info") infoCmd := exec.Command("hdiutil", "info", "-plist") infoOutput, infoErr := infoCmd.CombinedOutput() if infoErr == nil { @@ -481,7 +480,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { return "", "", fmt.Errorf("could not find mount point. Mount output: %s", string(mountOutput)) } - debug.Printf("Using mount point: %s", mountPoint) + log.Debug().Msgf("Using mount point: %s", mountPoint) // Find the app in the mounted DMG var newAppPath string @@ -492,7 +491,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { newAppPath = exactPath } else { // Search for any .app bundle in the mount point - debug.Printf("EpochSilicon.app not found at exact path, searching for .app bundles") + log.Debug().Msgf("EpochSilicon.app not found at exact path, searching for .app bundles") entries, err := os.ReadDir(mountPoint) if err != nil { // Unmount before returning error @@ -503,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()) - debug.Printf("Found .app bundle: %s", candidatePath) + log.Debug().Msgf("Found .app bundle: %s", candidatePath) newAppPath = candidatePath break } @@ -511,7 +510,7 @@ func TestDMGMount(dmgPath string) (string, string, error) { } // Unmount after testing - debug.Printf("Unmounting test DMG from: %s", mountPoint) + log.Debug().Msgf("Unmounting test DMG from: %s", mountPoint) exec.Command("hdiutil", "detach", mountPoint, "-force").Run() if newAppPath == "" { @@ -531,14 +530,14 @@ func CompareFileWithBundledResource(filePath, resourceName string) bool { // Get file info for the existing file fileInfo, err := os.Stat(filePath) if err != nil { - debug.Printf("Failed to stat file %s: %v", filePath, err) + log.Debug().Msgf("Failed to stat file %s: %v", filePath, err) return false } // Load the bundled resource resource, err := fyne.LoadResourceFromPath(resourceName) if err != nil { - debug.Printf("Failed to load bundled resource %s: %v", resourceName, err) + log.Debug().Msgf("Failed to load bundled resource %s: %v", resourceName, err) return false } @@ -546,7 +545,7 @@ func CompareFileWithBundledResource(filePath, resourceName string) bool { fileSize := fileInfo.Size() resourceSize := int64(len(resource.Content())) - debug.Printf("Comparing file sizes - %s: %d bytes vs bundled %s: %d bytes", + log.Debug().Msgf("Comparing file sizes - %s: %d bytes vs bundled %s: %d bytes", filePath, fileSize, resourceName, resourceSize) return fileSize == resourceSize diff --git a/pkg/utils/wine_registry.go b/pkg/utils/wine_registry.go index a746f2a..4bb844b 100644 --- a/pkg/utils/wine_registry.go +++ b/pkg/utils/wine_registry.go @@ -2,7 +2,7 @@ package utils import ( "fmt" - "log" + "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.Printf("Successfully enabled Option-as-Alt mapping in Wine registry (optimized)") + log.Info().Msgf("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.Printf("Successfully disabled Option-as-Alt mapping in Wine registry (optimized)") + log.Info().Msgf("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.Printf("Failed to get user home directory: %v", err) + log.Info().Msgf("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.Printf("CrossOver wine loader not found at: %s", wineLoaderPath) + log.Info().Msgf("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.Printf("Failed to get Wine registry path: %v", err) + log.Info().Msgf("Failed to get Wine registry path: %v", err) return false } if !PathExists(regPath) { - log.Printf("Wine user.reg file not found at: %s", regPath) + log.Info().Msgf("Wine user.reg file not found at: %s", regPath) return false } content, err := os.ReadFile(regPath) if err != nil { - log.Printf("Failed to read Wine registry file: %v", err) + log.Info().Msgf("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.Printf("Wine registry disable failed: %v", err) + log.Info().Msgf("Wine registry disable failed: %v", err) } err2 := setRegistryValuesFast(false) if err2 != nil { - log.Printf("File-based cleanup failed: %v", err2) + log.Info().Msgf("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.Printf("Successfully enabled Option-as-Alt mapping in Wine registry (fast method)") + log.Info().Msgf("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.Printf("Successfully disabled Option-as-Alt mapping in Wine registry (no file to modify)") + log.Info().Msgf("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.Printf("Successfully disabled Option-as-Alt mapping in Wine registry (fast method)") + log.Info().Msgf("Successfully disabled Option-as-Alt mapping in Wine registry (fast method)") return nil } -- 2.39.5 From a1f46438d061060f61329e3da64615db04c42e67 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Wed, 23 Jul 2025 08:59:16 -0700 Subject: [PATCH 2/6] start custom logger --- main.go | 19 +++--- pkg/launcher/launcher.go | 34 +++++----- pkg/launcher/recommended.go | 18 +++--- pkg/log/logging.go | 62 ++++++++++++++++++ pkg/patching/patching.go | 122 ++++++++++++++++++------------------ pkg/paths/paths.go | 16 ++--- pkg/service/service.go | 46 +++++++------- pkg/ui/components.go | 20 +++--- pkg/ui/layout.go | 4 +- pkg/ui/status.go | 6 +- pkg/ui/updater.go | 6 +- pkg/utils/keychain.go | 6 +- pkg/utils/utils.go | 64 +++++++++---------- pkg/utils/wine_registry.go | 26 ++++---- 14 files changed, 253 insertions(+), 196 deletions(-) create mode 100644 pkg/log/logging.go diff --git a/main.go b/main.go index 14a9e41..8307d9a 100644 --- a/main.go +++ b/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() }) diff --git a/pkg/launcher/launcher.go b/pkg/launcher/launcher.go index e12baee..ea5711b 100644 --- a/pkg/launcher/launcher.go +++ b/pkg/launcher/launcher.go @@ -41,7 +41,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { // Parse the shell command to extract components // The shellCmd format is: cd && - 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.") } } diff --git a/pkg/launcher/recommended.go b/pkg/launcher/recommended.go index b434326..be8a028 100644 --- a/pkg/launcher/recommended.go +++ b/pkg/launcher/recommended.go @@ -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 diff --git a/pkg/log/logging.go b/pkg/log/logging.go new file mode 100644 index 0000000..6f9f2da --- /dev/null +++ b/pkg/log/logging.go @@ -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...) +} diff --git a/pkg/patching/patching.go b/pkg/patching/patching.go index 766d623..f534f37 100644 --- a/pkg/patching/patching.go +++ b/pkg/patching/patching.go @@ -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 diff --git a/pkg/paths/paths.go b/pkg/paths/paths.go index 4be230d..740b4eb 100644 --- a/pkg/paths/paths.go +++ b/pkg/paths/paths.go @@ -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) } } } diff --git a/pkg/service/service.go b/pkg/service/service.go index b547cb6..8b3ab1c 100644 --- a/pkg/service/service.go +++ b/pkg/service/service.go @@ -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 diff --git a/pkg/ui/components.go b/pkg/ui/components.go index cf3578b..c176c7e 100644 --- a/pkg/ui/components.go +++ b/pkg/ui/components.go @@ -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 diff --git a/pkg/ui/layout.go b/pkg/ui/layout.go index 4f1319f..c98a46f 100644 --- a/pkg/ui/layout.go +++ b/pkg/ui/layout.go @@ -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 diff --git a/pkg/ui/status.go b/pkg/ui/status.go index 6a23c9f..9dc6620 100644 --- a/pkg/ui/status.go +++ b/pkg/ui/status.go @@ -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 } diff --git a/pkg/ui/updater.go b/pkg/ui/updater.go index 9d186c2..3750513 100644 --- a/pkg/ui/updater.go +++ b/pkg/ui/updater.go @@ -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() { diff --git a/pkg/utils/keychain.go b/pkg/utils/keychain.go index d2bf5cd..81b1ce4 100644 --- a/pkg/utils/keychain.go +++ b/pkg/utils/keychain.go @@ -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 } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 974706d..93e4d59 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -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, "") 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 diff --git a/pkg/utils/wine_registry.go b/pkg/utils/wine_registry.go index 4bb844b..eb4c46e 100644 --- a/pkg/utils/wine_registry.go +++ b/pkg/utils/wine_registry.go @@ -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 } -- 2.39.5 From 087923a13f77fe6a4ecd89e62b964f9df08e837d Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Thu, 24 Jul 2025 06:21:56 -0700 Subject: [PATCH 3/6] more logging changes --- FyneApp.toml | 2 +- main.go | 3 +++ pkg/launcher/launcher.go | 2 +- pkg/launcher/recommended.go | 2 +- pkg/log/logging.go | 38 ++++++++++++++++++++++++++++++++----- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/FyneApp.toml b/FyneApp.toml index 0136499..0a72c3d 100644 --- a/FyneApp.toml +++ b/FyneApp.toml @@ -3,4 +3,4 @@ Name = "EpochSilicon" ID = "com.burkey.epochsilicon" Version = "1.0.0" - Build = 3 + Build = 4 diff --git a/main.go b/main.go index 8307d9a..00f7433 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,9 @@ import ( const appVersion = "1.0.1" func main() { + log.SetupLogging() + defer log.Close() + PEApp := app.NewWithID("com.burkey.epochsilicon") PEWindow := PEApp.NewWindow("EpochSilicon v" + appVersion) PEWindow.Resize(fyne.NewSize(650, 500)) diff --git a/pkg/launcher/launcher.go b/pkg/launcher/launcher.go index ea5711b..a2ed4bc 100644 --- a/pkg/launcher/launcher.go +++ b/pkg/launcher/launcher.go @@ -2,8 +2,8 @@ package launcher import ( "bufio" + "epochsilicon/pkg/log" "fmt" - "github.com/rs/zerolog/log" "os" "os/exec" "path/filepath" diff --git a/pkg/launcher/recommended.go b/pkg/launcher/recommended.go index be8a028..d2c8c47 100644 --- a/pkg/launcher/recommended.go +++ b/pkg/launcher/recommended.go @@ -1,8 +1,8 @@ package launcher import ( + "epochsilicon/pkg/log" "fmt" - "github.com/rs/zerolog/log" "os" "path/filepath" "regexp" diff --git a/pkg/log/logging.go b/pkg/log/logging.go index 6f9f2da..fa2b491 100644 --- a/pkg/log/logging.go +++ b/pkg/log/logging.go @@ -3,14 +3,42 @@ package log import ( "github.com/rs/zerolog" "os" + "path/filepath" ) -var logger zerolog.Logger +const ApplicationSupportDir = "/Library/Application Support/EpochSilicon" -func init() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - zerolog.SetGlobalLevel(zerolog.InfoLevel) - logger = zerolog.New(os.Stdout).With().Timestamp().Logger() +var ( + logger zerolog.Logger + logFilePointer *os.File + logFilePath = filepath.Join(ApplicationSupportDir, "EpochSilicon.log") +) + +func SetupLogging() { + logFilePointer = nil + ToConsole(zerolog.InfoLevel) +} + +func Close() { + if logFilePointer != nil { + logFilePointer.Close() + } +} + +func ToFile(level zerolog.Level) { + Close() + var err error + logFilePointer, err = os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + if err != nil { + logger.Error().Msg(err.Error()) + return + } + logger = zerolog.New(logFilePointer).With().Timestamp().Logger().Level(level) +} + +func ToConsole(level zerolog.Level) { + Close() + logger = zerolog.New(os.Stdout).With().Timestamp().Logger().Level(level) } func Debug(msg string) { -- 2.39.5 From 67daf7027d2df6e80f31dc5574bdb9167300ada5 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Thu, 24 Jul 2025 06:53:02 -0700 Subject: [PATCH 4/6] updater error logs --- go.mod | 6 +++--- go.sum | 6 ++++++ pkg/patching/patching.go | 22 +++++++++++++--------- pkg/ui/status.go | 15 ++++++++------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 28b06a7..334edaf 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,8 @@ toolchain go1.24.5 require ( fyne.io/fyne/v2 v2.6.1 - git.burkey.co/eburk/epochcli v0.0.0-20250721041733-516a1f9b570e + git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16 + github.com/rs/zerolog v1.34.0 github.com/zalando/go-keyring v0.2.6 howett.net/plist v1.0.1 ) @@ -38,12 +39,11 @@ require ( github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rs/zerolog v1.34.0 // indirect github.com/rymdport/portal v0.4.2 // indirect github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect github.com/stretchr/testify v1.10.0 // indirect - github.com/yuin/goldmark v1.7.12 // indirect + github.com/yuin/goldmark v1.7.13 // indirect golang.org/x/image v0.29.0 // indirect golang.org/x/net v0.42.0 // indirect golang.org/x/sys v0.34.0 // indirect diff --git a/go.sum b/go.sum index feb5a61..60e88e8 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,10 @@ git.burkey.co/eburk/epochcli v0.0.0-20250721041340-6b6dbdda99e2 h1:89rNJ5p6gYJPZ git.burkey.co/eburk/epochcli v0.0.0-20250721041340-6b6dbdda99e2/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= git.burkey.co/eburk/epochcli v0.0.0-20250721041733-516a1f9b570e h1:WN1jlnC3sc/2ix70bzMPpzsPdsE/pqUIR/Vw8cVEkw8= git.burkey.co/eburk/epochcli v0.0.0-20250721041733-516a1f9b570e/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= +git.burkey.co/eburk/epochcli v0.0.0-20250723150949-7f454dc63253 h1:g/+ztvoMIJD80jSn7V388T6D8KMTqvZDcjc0B482e3A= +git.burkey.co/eburk/epochcli v0.0.0-20250723150949-7f454dc63253/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= +git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16 h1:L67RkxnNIpCoqy7dpN4XdPdNxQEFwA0/B2gisvUwNow= +git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= @@ -122,6 +126,8 @@ github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY= github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= +github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= diff --git a/pkg/patching/patching.go b/pkg/patching/patching.go index f534f37..777c8c7 100644 --- a/pkg/patching/patching.go +++ b/pkg/patching/patching.go @@ -205,20 +205,24 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { dialog.ShowInformation("Downloading patches", "Downloading patches for Project Epoch, this will take some time. Please wait until the status changes to \"Patched\"", myWindow) paths.DownloadingPatches = true go func() { - stats, err := epoch.Update(paths.EpochPath, true, true, false) - if err != nil { - errMsg := fmt.Sprintf("failed to update Epoch files: %v", err) + log.Debug("Attempting to download patches...") + stats := epoch.Update(paths.EpochPath, true, true, false) + if stats.Error != nil { + errMsg := fmt.Sprintf("failed to update Epoch files: %v", stats.Error) fyne.Do(func() { dialog.ShowError(errors.New(errMsg), myWindow) }) - paths.DownloadingPatches = false log.Error(errMsg) + } else { + for _, msg := range stats.LogMessages { + log.Debug(msg) + } + 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) + }) } - 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) - }) fyne.DoAndWait(func() { paths.DownloadingPatches = false updateAllStatuses() diff --git a/pkg/ui/status.go b/pkg/ui/status.go index 9dc6620..ae4bc47 100644 --- a/pkg/ui/status.go +++ b/pkg/ui/status.go @@ -108,13 +108,14 @@ func updateEpochStatus() { // Check for Epoch-specific files epochPatchesApplied := false - stats, err := epoch.Update(paths.EpochPath, false, true, true) - if err != nil { - log.Debugf("Failed to get download Epoch patches: %v", err) - } - if stats.Outdated == 0 { - log.Debug("Nothing is outdated") - epochPatchesApplied = true + stats := epoch.Update(paths.EpochPath, false, true, true) + if stats.Error != nil { + log.Error(stats.Error.Error()) + } else { + if stats.Outdated == 0 { + log.Debug("Everything is up-to-date!") + epochPatchesApplied = true + } } // Check if patched files have the correct size (matches bundled versions) -- 2.39.5 From caf20043888b5f53ab6c7f6366238111d75cd33f Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Thu, 24 Jul 2025 07:23:29 -0700 Subject: [PATCH 5/6] more logs --- FyneApp.toml | 2 +- go.mod | 2 +- go.sum | 2 ++ pkg/launcher/launcher.go | 7 +++---- pkg/log/logging.go | 5 +++-- pkg/patching/patching.go | 2 +- pkg/ui/status.go | 1 - 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/FyneApp.toml b/FyneApp.toml index 0a72c3d..e6a593a 100644 --- a/FyneApp.toml +++ b/FyneApp.toml @@ -3,4 +3,4 @@ Name = "EpochSilicon" ID = "com.burkey.epochsilicon" Version = "1.0.0" - Build = 4 + Build = 9 diff --git a/go.mod b/go.mod index 334edaf..a5b08b3 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.24.5 require ( fyne.io/fyne/v2 v2.6.1 - git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16 + git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b github.com/rs/zerolog v1.34.0 github.com/zalando/go-keyring v0.2.6 howett.net/plist v1.0.1 diff --git a/go.sum b/go.sum index 60e88e8..e77ad1e 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ git.burkey.co/eburk/epochcli v0.0.0-20250723150949-7f454dc63253 h1:g/+ztvoMIJD80 git.burkey.co/eburk/epochcli v0.0.0-20250723150949-7f454dc63253/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16 h1:L67RkxnNIpCoqy7dpN4XdPdNxQEFwA0/B2gisvUwNow= git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= +git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b h1:fPDSiwJI3PzaU5utiurrnpNIv6IYj+CcUmwCzVcunsU= +git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= diff --git a/pkg/launcher/launcher.go b/pkg/launcher/launcher.go index a2ed4bc..22a1ef3 100644 --- a/pkg/launcher/launcher.go +++ b/pkg/launcher/launcher.go @@ -16,10 +16,9 @@ import ( "fyne.io/fyne/v2/dialog" ) -var EnableMetalHud = false // Default to disabled -var CustomEnvVars = "" // Custom environment variables -var EnableVanillaTweaks = false // Default to disabled -var AutoDeleteWdb = false // Default to disabled +var EnableMetalHud = false // Default to disabled +var CustomEnvVars = "" // Custom environment variables +var AutoDeleteWdb = false // Default to disabled // Terminal state management var ( diff --git a/pkg/log/logging.go b/pkg/log/logging.go index fa2b491..78da6e4 100644 --- a/pkg/log/logging.go +++ b/pkg/log/logging.go @@ -16,7 +16,7 @@ var ( func SetupLogging() { logFilePointer = nil - ToConsole(zerolog.InfoLevel) + ToConsole(zerolog.DebugLevel) } func Close() { @@ -33,7 +33,8 @@ func ToFile(level zerolog.Level) { logger.Error().Msg(err.Error()) return } - logger = zerolog.New(logFilePointer).With().Timestamp().Logger().Level(level) + multi := zerolog.MultiLevelWriter(logFilePointer, os.Stdout) + logger = zerolog.New(multi).With().Timestamp().Logger().Level(level) } func ToConsole(level zerolog.Level) { diff --git a/pkg/patching/patching.go b/pkg/patching/patching.go index 777c8c7..54f8dae 100644 --- a/pkg/patching/patching.go +++ b/pkg/patching/patching.go @@ -204,8 +204,8 @@ func PatchEpoch(myWindow fyne.Window, updateAllStatuses func()) { // 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) paths.DownloadingPatches = true + log.Debug("Attempting to download Epoch patches...") go func() { - log.Debug("Attempting to download patches...") stats := epoch.Update(paths.EpochPath, true, true, false) if stats.Error != nil { errMsg := fmt.Sprintf("failed to update Epoch files: %v", stats.Error) diff --git a/pkg/ui/status.go b/pkg/ui/status.go index ae4bc47..d839d85 100644 --- a/pkg/ui/status.go +++ b/pkg/ui/status.go @@ -113,7 +113,6 @@ func updateEpochStatus() { log.Error(stats.Error.Error()) } else { if stats.Outdated == 0 { - log.Debug("Everything is up-to-date!") epochPatchesApplied = true } } -- 2.39.5 From 0b80c2d71354b35623817a5430527c4c671c0ec7 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Thu, 24 Jul 2025 08:29:34 -0700 Subject: [PATCH 6/6] log to file --- FyneApp.toml | 2 +- go.mod | 1 + go.sum | 53 +------------------- main.go | 1 - pkg/launcher/launcher.go | 33 ++++--------- pkg/log/logging.go | 101 +++++++++++++++++++++++++++++---------- pkg/ui/components.go | 15 ++++++ pkg/ui/popup.go | 9 ++-- pkg/ui/variables.go | 7 +-- pkg/utils/prefs.go | 1 + 10 files changed, 113 insertions(+), 110 deletions(-) diff --git a/FyneApp.toml b/FyneApp.toml index e6a593a..5a28b63 100644 --- a/FyneApp.toml +++ b/FyneApp.toml @@ -3,4 +3,4 @@ Name = "EpochSilicon" ID = "com.burkey.epochsilicon" Version = "1.0.0" - Build = 9 + Build = 14 diff --git a/go.mod b/go.mod index a5b08b3..ee85232 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b github.com/rs/zerolog v1.34.0 github.com/zalando/go-keyring v0.2.6 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 howett.net/plist v1.0.1 ) diff --git a/go.sum b/go.sum index e77ad1e..69553c9 100644 --- a/go.sum +++ b/go.sum @@ -1,48 +1,27 @@ -al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho= -al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeXHA= al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= fyne.io/fyne/v2 v2.6.1 h1:kjPJD4/rBS9m2nHJp+npPSuaK79yj6ObMTuzR6VQ1Is= fyne.io/fyne/v2 v2.6.1/go.mod h1:YZt7SksjvrSNJCwbWFV32WON3mE1Sr7L41D29qMZ/lU= fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg= fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs= -git.burkey.co/eburk/epochcli v0.0.0-20250721033741-54cc1d9a552e h1:TiiZEnc7E3/wJ86qHckGoNht0snSUpQyY2cjxRUSs3Q= -git.burkey.co/eburk/epochcli v0.0.0-20250721033741-54cc1d9a552e/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= -git.burkey.co/eburk/epochcli v0.0.0-20250721041340-6b6dbdda99e2 h1:89rNJ5p6gYJPZkeJM8nyRHMMgHErfVz8SdLcGiqEyBM= -git.burkey.co/eburk/epochcli v0.0.0-20250721041340-6b6dbdda99e2/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= -git.burkey.co/eburk/epochcli v0.0.0-20250721041733-516a1f9b570e h1:WN1jlnC3sc/2ix70bzMPpzsPdsE/pqUIR/Vw8cVEkw8= -git.burkey.co/eburk/epochcli v0.0.0-20250721041733-516a1f9b570e/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= -git.burkey.co/eburk/epochcli v0.0.0-20250723150949-7f454dc63253 h1:g/+ztvoMIJD80jSn7V388T6D8KMTqvZDcjc0B482e3A= -git.burkey.co/eburk/epochcli v0.0.0-20250723150949-7f454dc63253/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= -git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16 h1:L67RkxnNIpCoqy7dpN4XdPdNxQEFwA0/B2gisvUwNow= -git.burkey.co/eburk/epochcli v0.0.0-20250724134158-4d47056e5b16/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b h1:fPDSiwJI3PzaU5utiurrnpNIv6IYj+CcUmwCzVcunsU= git.burkey.co/eburk/epochcli v0.0.0-20250724135717-365171fddc6b/go.mod h1:DgybCn9/LpJwvkrsyea9N2nWy/wuDgo6jkpOWYkTH3c= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8= github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fyne-io/gl-js v0.1.0 h1:8luJzNs0ntEAJo+8x8kfUOXujUlP8gB3QMOxO2mUdpM= -github.com/fyne-io/gl-js v0.1.0/go.mod h1:ZcepK8vmOYLu96JoxbCKJy2ybr+g1pTnaBDdl7c3ajI= github.com/fyne-io/gl-js v0.2.0 h1:+EXMLVEa18EfkXBVKhifYB6OGs3HwKO3lUElA0LlAjs= github.com/fyne-io/gl-js v0.2.0/go.mod h1:ZcepK8vmOYLu96JoxbCKJy2ybr+g1pTnaBDdl7c3ajI= -github.com/fyne-io/glfw-js v0.2.0 h1:8GUZtN2aCoTPNqgRDxK5+kn9OURINhBEBc7M4O1KrmM= -github.com/fyne-io/glfw-js v0.2.0/go.mod h1:Ri6te7rdZtBgBpxLW19uBpp3Dl6K9K/bRaYdJ22G8Jk= github.com/fyne-io/glfw-js v0.3.0 h1:d8k2+Y7l+zy2pc7wlGRyPfTgZoqDf3AI4G+2zOWhWUk= github.com/fyne-io/glfw-js v0.3.0/go.mod h1:Ri6te7rdZtBgBpxLW19uBpp3Dl6K9K/bRaYdJ22G8Jk= github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA= @@ -51,14 +30,10 @@ github.com/fyne-io/oksvg v0.1.0 h1:7EUKk3HV3Y2E+qypp3nWqMXD7mum0hCw2KEGhI1fnBw= github.com/fyne-io/oksvg v0.1.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI= github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA= github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728 h1:RkGhqHxEVAvPM0/R+8g7XRwQnHatO0KAuVcwHo8q9W8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20250301202403-da16c1255728/go.mod h1:SyRD8YfuKk+ZXlDqYiqe1qMSqjNgtHzBTG810KUagMc= github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc= github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU= -github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8= -github.com/go-text/typesetting v0.2.1/go.mod h1:mTOxEwasOFpAMBjEQDhdWRckoLLeI/+qrQeBCTGEt6M= github.com/go-text/typesetting v0.3.0 h1:OWCgYpp8njoxSRpwrdd1bQOxdjOXDj9Rqart9ML4iF4= github.com/go-text/typesetting v0.3.0/go.mod h1:qjZLkhRgOEYMhU9eHBr3AR4sfnGJvOXNLt8yRAySFuY= github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC+94v2xrb1PoS4NIDe7DGYtLnU2wWiQe9a1B1c0= @@ -72,12 +47,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/hack-pad/go-indexeddb v0.3.2 h1:DTqeJJYc1usa45Q5r52t01KhvlSN02+Oq+tQbSBI91A= github.com/hack-pad/go-indexeddb v0.3.2/go.mod h1:QvfTevpDVlkfomY498LhstjwbPW6QC4VC/lxYb0Kom0= -github.com/hack-pad/safejs v0.1.0 h1:qPS6vjreAqh2amUqj4WNG1zIw7qlRQJ9K10eDKMCnE8= -github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio= github.com/hack-pad/safejs v0.1.1 h1:d5qPO0iQ7h2oVtpzGnLExE+Wn9AtytxIfltcS2b9KD8= github.com/hack-pad/safejs v0.1.1/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio= -github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08 h1:wMeVzrPO3mfHIWLZtDcSaGAe2I4PW9B/P5nMkRSwCAc= -github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o= github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade h1:FmusiCI1wHw+XQbvL9M+1r/C3SPqKrmBaIOYwVfQoDE= github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -94,8 +65,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD0D1vHk= -github.com/nicksnyder/go-i18n/v2 v2.5.1/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ= github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ= github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= @@ -108,55 +77,37 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= -github.com/rymdport/portal v0.4.1 h1:2dnZhjf5uEaeDjeF/yBIeeRo6pNI2QAKm7kq1w/kbnA= -github.com/rymdport/portal v0.4.1/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4= github.com/rymdport/portal v0.4.2 h1:7jKRSemwlTyVHHrTGgQg7gmNPJs88xkbKcIL3NlcmSU= github.com/rymdport/portal v0.4.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE= github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= -github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY= -github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= -golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= -golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= golang.org/x/image v0.29.0 h1:HcdsyR4Gsuys/Axh0rDEmlBmB68rW1U9BUdB3UVHsas= golang.org/x/image v0.29.0/go.mod h1:RVJROnf3SLK8d26OW91j4FrIHGbsJ8QnbEocVTOWQDA= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= diff --git a/main.go b/main.go index 00f7433..bbb6376 100644 --- a/main.go +++ b/main.go @@ -14,7 +14,6 @@ const appVersion = "1.0.1" func main() { log.SetupLogging() - defer log.Close() PEApp := app.NewWithID("com.burkey.epochsilicon") PEWindow := PEApp.NewWindow("EpochSilicon v" + appVersion) diff --git a/pkg/launcher/launcher.go b/pkg/launcher/launcher.go index 22a1ef3..dd7a071 100644 --- a/pkg/launcher/launcher.go +++ b/pkg/launcher/launcher.go @@ -70,7 +70,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { scanner := bufio.NewScanner(stdout) for scanner.Scan() { line := scanner.Text() - log.Debugf("GAME STDOUT: %s", line) + log.WineLoggerStdout(line) } }() @@ -78,7 +78,7 @@ func runGameIntegrated(parentWindow fyne.Window, shellCmd string) error { scanner := bufio.NewScanner(stderr) for scanner.Scan() { line := scanner.Text() - log.Debugf("GAME STDERR: %s", line) + log.WineLoggerStderr(line) } }() @@ -200,29 +200,12 @@ func continueLaunch(myWindow fyne.Window, wowExePath string) { utils.QuotePathForShell(wineloader2Path), utils.QuotePathForShell(wowExePath)) - // Check user preference for terminal display - prefs, _ := utils.LoadPrefs() - - if prefs.ShowTerminalNormally { - // Use the old method with external Terminal.app - escapedShellCmd := utils.EscapeStringForAppleScript(shellCmd) - cmd2Script := fmt.Sprintf("tell application \"Terminal\" to do script \"%s\"", escapedShellCmd) - - log.Debug("Executing WoW launch command via AppleScript...") - if !utils.RunOsascript(cmd2Script, myWindow) { - return - } - - log.Debug("Launch command executed. Check the new terminal window.") - } else { - // Use 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("Game launched with integrated terminal. Check the application logs for output.") + // Use 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 } } diff --git a/pkg/log/logging.go b/pkg/log/logging.go index 78da6e4..0376ab5 100644 --- a/pkg/log/logging.go +++ b/pkg/log/logging.go @@ -2,44 +2,87 @@ package log import ( "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "gopkg.in/natefinch/lumberjack.v2" + "io" "os" "path/filepath" ) -const ApplicationSupportDir = "/Library/Application Support/EpochSilicon" - var ( - logger zerolog.Logger - logFilePointer *os.File - logFilePath = filepath.Join(ApplicationSupportDir, "EpochSilicon.log") + logger zerolog.Logger + wineLogger zerolog.Logger ) func SetupLogging() { - logFilePointer = nil - ToConsole(zerolog.DebugLevel) -} - -func Close() { - if logFilePointer != nil { - logFilePointer.Close() - } -} - -func ToFile(level zerolog.Level) { - Close() - var err error - logFilePointer, err = os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + // App logs + path, err := getLogfilePath() if err != nil { - logger.Error().Msg(err.Error()) + log.Error().Err(err).Str("path", path).Msg("Failed to get log path") return } - multi := zerolog.MultiLevelWriter(logFilePointer, os.Stdout) - logger = zerolog.New(multi).With().Timestamp().Logger().Level(level) + + var mw io.Writer + l := createLogWriter(path, 10, 3) + if l != nil { + mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout}, l) + } else { + mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout}) + } + logger = zerolog.New(mw).With().Timestamp().Logger() + SetLevelInfo() + + // Wine logs + wineLogPath, err := getWineLogfilePath() + if err != nil { + Errorf("Failed to get wine log path: %v", err) + return + } + l = createLogWriter(wineLogPath, 25, 1) + if l != nil { + mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout}, l) + } else { + mw = io.MultiWriter(zerolog.ConsoleWriter{Out: os.Stdout}) + } + wineLogger = zerolog.New(mw).With().Timestamp().Logger() + wineLogger.Level(zerolog.InfoLevel) } -func ToConsole(level zerolog.Level) { - Close() - logger = zerolog.New(os.Stdout).With().Timestamp().Logger().Level(level) +func createLogWriter(path string, maxSize int, maxBackups int) io.Writer { + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + log.Error().Err(err).Str("path", path).Msg("Failed to create log path") + return nil + } + + return &lumberjack.Logger{ + Filename: path, + MaxSize: maxSize, + MaxBackups: maxBackups, + } +} + +func SetLevelDebug() { + logger.Level(zerolog.DebugLevel) +} + +func SetLevelInfo() { + logger.Level(zerolog.InfoLevel) +} + +func getLogfilePath() (string, error) { + dir, err := os.UserConfigDir() + if err != nil { + return "", err + } + return filepath.Join(dir, "EpochSilicon", "epochsilicon.log"), nil +} + +func getWineLogfilePath() (string, error) { + dir, err := os.UserConfigDir() + if err != nil { + return "", err + } + return filepath.Join(dir, "EpochSilicon", "epochsilicon.log"), nil } func Debug(msg string) { @@ -89,3 +132,11 @@ func Panic(msg string) { func Panicf(format string, args ...interface{}) { logger.Panic().Msgf(format, args...) } + +func WineLoggerStdout(msg string) { + wineLogger.Info().Msgf("STDOUT: %s", msg) +} + +func WineLoggerStderr(msg string) { + wineLogger.Info().Msgf("STDERR: %s", msg) +} diff --git a/pkg/ui/components.go b/pkg/ui/components.go index c176c7e..dbb18b7 100644 --- a/pkg/ui/components.go +++ b/pkg/ui/components.go @@ -41,6 +41,21 @@ func createOptionsComponents() { }) showTerminalCheckbox.SetChecked(prefs.ShowTerminalNormally) + advancedLoggingCheckbox = widget.NewCheck("Advanced Logging", func(checked bool) { + // Save to preferences + prefs, _ := utils.LoadPrefs() + prefs.AdvancedLogging = checked + utils.SavePrefs(prefs) + log.Debugf("Advanced logging set to %v", checked) + + if checked { + log.SetLevelDebug() + } else { + log.SetLevelInfo() + } + }) + advancedLoggingCheckbox.SetChecked(prefs.AdvancedLogging) + autoDeleteWdbCheckbox = widget.NewCheck("Auto-delete WDB directory on launch", func(checked bool) { launcher.AutoDeleteWdb = checked // Save to preferences diff --git a/pkg/ui/popup.go b/pkg/ui/popup.go index 294ae81..fafdac1 100644 --- a/pkg/ui/popup.go +++ b/pkg/ui/popup.go @@ -30,6 +30,7 @@ func showOptionsPopup() { generalContainer := container.NewVBox( generalTitle, widget.NewSeparator(), + advancedLoggingCheckbox, metalHudCheckbox, showTerminalCheckbox, autoDeleteWdbCheckbox, @@ -222,11 +223,11 @@ func showTroubleshootingPopup() { troubleshootingCloseButton = widget.NewButton("Close", func() {}) popupContent := container.NewBorder( - nil, // top + nil, // top container.NewCenter(troubleshootingCloseButton), // bottom - nil, // left - nil, // right - container.NewPadded(scrollContainer), // center + nil, // left + nil, // right + container.NewPadded(scrollContainer), // center ) windowSize := currentWindow.Content().Size() diff --git a/pkg/ui/variables.go b/pkg/ui/variables.go index 86c3813..ed21ff4 100644 --- a/pkg/ui/variables.go +++ b/pkg/ui/variables.go @@ -28,9 +28,10 @@ var ( stopServiceButton *widget.Button // Option checkboxes - metalHudCheckbox *widget.Check - showTerminalCheckbox *widget.Check - autoDeleteWdbCheckbox *widget.Check + metalHudCheckbox *widget.Check + showTerminalCheckbox *widget.Check + autoDeleteWdbCheckbox *widget.Check + advancedLoggingCheckbox *widget.Check // Recommended settings button applyRecommendedSettingsButton *widget.Button diff --git a/pkg/utils/prefs.go b/pkg/utils/prefs.go index f373b54..51d9a9c 100644 --- a/pkg/utils/prefs.go +++ b/pkg/utils/prefs.go @@ -16,6 +16,7 @@ type UserPrefs struct { RemapOptionAsAlt bool `json:"remap_option_as_alt"` AutoDeleteWdb bool `json:"auto_delete_wdb"` EnableMetalHud bool `json:"enable_metal_hud"` + AdvancedLogging bool `json:"advanced_logging"` } func getPrefsPath() (string, error) { -- 2.39.5