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  }