Add Rename

Allow modules to be renamed by mutators.  This will allow modules to
dynamically adapt to the presence or absence of modules with the same
name.  For example, if a source module does not exist, a prebuilt module
could rename itself to the name of the source module so that
dependenices on the module name are satisified.

Change-Id: I44004604c6d9db041bb7d38fe6c1ca877bc7d6f1
This commit is contained in:
Colin Cross 2016-10-12 10:45:05 -07:00
parent b3f96c3306
commit c4e5b8157b
2 changed files with 55 additions and 1 deletions

View file

@ -101,6 +101,8 @@ type Context struct {
// set lazily by sortedModuleNames
cachedSortedModuleNames []string
renames []rename // List of pending renames to apply after the mutator pass
fs fileSystem
}
@ -1750,6 +1752,7 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
done := make(chan bool)
c.depsModified = 0
c.renames = nil
visit := func(module *moduleInfo) bool {
if module.splitModules != nil {
@ -1855,6 +1858,11 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
c.depsModified++
}
errs = c.handleRenames()
if len(errs) > 0 {
return errs
}
if c.depsModified > 0 {
errs = c.updateDependencies()
if len(errs) > 0 {
@ -2144,7 +2152,46 @@ func (c *Context) walkDeps(topModule *moduleInfo,
walk(topModule)
}
type innerPanicError error
type rename struct {
group *moduleGroup
name string
}
func (c *Context) rename(group *moduleGroup, name string) {
c.renames = append(c.renames, rename{group, name})
}
func (c *Context) handleRenames() []error {
var errs []error
for _, rename := range c.renames {
group, name := rename.group, rename.name
if name == group.name {
continue
}
existing := c.moduleNames[name]
if existing != nil {
errs = append(errs,
&BlueprintError{
Err: fmt.Errorf("renaming module %q to %q conflicts with existing module",
group.name, name),
Pos: group.modules[0].pos,
},
&BlueprintError{
Err: fmt.Errorf("<-- existing module defined here"),
Pos: existing.modules[0].pos,
},
)
continue
}
c.moduleNames[name] = group
delete(c.moduleNames, group.name)
group.name = name
}
return errs
}
func (c *Context) modulesFromName(name string) []*moduleInfo {
if group := c.moduleNames[name]; group != nil {

View file

@ -457,6 +457,7 @@ type baseMutatorContext interface {
BaseModuleContext
OtherModuleExists(name string) bool
Rename(name string)
Module() Module
}
@ -656,6 +657,12 @@ func (mctx *mutatorContext) OtherModuleExists(name string) bool {
return mctx.context.moduleNames[name] != nil
}
// Rename all variants of a module. The new name is not visible to calls to ModuleName,
// AddDependency or OtherModuleName until after this mutator pass is complete.
func (mctx *mutatorContext) Rename(name string) {
mctx.context.rename(mctx.module.group, name)
}
// SimpleName is an embeddable object to implement the ModuleContext.Name method using a property
// called "name". Modules that embed it must also add SimpleName.Properties to their property
// structure list.