Run LoadHooks before registering module

Previously a LoadHook could not modify the name of a module because the
module was registered before the LoadHooks were run. That made it very
complicated (requiring mutators and auto generated names) to create a
module type whose name was determined by say the directory in which it
is defined.

This change moves the LoadHook execution slightly earlier so it runs
before registration of the module.

That caused one slight side problem which was that the
moduleInfo.Name() would fail when called in a LoadHook. That was
because that gets the name from group.name but was group was nil
because it is only set when the module is registered.

Modifying the moduleInfo.Name() method to get the name from the module
logicModule.Name() if group is nil fixed that. The reason for getting
the name from the group.name rather than the logicModule.Name() is that
the former tracks renames but the latter does not. However that is not
an issue in this case as there has been no opportunity for the module
to be renamed until after the LoadHook has returned.
This commit is contained in:
Paul Duffin 2020-05-04 11:00:03 +01:00
parent 2a062a2ef0
commit 244033b20f

View file

@ -218,7 +218,16 @@ type depInfo struct {
}
func (module *moduleInfo) Name() string {
return module.group.name
// If this is called from a LoadHook (which is run before the module has been registered)
// then group will not be set and so the name is retrieved from logicModule.Name().
// Usually, using that method is not safe as it does not track renames (group.name does).
// However, when called from LoadHook it is safe as there is no way to rename a module
// until after the LoadHook has run and the module has been registered.
if module.group != nil {
return module.group.name
} else {
return module.logicModule.Name()
}
}
func (module *moduleInfo) String() string {
@ -683,14 +692,18 @@ func (c *Context) ParseFileList(rootDir string, filePaths []string,
var scopedModuleFactories map[string]ModuleFactory
var addModule func(module *moduleInfo) []error
addModule = func(module *moduleInfo) (errs []error) {
moduleCh <- newModuleInfo{module, addedCh}
<-addedCh
var newModules []*moduleInfo
newModules, errs = runAndRemoveLoadHooks(c, config, module, &scopedModuleFactories)
addModule = func(module *moduleInfo) ([]error) {
// Run any load hooks immediately before it is sent to the moduleCh and is
// registered by name. This allows load hooks to set and/or modify any aspect
// of the module (including names) using information that is not available when
// the module factory is called.
newModules, errs := runAndRemoveLoadHooks(c, config, module, &scopedModuleFactories)
if len(errs) > 0 {
return errs
}
moduleCh <- newModuleInfo{module, addedCh}
<-addedCh
for _, n := range newModules {
errs = addModule(n)
if len(errs) > 0 {