diff --git a/lib/managedservicesplatform/runtime/env.go b/lib/managedservicesplatform/runtime/env.go index 38849bd5526..24957c7008e 100644 --- a/lib/managedservicesplatform/runtime/env.go +++ b/lib/managedservicesplatform/runtime/env.go @@ -9,9 +9,19 @@ import ( "github.com/sourcegraph/sourcegraph/lib/errors" ) +type requestedEnvVar struct { + name string + defaultValue string + description string +} + type Env struct { errs []error env map[string]string + + // requestedEnvVars are only available after ConfigLoader is used on this + // Env instance. + requestedEnvVars []requestedEnvVar } func newEnv() (*Env, error) { @@ -30,8 +40,13 @@ func newEnv() (*Env, error) { }, nil } -// TODO: Try to use third param description to generate docs. -func (e *Env) get(name, defaultValue, _ string) string { +func (e *Env) get(name, defaultValue, description string) string { + e.requestedEnvVars = append(e.requestedEnvVars, requestedEnvVar{ + name: name, + defaultValue: defaultValue, + description: description, + }) + v, ok := e.env[name] if !ok { return defaultValue diff --git a/lib/managedservicesplatform/runtime/service.go b/lib/managedservicesplatform/runtime/service.go index ccb39174811..809abc800c1 100644 --- a/lib/managedservicesplatform/runtime/service.go +++ b/lib/managedservicesplatform/runtime/service.go @@ -2,6 +2,9 @@ package runtime import ( "context" + "flag" + "fmt" + "os" "cloud.google.com/go/profiler" "github.com/getsentry/sentry-go" @@ -29,6 +32,8 @@ type Service[ConfigT any] interface { ) (background.Routine, error) } +var showHelp = flag.Bool("help", false, "Show service help text") + // Start handles the entire lifecycle of the program running Service, and should // be the only thing called in a MSP program's main package, for example: // @@ -40,6 +45,7 @@ func Start[ ConfigT any, LoaderT ConfigLoader[ConfigT], ](service Service[ConfigT]) { + flag.Parse() passSanityCheck(service) // Resource representing the service @@ -70,6 +76,23 @@ func Start[ config.Load(env) contract := newContract(log.Scoped("msp.contract"), env, service) + // Fast-exit with configuration facts if requested + if *showHelp { + fmt.Printf("SERVICE: %s\nVERSION: %s\n", + service.Name(), service.Version()) + fmt.Printf("CONFIGURATION OPTIONS:\n") + for _, v := range env.requestedEnvVars { + fmt.Printf("- '%s': %s", v.name, v.description) + if v.defaultValue != "" { + fmt.Printf(" (default: %q)", v.defaultValue) + } else { + fmt.Printf(" (required)") + } + fmt.Println() + } + os.Exit(0) + } + // Enable Sentry error log reporting var sentryEnabled bool if contract.internal.sentryDSN != nil {