Allow primary builder to handle missing dependencies

In some cases the primary builder may need to handle missing
dependencies.  Add Context.SetAllowMissingDependencies to cause
Blueprint to store the list of missing dependencies without immediately
emitting an error, and ModuleContext.GetMissingDependencies to return
the missing dependencies to the primary builder.  If the primary builder
does not call ModuleContext.GetMissingDependencies Blueprint will emit
dependency errors.
This commit is contained in:
Colin Cross 2015-12-17 15:49:30 -08:00
parent eb97a6e7a1
commit 036a1df374
2 changed files with 47 additions and 5 deletions

View file

@ -81,6 +81,9 @@ type Context struct {
// set by SetIgnoreUnknownModuleTypes
ignoreUnknownModuleTypes bool
// set by SetAllowMissingDependencies
allowMissingDependencies bool
// set during PrepareBuildActions
pkgNames map[*packageContext]string
globalVariables map[Variable]*ninjaString
@ -137,7 +140,8 @@ type moduleInfo struct {
moduleProperties []interface{}
// set during ResolveDependencies
directDeps []*moduleInfo
directDeps []*moduleInfo
missingDeps []string
// set during updateDependencies
reverseDeps []*moduleInfo
@ -437,6 +441,14 @@ func (c *Context) SetIgnoreUnknownModuleTypes(ignoreUnknownModuleTypes bool) {
c.ignoreUnknownModuleTypes = ignoreUnknownModuleTypes
}
// SetAllowMissingDependencies changes the behavior of Blueprint to ignore
// unresolved dependencies. If the module's GenerateBuildActions calls
// ModuleContext.GetMissingDependencies Blueprint will not emit any errors
// for missing dependencies.
func (c *Context) SetAllowMissingDependencies(allowMissingDependencies bool) {
c.allowMissingDependencies = allowMissingDependencies
}
// Parse parses a single Blueprints file from r, creating Module objects for
// each of the module definitions encountered. If the Blueprints file contains
// an assignment to the "subdirs" variable, then the subdirectories listed are
@ -1121,6 +1133,10 @@ func (c *Context) addDependency(module *moduleInfo, depName string) []error {
depInfo, ok := c.moduleGroups[depName]
if !ok {
if c.allowMissingDependencies {
module.missingDeps = append(module.missingDeps, depName)
return nil
}
return []error{&Error{
Err: fmt.Errorf("%q depends on undefined module %q",
module.properties.Name, depName),
@ -1181,6 +1197,10 @@ func (c *Context) addVariationDependency(module *moduleInfo, variations []Variat
depInfo, ok := c.moduleGroups[depName]
if !ok {
if c.allowMissingDependencies {
module.missingDeps = append(module.missingDeps, depName)
return nil
}
return []error{&Error{
Err: fmt.Errorf("%q depends on undefined module %q",
module.properties.Name, depName),
@ -1674,7 +1694,8 @@ func (c *Context) generateModuleBuildActions(config interface{},
config: config,
module: module,
},
scope: scope,
scope: scope,
handledMissingDeps: module.missingDeps == nil,
}
mctx.module.logicModule.GenerateBuildActions(mctx)
@ -1684,6 +1705,19 @@ func (c *Context) generateModuleBuildActions(config interface{},
return true
}
if module.missingDeps != nil && !mctx.handledMissingDeps {
var errs []error
for _, depName := range module.missingDeps {
errs = append(errs, &Error{
Err: fmt.Errorf("%q depends on undefined module %q",
module.properties.Name, depName),
Pos: module.pos,
})
}
errsCh <- errs
return true
}
depsCh <- mctx.ninjaFileDeps
newErrs := c.processLocalBuildActions(&module.actionDefs,

View file

@ -146,6 +146,8 @@ type ModuleContext interface {
PrimaryModule() Module
FinalModule() Module
VisitAllModuleVariants(visit func(Module))
GetMissingDependencies() []string
}
var _ BaseModuleContext = (*baseModuleContext)(nil)
@ -221,9 +223,10 @@ var _ ModuleContext = (*moduleContext)(nil)
type moduleContext struct {
baseModuleContext
scope *localScope
ninjaFileDeps []string
actionDefs localBuildActions
scope *localScope
ninjaFileDeps []string
actionDefs localBuildActions
handledMissingDeps bool
}
func (m *moduleContext) OtherModuleName(logicModule Module) string {
@ -322,6 +325,11 @@ func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
}
}
func (m *moduleContext) GetMissingDependencies() []string {
m.handledMissingDeps = true
return m.module.missingDeps
}
//
// MutatorContext
//