From 1275914fb15e74b020d018bcdab3873895a119b2 Mon Sep 17 00:00:00 2001 From: Aiden Fine Date: Tue, 3 Mar 2026 10:28:58 -0500 Subject: [PATCH 1/2] replace log with zap logger --- foreman-builder/cmd/create.go | 17 ++++++++--------- foreman-builder/cmd/delete.go | 10 +++++----- foreman-builder/cmd/list.go | 3 +-- foreman-builder/cmd/sync.go | 6 +++--- foreman-builder/yml.go | 3 +-- go.mod | 2 ++ go.sum | 15 ++++++++++++++- main.go | 19 +++++++++---------- 8 files changed, 43 insertions(+), 32 deletions(-) diff --git a/foreman-builder/cmd/create.go b/foreman-builder/cmd/create.go index 209ff37..8732318 100644 --- a/foreman-builder/cmd/create.go +++ b/foreman-builder/cmd/create.go @@ -3,7 +3,6 @@ package cmd import ( "bufio" "fmt" - "log" "os" "os/exec" "os/user" @@ -38,7 +37,7 @@ var createCmd = &cobra.Command{ func runCreate() { currentUser, err := user.Current() if err != nil { - log.Fatalf("Failed to get current user: %s", err) + foremanbuilder.Logger.Fatalf("Failed to get current user: %s", err) } username := currentUser.Username fmt.Println("Username:", username) @@ -64,11 +63,11 @@ func runCreate() { // fmt.Println("Selected Shell", selectedShell) - log.Printf("Starting enviornment creation ") + foremanbuilder.Logger.Info("Starting environment creation") config, err := foremanbuilder.GetYmlValues("./config.yml") if err != nil { - log.Printf("No config file found skipping...") + foremanbuilder.Logger.Info("No config file found, skipping") } data := foremanbuilder.OrbstackConfigData{ @@ -80,19 +79,19 @@ func runCreate() { home, err := os.UserHomeDir() if err != nil { - log.Fatalf("Failed to get home directory: %v", err) + foremanbuilder.Logger.Fatalf("Failed to get home directory: %v", err) } confsDir := filepath.Join(home, ".foreman-builder", "confs") if err := os.MkdirAll(confsDir, 0755); err != nil { - log.Fatalf("Failed to create confs directory: %v", err) + foremanbuilder.Logger.Fatalf("Failed to create confs directory: %v", err) } pathName := filepath.Join(confsDir, fmt.Sprintf("orbstack-foreman-%s.yml", data.Username)) fmt.Println("using", pathName) err = foremanbuilder.GenerateContainerConfig(data, pathName) if err != nil { - log.Fatal(err) + foremanbuilder.Logger.Fatal(err) } // run command to create container @@ -102,13 +101,13 @@ func runCreate() { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - log.Fatalf("Error creating container: %s", err) + foremanbuilder.Logger.Fatalf("Error creating container: %s", err) } fmt.Println("Container has been created!") err = foremanbuilder.AppendToFile(filepath.Join(home, ".foreman-builder/containers"), containerName) if err != nil { - log.Println("Failed to write container to container file") + foremanbuilder.Logger.Error("Failed to write container to container file") } } diff --git a/foreman-builder/cmd/delete.go b/foreman-builder/cmd/delete.go index a57a4db..4e11e39 100644 --- a/foreman-builder/cmd/delete.go +++ b/foreman-builder/cmd/delete.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "log" "os" "os/exec" "path/filepath" @@ -17,7 +16,8 @@ var deleteCmd = &cobra.Command{ Short: "Delete container via name.", Run: func(cmd *cobra.Command, args []string) { if len(args) < 1 || len(args) > 1 { - log.Fatalf("Arg Error: Got %d args, when 1 was expected \n", len(args)) + foremanbuilder.Logger.Errorf("Arg Error: Got %d args, when 1 was expected", len(args)) + fmt.Printf("Arg Error: Got %d args, when 1 was expected \n", len(args)) os.Exit(1) } containerName := args[0] @@ -31,20 +31,20 @@ func runDelete(containerName string) { // check if item actually exists first AND foreman-builder created it home, err := os.UserHomeDir() if err != nil { - log.Panicf("Failed to get home directory: %v\n", err) + foremanbuilder.Logger.Fatalf("Failed to get home directory: %v", err) } dotFolderPath := filepath.Join(home, ".foreman-builder") containersPath := filepath.Join(dotFolderPath, "containers") containers, err := foremanbuilder.GetAllLines(containersPath) if !slices.Contains(containers, containerName) { - log.Fatalf("%s was not created with foreman-builder, foreman-builder will not delete it", containerName) + foremanbuilder.Logger.Fatalf("%s was not created with foreman-builder, foreman-builder will not delete it", containerName) os.Exit(1) } containerInfo, err := foremanbuilder.ContainerInfo(containerName) if err != nil { - log.Fatalf("Failed to get container info %v \n", err) + foremanbuilder.Logger.Fatalf("Failed to get container info: %v", err) os.Exit(1) } if containerInfo.State == "running" { diff --git a/foreman-builder/cmd/list.go b/foreman-builder/cmd/list.go index e4b658e..747ea94 100644 --- a/foreman-builder/cmd/list.go +++ b/foreman-builder/cmd/list.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "log" "os" "path/filepath" @@ -23,7 +22,7 @@ func runList() { fmt.Println("Foreman containers:") home, err := os.UserHomeDir() if err != nil { - log.Panicf("Failed to get home directory: %v\n", err) + foremanbuilder.Logger.Fatalf("Failed to get home directory: %v", err) } dotFolderPath := filepath.Join(home, ".foreman-builder") containersPath := filepath.Join(dotFolderPath, "containers") diff --git a/foreman-builder/cmd/sync.go b/foreman-builder/cmd/sync.go index 643a996..528176f 100644 --- a/foreman-builder/cmd/sync.go +++ b/foreman-builder/cmd/sync.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "log" "os" "path/filepath" "slices" @@ -26,18 +25,19 @@ import ( func SyncContainers() { orbContainers, err := foremanbuilder.GetOrbStackContainers() if err != nil { - fmt.Printf("Error: %v\n", err) + foremanbuilder.Logger.Fatalf("Error: %v\n", err) } home, err := os.UserHomeDir() if err != nil { - log.Panicf("Failed to get home directory: %v\n", err) + foremanbuilder.Logger.Fatalf("Failed to get home directory: %v", err) } dotFolderPath := filepath.Join(home, ".foreman-builder") containersPath := filepath.Join(dotFolderPath, "containers") foremanContainers, err := foremanbuilder.GetAllLines(containersPath) if err != nil { fmt.Printf("Error getting all containers %v\n", err) + foremanbuilder.Logger.Errorf("Error has occurred getting all containers %v\n", err) } for i := 0; i < len(foremanContainers)-1; i++ { diff --git a/foreman-builder/yml.go b/foreman-builder/yml.go index a1cf8b1..f4efc83 100644 --- a/foreman-builder/yml.go +++ b/foreman-builder/yml.go @@ -4,7 +4,6 @@ import ( "bytes" _ "embed" "io" - "log" "os" "text/template" @@ -51,7 +50,7 @@ func GenerateContainerConfig(data OrbstackConfigData, pathName string) error { if len(data.Packages) != 0 { installStr := MakeInstallStringFromStruct(data.Packages) - log.Printf(installStr, "install str") + Logger.Debugf("install string: %s", installStr) data.InstallString = installStr } diff --git a/go.mod b/go.mod index c3c7ad0..6080fb9 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,8 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kr/pretty v0.2.0 // indirect github.com/spf13/pflag v1.0.9 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.1 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect ) diff --git a/go.sum b/go.sum index d09530a..d1a4de4 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEX github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U= github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +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/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -26,8 +28,9 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -42,6 +45,8 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +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/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -49,8 +54,16 @@ github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= diff --git a/main.go b/main.go index 33a2911..b18fb2b 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "log" "os" "path/filepath" "runtime" @@ -17,12 +16,12 @@ func main() { } if !foremanbuilder.IsOrbStackRunning() { - log.Fatalf("Orbstack must be running") + foremanbuilder.Logger.Fatal("Orbstack must be running") } home, err := os.UserHomeDir() if err != nil { - log.Panicf("Failed to get home directory: %v\n", err) + foremanbuilder.Logger.Fatalf("Failed to get home directory: %v", err) } dotFolderPath := filepath.Join(home, ".foreman-builder") @@ -30,27 +29,27 @@ func main() { dotfolderExists, err := foremanbuilder.DoesFileOrDirectoryExist(dotFolderPath) if err != nil { - log.Printf("Error checking dotfolder: %v\n", err) + foremanbuilder.Logger.Errorf("Error checking dotfolder: %v", err) } containersExists, err := foremanbuilder.DoesFileOrDirectoryExist(containersPath) if err != nil { - log.Printf("Error checking containers file: %v\n", err) + foremanbuilder.Logger.Errorf("Error checking containers file: %v", err) } if !dotfolderExists { - log.Printf("Creating dotfolder...\n") + foremanbuilder.Logger.Info("Creating dotfolder...") err := os.MkdirAll(dotFolderPath, 0755) if err != nil { - log.Panicf("Failed to create dotfolder: %v\n", err) + foremanbuilder.Logger.Fatalf("Failed to create dotfolder: %v", err) } } if !containersExists { - log.Printf("Creating containers file...\n") + foremanbuilder.Logger.Info("Creating containers file...") err := os.WriteFile(containersPath, []byte(""), 0644) if err != nil { - log.Panicf("Failed to create container file: %v\n", err) + foremanbuilder.Logger.Fatalf("Failed to create container file: %v", err) } } cmd.SyncContainers() @@ -64,7 +63,7 @@ func isSystemSupported() bool { userCPU := runtime.GOARCH if userCPU != "arm64" { - log.Fatal("foreman-builder does not currently support non apple-silicon devices!") + foremanbuilder.Logger.Fatal("foreman-builder does not currently support non apple-silicon devices!") return false } return true From 3823a6f1bc9479144d9130c1ae90a3dee0c929dc Mon Sep 17 00:00:00 2001 From: Aiden Fine Date: Tue, 3 Mar 2026 10:29:33 -0500 Subject: [PATCH 2/2] add logger.go --- foreman-builder/logger.go | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 foreman-builder/logger.go diff --git a/foreman-builder/logger.go b/foreman-builder/logger.go new file mode 100644 index 0000000..f9443e2 --- /dev/null +++ b/foreman-builder/logger.go @@ -0,0 +1,42 @@ +package foremanbuilder + +import ( + "os" + "strings" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// Logger is the package-level sugared logger controlled by the LOG_LEVEL env var +var Logger *zap.SugaredLogger + +func init() { + level := zapcore.FatalLevel + if env := os.Getenv("LOG_LEVEL"); env != "" { + switch strings.ToLower(env) { + case "debug": + level = zapcore.DebugLevel + case "info": + level = zapcore.InfoLevel + case "warn": + level = zapcore.WarnLevel + case "error": + level = zapcore.ErrorLevel + } + } + + cfg := zap.Config{ + Level: zap.NewAtomicLevelAt(level), + Encoding: "console", + EncoderConfig: zap.NewDevelopmentEncoderConfig(), + OutputPaths: []string{"stderr"}, + ErrorOutputPaths: []string{"stderr"}, + } + + logger, err := cfg.Build() + if err != nil { + panic(err) + } + Logger = logger.Sugar() +}