go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/apputil/entrypoint.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package apputil 9 10 import ( 11 "context" 12 "flag" 13 "strings" 14 15 "go.charczuk.com/sdk/cliutil" 16 "go.charczuk.com/sdk/configutil" 17 "go.charczuk.com/sdk/logutil" 18 ) 19 20 // EntryPointConfigProvider is a type that can provide 21 // an entrypoint config. 22 type EntryPointConfigProvider interface { 23 LoggerProvider 24 } 25 26 // EntryPoint is a top level handler for a simple app. 27 // 28 // It handles reading the config, and setting up the logger. 29 type EntryPoint[T EntryPointConfigProvider] struct { 30 Setup func(context.Context, T) error 31 Start func(context.Context, T) error 32 33 config T 34 flagSetup bool 35 flagStart bool 36 didInit bool 37 } 38 39 // Init should be run before `Run` and registers flags and the like. 40 func (e *EntryPoint[T]) Init() { 41 if e.didInit { 42 return 43 } 44 e.didInit = true 45 flag.BoolVar(&e.flagSetup, "setup", false, "if we should run the first time setup steps") 46 flag.BoolVar(&e.flagStart, "start", true, "if we should start the server (false will exit after other steps complete)") 47 flag.Parse() 48 } 49 50 // Main is the actual function that needs to be called in Main. 51 func (e *EntryPoint[T]) Main() { 52 if !e.didInit { 53 e.Init() 54 } 55 ctx := context.Background() 56 configPaths := configutil.MustRead(&e.config) 57 log := logutil.New( 58 logutil.OptConfig(e.config.GetLogger()), 59 ) 60 61 ctx = logutil.WithLogger(ctx, log) 62 if len(configPaths) > 0 { 63 logutil.Infof(log, "using config path(s): %s", strings.Join(configPaths, ", ")) 64 } else { 65 logutil.Infof(log, "using environment resolved config") 66 } 67 if e.flagSetup && e.Setup != nil { 68 logutil.Infof(log, "running first time setup") 69 if err := e.Setup(ctx, e.config); err != nil { 70 cliutil.Fatal(err) 71 } 72 logutil.Infof(log, "running first time setup complete") 73 } else { 74 logutil.Debug(log, "skipping running first time setup") 75 } 76 if e.flagStart && e.Start != nil { 77 logutil.Infof(log, "starting") 78 if err := e.Start(ctx, e.config); err != nil { 79 cliutil.Fatal(err) 80 } 81 } else { 82 logutil.Infof(log, "exiting") 83 } 84 }