From fc41a6ee5b14dd1d2ff48b7338760846482d653e Mon Sep 17 00:00:00 2001 From: Elijah Duffy Date: Fri, 30 May 2025 16:18:21 -0700 Subject: [PATCH] load dependencies by name instead of reference --- lifecycle.go | 23 +++++++++++++++++++---- module.go | 14 +++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/lifecycle.go b/lifecycle.go index e2cf10f..72535d4 100644 --- a/lifecycle.go +++ b/lifecycle.go @@ -163,13 +163,18 @@ func (app *Lifecycle) setupSingle(sub *Module, logger *slog.Logger) (bool, error // Check if all dependencies are satisfied for _, dep := range sub.depends { - if _, ok := app.setupTracker[dep.name]; !ok { + if _, ok := app.setupTracker[dep]; !ok { if app.opts.DisableAutoload { - return false, fmt.Errorf("dependency '%s' not satisfied for '%s'", dep.name, sub.name) + return false, fmt.Errorf("dependency '%s' not satisfied for '%s'", dep, sub.name) } else { // Attempt to set up the dependency - if _, err := app.setupSingle(dep, logger); err != nil { - return false, fmt.Errorf("error setting up dependency '%s' for '%s': %w", dep.name, sub.name, err) + mod, err := app.getModuleByName(dep) + if err != nil { + return false, err + } + + if _, err := app.setupSingle(mod, logger); err != nil { + return false, fmt.Errorf("error setting up dependency '%s' for '%s': %w", dep, sub.name, err) } } @@ -213,6 +218,16 @@ func (app *Lifecycle) singleTeardown(sub *Module) (bool, error) { return false, nil } +// getModuleByName retrieves a module by its name from the lifecycle. +func (app *Lifecycle) getModuleByName(name string) (*Module, error) { + for _, sub := range app.modules { + if sub.name == name { + return sub, nil + } + } + return nil, fmt.Errorf("module '%s' not found", name) +} + // mapToString converts a map to an opinionated string representation. func mapToString(m map[string]bool) string { if len(m) == 0 { diff --git a/module.go b/module.go index 6e96ef7..f966e47 100644 --- a/module.go +++ b/module.go @@ -12,7 +12,7 @@ type Module struct { name string setup setupFn teardown teardownFn - depends []*Module + depends []string } // ModuleOpts contains user-exposed options when defining a module. @@ -21,8 +21,9 @@ type ModuleOpts struct { Setup setupFn // Teardown is the teardown function for the module. Teardown teardownFn - // Depends is a list of modules that this module depends on. - Depends []*Module + // Depends is a list of modules that this module depends on. Each entry must + // be the exact name of a module registered in the lifecycle. + Depends []string } // NewModule creates a new Module instance with the given name and options. @@ -38,7 +39,7 @@ func NewModule(name string, opts ModuleOpts) *Module { // Logger returns the logger for the module. func (s *Module) Logger() *slog.Logger { if s.logger == nil { - panic(fmt.Sprintf("subsytem %s used before logger was initialized", s.name)) + panic(fmt.Sprintf("module %s used before logger was initialized", s.name)) } return s.logger } @@ -47,8 +48,3 @@ func (s *Module) Logger() *slog.Logger { func (s *Module) Name() string { return s.name } - -// ModuleList is a convenience function that creates a slice of modules. -func ModuleList(modules ...*Module) []*Module { - return modules -}