add Lifecycle.RequireUnique methods for load-once deps

This commit is contained in:
Elijah Duffy
2025-06-03 16:58:59 -07:00
parent b290bc0f7e
commit 6f9e3731ac
2 changed files with 80 additions and 0 deletions

View File

@@ -123,6 +123,12 @@ func (app *Lifecycle) Require(modules ...*Module) error {
return app.RequireL(app.logger, modules...)
}
// RequireUnique is the same as Require, but it returns an error if any requested
// module is already set up--rather than ignoring it.
func (app *Lifecycle) RequireUnique(modules ...*Module) error {
return app.RequireUniqueL(app.logger, modules...)
}
// RequireL adds module(s) to the lifecycle with a specific logger and
// immediately runs any setup functions. See Require for more details.
// This variation is useful when you need to set up modules with a non-
@@ -163,6 +169,23 @@ func (app *Lifecycle) RequireL(logger *slog.Logger, modules ...*Module) error {
return nil
}
// RequireUniqueL is the same as RequireL, but it returns an error if any requested
// module is already set up--rather than ignoring it.
func (app *Lifecycle) RequireUniqueL(logger *slog.Logger, modules ...*Module) error {
// Check if any module is already set up
for _, mod := range modules {
if mod == nil {
return fmt.Errorf("module is nil")
}
if _, ok := app.setupTracker[mod.name]; ok {
return fmt.Errorf("module '%s' is already set up, cannot require it again", mod.name)
}
}
return app.RequireL(logger, modules...)
}
// setupSingle is a helper function to set up a single module. Returns an error
// if the module cannot be set up or if dependencies are not satisfied.
func (app *Lifecycle) setupSingle(mod *Module, logger *slog.Logger) error {