diff --git a/cmd/root.go b/cmd/root.go index 9657a7c..843ced6 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,8 +6,8 @@ import ( "os" "github.com/akyaiy/GoSally-mvp/hooks" + "github.com/akyaiy/GoSally-mvp/internal/colors" "github.com/akyaiy/GoSally-mvp/internal/core/corestate" - "github.com/akyaiy/GoSally-mvp/internal/engine/logs" "github.com/spf13/cobra" ) @@ -24,7 +24,7 @@ scripts in a given directory. For more information, visit: https://gosally.oblat func Execute() { log.SetOutput(os.Stdout) - log.SetPrefix(logs.SetBrightBlack(fmt.Sprintf("(%s) ", corestate.StageNotReady))) + log.SetPrefix(colors.SetBrightBlack(fmt.Sprintf("(%s) ", corestate.StageNotReady))) log.SetFlags(log.Ldate | log.Ltime) hooks.Compositor.LoadCMDLine(rootCmd) _ = rootCmd.Execute() diff --git a/go.mod b/go.mod index 92f3fb6..5cee585 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.24.4 require ( github.com/go-chi/chi/v5 v5.2.2 + github.com/google/uuid v1.6.0 github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.20.1 github.com/yuin/gopher-lua v1.1.1 @@ -17,7 +18,6 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect @@ -29,7 +29,6 @@ require ( github.com/spf13/cast v1.9.2 // indirect github.com/spf13/pflag v1.0.7 // indirect github.com/subosito/gotenv v1.6.0 // indirect - go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect golang.org/x/sys v0.34.0 // indirect golang.org/x/text v0.27.0 // indirect diff --git a/go.sum b/go.sum index 364456c..8663a34 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9L github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -36,12 +38,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k= -github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= github.com/sagikazarmark/locafero v0.10.0 h1:FM8Cv6j2KqIhM2ZK7HZjm4mpj9NBktLgowT1aN9q5Cc= github.com/sagikazarmark/locafero v0.10.0/go.mod h1:Ieo3EUsjifvQu4NZwV5sPd4dwvu0OCgEQV7vjc9yDjw= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= @@ -61,17 +59,21 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4= golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc= +golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= +golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -81,11 +83,29 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/cc/v4 v4.26.3 h1:yEN8dzrkRFnn4PUUKXLYIqVf2PJYAEjMTFjO3BDGc3I= +modernc.org/cc/v4 v4.26.3/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU= +modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE= +modernc.org/fileutil v1.3.8 h1:qtzNm7ED75pd1C7WgAGcK4edm4fvhtBsEiI/0NQ54YM= +modernc.org/fileutil v1.3.8/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= +modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= modernc.org/libc v1.66.6 h1:RyQpwAhM/19nXD8y3iejM/AjmKwY2TjxZTlUWTsWw2U= modernc.org/libc v1.66.6/go.mod h1:j8z0EYAuumoMQ3+cWXtmw6m+LYn3qm8dcZDFtFTSq+M= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= modernc.org/sqlite v1.38.2 h1:Aclu7+tgjgcQVShZqim41Bbw9Cho0y/7WzYptXqkEek= modernc.org/sqlite v1.38.2/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/hooks/initial.go b/hooks/initial.go index 67ed76f..0763ed0 100644 --- a/hooks/initial.go +++ b/hooks/initial.go @@ -2,6 +2,7 @@ package hooks import ( "bufio" + "context" "errors" "fmt" "io" @@ -9,12 +10,14 @@ import ( "log" "log/slog" "os" + "os/signal" "path/filepath" "slices" "strings" "syscall" "time" + "github.com/akyaiy/GoSally-mvp/internal/colors" "github.com/akyaiy/GoSally-mvp/internal/core/corestate" "github.com/akyaiy/GoSally-mvp/internal/core/run_manager" "github.com/akyaiy/GoSally-mvp/internal/core/utils" @@ -26,15 +29,15 @@ import ( var Compositor *config.Compositor = config.NewCompositor() -func Init0Hook(cs *corestate.CoreState, x *app.AppX) { +func Init0Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) { x.Config = Compositor x.Log.SetOutput(os.Stdout) - x.Log.SetPrefix(logs.SetBrightBlack(fmt.Sprintf("(%s) ", cs.Stage))) + x.Log.SetPrefix(colors.SetBrightBlack(fmt.Sprintf("(%s) ", cs.Stage))) x.Log.SetFlags(log.Ldate | log.Ltime) } // First stage: pre-init -func Init1Hook(cs *corestate.CoreState, x *app.AppX) { +func Init1Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) { *cs = *corestate.NewCorestate(&corestate.CoreState{ UUID32DirName: "uuid", NodeBinName: filepath.Base(os.Args[0]), @@ -45,8 +48,8 @@ func Init1Hook(cs *corestate.CoreState, x *app.AppX) { }) } -func Init2Hook(cs *corestate.CoreState, x *app.AppX) { - x.Log.SetPrefix(logs.SetYellow(fmt.Sprintf("(%s) ", cs.Stage))) +func Init2Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) { + x.Log.SetPrefix(colors.SetYellow(fmt.Sprintf("(%s) ", cs.Stage))) if err := x.Config.LoadEnv(); err != nil { x.Log.Fatalf("env load error: %s", err) @@ -61,7 +64,7 @@ func Init2Hook(cs *corestate.CoreState, x *app.AppX) { } } -func Init3Hook(cs *corestate.CoreState, x *app.AppX) { +func Init3Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) { uuid32, err := corestate.GetNodeUUID(filepath.Join(cs.MetaDir, "uuid")) if errors.Is(err, fs.ErrNotExist) { if err := corestate.SetNodeUUID(filepath.Join(cs.NodePath, cs.MetaDir, cs.UUID32DirName)); err != nil { @@ -78,7 +81,7 @@ func Init3Hook(cs *corestate.CoreState, x *app.AppX) { cs.UUID32 = uuid32 } -func Init4Hook(cs *corestate.CoreState, x *app.AppX) { +func Init4Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) { if *x.Config.Env.ParentStagePID != os.Getpid() { // still pre-init stage runDir, err := run_manager.Create(cs.UUID32) @@ -129,9 +132,18 @@ func Init4Hook(cs *corestate.CoreState, x *app.AppX) { } // post-init stage -func Init5Hook(cs *corestate.CoreState, x *app.AppX) { +func Init5Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) { + nodeApp.Fallback(func(ctx context.Context, cs *corestate.CoreState, x *app.AppX) { + x.Log.Println("Cleaning up...") + + if err := run_manager.Clean(); err != nil { + x.Log.Printf("%s: Cleanup error: %s", colors.PrintError(), err.Error()) + } + x.Log.Println("bye!") + }) + cs.Stage = corestate.StagePostInit - x.Log.SetPrefix(logs.SetBlue(fmt.Sprintf("(%s) ", cs.Stage))) + x.Log.SetPrefix(colors.SetBlue(fmt.Sprintf("(%s) ", cs.Stage))) cs.RunDir = run_manager.Toggle() exist, err := utils.ExistsMatchingDirs(filepath.Join(os.TempDir(), fmt.Sprintf("/*-%s-%s", cs.UUID32, "gosally-runtime")), cs.RunDir) @@ -172,9 +184,9 @@ func Init5Hook(cs *corestate.CoreState, x *app.AppX) { } } -func Init6Hook(cs *corestate.CoreState, x *app.AppX) { +func Init6Hook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) { if !slices.Contains(*x.Config.Conf.DisableWarnings, "--WNonStdTmpDir") && os.TempDir() != "/tmp" { - x.Log.Printf("%s: %s", logs.PrintWarn(), "Non-standard value specified for temporary directory") + x.Log.Printf("%s: %s", colors.PrintWarn(), "Non-standard value specified for temporary directory") } if strings.Contains(*x.Config.Conf.Log.OutPath, `%tmp%`) { replaced := strings.ReplaceAll(*x.Config.Conf.Log.OutPath, "%tmp%", filepath.Clean(run_manager.RuntimeDir())) @@ -182,7 +194,7 @@ func Init6Hook(cs *corestate.CoreState, x *app.AppX) { } if !slices.Contains(logs.Levels.Available, *x.Config.Conf.Log.Level) { if !slices.Contains(*x.Config.Conf.DisableWarnings, "--WUndefLogLevel") { - x.Log.Printf("%s: %s", logs.PrintWarn(), fmt.Sprintf("Unknown logging level %s, fallback level: %s", *x.Config.Conf.Log.Level, logs.Levels.Fallback)) + x.Log.Printf("%s: %s", colors.PrintWarn(), fmt.Sprintf("Unknown logging level %s, fallback level: %s", *x.Config.Conf.Log.Level, logs.Levels.Fallback)) } x.Config.Conf.Log.Level = &logs.Levels.Fallback } @@ -193,28 +205,19 @@ func Init6Hook(cs *corestate.CoreState, x *app.AppX) { fmt.Printf("Environment:\n") x.Config.Print(x.Config.Env) - ok := true - fmt.Printf("%s (%s/%s): ", "Is that ok?", logs.SetBrightGreen("Y"), logs.SetBrightRed("n")) - - reader := bufio.NewReader(os.Stdin) - input, _ := reader.ReadString('\n') - input = strings.TrimSpace(strings.ToLower(input)) - - ok = input == "" || input == "y" || input == "yes" - - if !ok { - _ = run_manager.Clean() - x.Log.Fatalf("Cancel launch") + if !askConfirm("Is that ok?", true) { + x.Log.Printf("Cancel launch") + nodeApp.CallFallback(ctx) } } x.Log.Printf("Starting \"%s\" node", *x.Config.Conf.Node.Name) } -func Init7Hook(cs *corestate.CoreState, x *app.AppX) { +func Init7Hook(_ context.Context, cs *corestate.CoreState, x *app.AppX) { cs.Stage = corestate.StageReady - x.Log.SetPrefix(logs.SetGreen(fmt.Sprintf("(%s) ", cs.Stage))) + x.Log.SetPrefix(colors.SetGreen(fmt.Sprintf("(%s) ", cs.Stage))) x.SLog = new(slog.Logger) newSlog, err := logs.SetupLogger(x.Config.Conf.Log) @@ -225,26 +228,38 @@ func Init7Hook(cs *corestate.CoreState, x *app.AppX) { *x.SLog = *newSlog } -// repl := map[string]string{ -// "tmp": filepath.Clean(run_manager.RuntimeDir()), -// } -// re := regexp.MustCompile(`%(\w+)%`) -// result := re.ReplaceAllStringFunc(x.Config.Conf.Log.OutPath, func(match string) string { -// sub := re.FindStringSubmatch(match) -// if len(sub) < 2 { -// return match -// } -// key := sub[1] -// if val, ok := repl[key]; ok { -// return val -// } -// return match -// }) +func askConfirm(prompt string, defaultYes bool) bool { + ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) -// if strings.Contains(x.Config.Conf.Log.OutPath, "%tmp%") { -// relPath := strings.TrimPrefix(result, filepath.Clean(run_manager.RuntimeDir())) -// if err := run_manager.SetDir(relPath); err != nil { -// _ = run_manager.Clean() -// x.Log.Fatalf("Unexpected failure: %s", err.Error()) -// } -// } + fmt.Print(prompt) + if defaultYes { + fmt.Printf(" (%s/%s): ", colors.SetBrightGreen("Y"), colors.SetBrightRed("n")) + } else { + fmt.Printf(" (%s/%s): ", colors.SetBrightGreen("n"), colors.SetBrightRed("Y")) + } + + inputChan := make(chan string, 1) + + go func() { + reader := bufio.NewReader(os.Stdin) + text, _ := reader.ReadString('\n') + inputChan <- text + }() + + select { + case <-ctx.Done(): + fmt.Println("") + nodeApp.CallFallback(ctx) + os.Exit(3) + case text := <-inputChan: + text = strings.TrimSpace(strings.ToLower(text)) + if text == "" { + return defaultYes + } + if text == "y" || text == "yes" { + return true + } + return false + } + return defaultYes +} diff --git a/hooks/run.go b/hooks/run.go index 41b2a8c..995806c 100644 --- a/hooks/run.go +++ b/hooks/run.go @@ -11,6 +11,7 @@ import ( "regexp" "time" + "github.com/akyaiy/GoSally-mvp/internal/colors" "github.com/akyaiy/GoSally-mvp/internal/core/corestate" "github.com/akyaiy/GoSally-mvp/internal/core/run_manager" "github.com/akyaiy/GoSally-mvp/internal/core/update" @@ -97,7 +98,7 @@ func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error { nodeApp.Fallback(func(ctx context.Context, cs *corestate.CoreState, x *app.AppX) { if err := srv.Shutdown(ctxMain); err != nil { - x.Log.Printf("%s: Failed to stop the server gracefully: %s", logs.PrintError(), err.Error()) + x.Log.Printf("%s: Failed to stop the server gracefully: %s", colors.PrintError(), err.Error()) } else { x.Log.Printf("Server stopped gracefully") } @@ -105,7 +106,7 @@ func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error { x.Log.Println("Cleaning up...") if err := run_manager.Clean(); err != nil { - x.Log.Printf("%s: Cleanup error: %s", logs.PrintError(), err.Error()) + x.Log.Printf("%s: Cleanup error: %s", colors.PrintError(), err.Error()) } x.Log.Println("bye!") }) @@ -115,27 +116,27 @@ func RunHook(ctx context.Context, cs *corestate.CoreState, x *app.AppX) error { if *x.Config.Conf.TLS.TlsEnabled { listener, err := net.Listen("tcp", fmt.Sprintf("%s:%s", *x.Config.Conf.HTTPServer.Address, *x.Config.Conf.HTTPServer.Port)) if err != nil { - x.Log.Printf("%s: Failed to start TLS listener: %s", logs.PrintError(), err.Error()) + x.Log.Printf("%s: Failed to start TLS listener: %s", colors.PrintError(), err.Error()) cancelMain() return } x.Log.Printf("Serving on %s port %s with TLS... (https://%s%s)", *x.Config.Conf.HTTPServer.Address, *x.Config.Conf.HTTPServer.Port, fmt.Sprintf("%s:%s", *x.Config.Conf.HTTPServer.Address, *x.Config.Conf.HTTPServer.Port), config.ComDirRoute) limitedListener := netutil.LimitListener(listener, 100) if err := srv.ServeTLS(limitedListener, *x.Config.Conf.TLS.CertFile, *x.Config.Conf.TLS.KeyFile); err != nil && !errors.Is(err, http.ErrServerClosed) { - x.Log.Printf("%s: Failed to start HTTPS server: %s", logs.PrintError(), err.Error()) + x.Log.Printf("%s: Failed to start HTTPS server: %s", colors.PrintError(), err.Error()) cancelMain() } } else { x.Log.Printf("Serving on %s port %s... (http://%s%s)", *x.Config.Conf.HTTPServer.Address, *x.Config.Conf.HTTPServer.Port, fmt.Sprintf("%s:%s", *x.Config.Conf.HTTPServer.Address, *x.Config.Conf.HTTPServer.Port), config.ComDirRoute) listener, err := net.Listen("tcp", fmt.Sprintf("%s:%s", *x.Config.Conf.HTTPServer.Address, *x.Config.Conf.HTTPServer.Port)) if err != nil { - x.Log.Printf("%s: Failed to start listener: %s", logs.PrintError(), err.Error()) + x.Log.Printf("%s: Failed to start listener: %s", colors.PrintError(), err.Error()) cancelMain() return } limitedListener := netutil.LimitListener(listener, 100) if err := srv.Serve(limitedListener); err != nil && !errors.Is(err, http.ErrServerClosed) { - x.Log.Printf("%s: Failed to start HTTP server: %s", logs.PrintError(), err.Error()) + x.Log.Printf("%s: Failed to start HTTP server: %s", colors.PrintError(), err.Error()) cancelMain() } } diff --git a/internal/engine/logs/color.go b/internal/colors/color.go similarity index 98% rename from internal/engine/logs/color.go rename to internal/colors/color.go index 1c5a4fd..785c7cc 100644 --- a/internal/engine/logs/color.go +++ b/internal/colors/color.go @@ -1,4 +1,4 @@ -package logs +package colors import "fmt" diff --git a/internal/engine/app/app.go b/internal/engine/app/app.go index 8a864a3..f2a0286 100644 --- a/internal/engine/app/app.go +++ b/internal/engine/app/app.go @@ -14,7 +14,7 @@ import ( ) type AppContract interface { - InitialHooks(fn ...func(cs *corestate.CoreState, x *AppX)) + InitialHooks(fn ...func(ctx context.Context, cs *corestate.CoreState, x *AppX)) Run(fn func(ctx context.Context, cs *corestate.CoreState, x *AppX) error) Fallback(fn func(ctx context.Context, cs *corestate.CoreState, x *AppX)) @@ -22,7 +22,7 @@ type AppContract interface { } type App struct { - initHooks []func(cs *corestate.CoreState, x *AppX) + initHooks []func(ctx context.Context, cs *corestate.CoreState, x *AppX) runHook func(ctx context.Context, cs *corestate.CoreState, x *AppX) error fallback func(ctx context.Context, cs *corestate.CoreState, x *AppX) @@ -47,7 +47,7 @@ func New() AppContract { } } -func (a *App) InitialHooks(fn ...func(cs *corestate.CoreState, x *AppX)) { +func (a *App) InitialHooks(fn ...func(ctx context.Context, cs *corestate.CoreState, x *AppX)) { a.initHooks = append(a.initHooks, fn...) } @@ -58,13 +58,13 @@ func (a *App) Fallback(fn func(ctx context.Context, cs *corestate.CoreState, x * func (a *App) Run(fn func(ctx context.Context, cs *corestate.CoreState, x *AppX) error) { a.runHook = fn - for _, hook := range a.initHooks { - hook(a.Corestate, a.AppX) - } - ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) defer stop() + for _, hook := range a.initHooks { + hook(ctx, a.Corestate, a.AppX) + } + defer func() { if r := recover(); r != nil { a.AppX.Log.Printf("PANIC recovered: %v", r) @@ -90,5 +90,6 @@ func (a *App) CallFallback(ctx context.Context) { if a.fallback != nil { a.fallback(ctx, a.Corestate, a.AppX) } + os.Exit(3) }) } diff --git a/internal/engine/config/print.go b/internal/engine/config/print.go index 1a766d0..287bfa7 100644 --- a/internal/engine/config/print.go +++ b/internal/engine/config/print.go @@ -4,6 +4,8 @@ import ( "fmt" "reflect" "time" + + "github.com/akyaiy/GoSally-mvp/internal/colors" ) func (c *Compositor) Print(v any) { @@ -29,9 +31,11 @@ func (c *Compositor) printConfig(v any, prefix string) { } } + coloredFieldName := colors.SetBrightCyan(fieldName) + if field.Kind() == reflect.Ptr { if field.IsNil() { - fmt.Printf("%s%s: \n", prefix, fieldName) + fmt.Printf("%s%s: %s\n", prefix, coloredFieldName, colors.SetBrightRed("")) continue } field = field.Elem() @@ -40,19 +44,29 @@ func (c *Compositor) printConfig(v any, prefix string) { if field.Kind() == reflect.Struct { if field.Type() == reflect.TypeOf(time.Duration(0)) { duration := field.Interface().(time.Duration) - fmt.Printf("%s%s: %s\n", prefix, fieldName, duration.String()) + fmt.Printf("%s%s: %s\n", + prefix, + coloredFieldName, + colors.SetBrightYellow(duration.String())) } else { - fmt.Printf("%s%s:\n", prefix, fieldName) + fmt.Printf("%s%s:\n", prefix, coloredFieldName) c.printConfig(field.Addr().Interface(), prefix+" ") } } else if field.Kind() == reflect.Slice { - fmt.Printf("%s%s: %v\n", prefix, fieldName, field.Interface()) + fmt.Printf("%s%s: %s\n", + prefix, + coloredFieldName, + colors.SetBrightYellow(fmt.Sprintf("%v", field.Interface()))) } else { value := field.Interface() + valueStr := fmt.Sprintf("%v", value) if field.Kind() == reflect.String { - value = fmt.Sprintf("\"%s\"", value) + valueStr = fmt.Sprintf("\"%s\"", value) } - fmt.Printf("%s%s: %v\n", prefix, fieldName, value) + fmt.Printf("%s%s: %s\n", + prefix, + coloredFieldName, + colors.SetBrightYellow(valueStr)) } } } diff --git a/internal/server/sv1/lua_handler.go b/internal/server/sv1/lua_handler.go index b156340..8c3509c 100644 --- a/internal/server/sv1/lua_handler.go +++ b/internal/server/sv1/lua_handler.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "github.com/akyaiy/GoSally-mvp/internal/engine/logs" + "github.com/akyaiy/GoSally-mvp/internal/colors" "github.com/akyaiy/GoSally-mvp/internal/server/rpc" lua "github.com/yuin/gopher-lua" ) @@ -78,13 +78,13 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest, L.SetField(logTable, "EventError", L.NewFunction(func(L *lua.LState) int { msg := L.ToString(1) - h.x.Log.Printf("%s: %s: %s", logs.PrintError(), path, msg) + h.x.Log.Printf("%s: %s: %s", colors.PrintError(), path, msg) return 0 })) L.SetField(logTable, "EventWarn", L.NewFunction(func(L *lua.LState) int { msg := L.ToString(1) - h.x.Log.Printf("%s: %s: %s", logs.PrintWarn(), path, msg) + h.x.Log.Printf("%s: %s: %s", colors.PrintWarn(), path, msg) return 0 }))