Deprecate EarlyMutator and DynamicDependencies
DynamicDependencies can be implemented more flexibly by a BottomUpMutator. If there are no DynamicDependencies, then EarlyMutators are identical to BottomUpMutators. Deperecate both, and reimplement DynamicDependencies inside a BottomUpMutator that is guaranteed to be registered first.
This commit is contained in:
parent
45021dcbbd
commit
763b6f18fa
3 changed files with 87 additions and 150 deletions
109
context.go
109
context.go
|
@ -224,12 +224,16 @@ func (e *Error) Error() string {
|
|||
// RegisterSingletonFactory methods must be called before it can do anything
|
||||
// useful.
|
||||
func NewContext() *Context {
|
||||
return &Context{
|
||||
ctx := &Context{
|
||||
moduleFactories: make(map[string]ModuleFactory),
|
||||
moduleGroups: make(map[string]*moduleGroup),
|
||||
moduleInfo: make(map[Module]*moduleInfo),
|
||||
moduleNinjaNames: make(map[string]*moduleGroup),
|
||||
}
|
||||
|
||||
ctx.RegisterBottomUpMutator("blueprint_deps", blueprintDepsMutator)
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
// A ModuleFactory function creates a new Module object. See the
|
||||
|
@ -402,6 +406,10 @@ func (c *Context) RegisterBottomUpMutator(name string, mutator BottomUpMutator)
|
|||
//
|
||||
// The mutator type names given here must be unique to all bottom up or early
|
||||
// mutators in the Context.
|
||||
//
|
||||
// Deprecated, use a BottomUpMutator instead. The only difference between
|
||||
// EarlyMutator and BottomUpMutator is that EarlyMutator runs before the
|
||||
// deprecated DynamicDependencies.
|
||||
func (c *Context) RegisterEarlyMutator(name string, mutator EarlyMutator) {
|
||||
for _, m := range c.variantMutatorNames {
|
||||
if m == name {
|
||||
|
@ -1057,27 +1065,8 @@ func (c *Context) addModule(module *moduleInfo) []error {
|
|||
// modules defined in the parsed Blueprints files are valid. This means that
|
||||
// the modules depended upon are defined and that no circular dependencies
|
||||
// exist.
|
||||
//
|
||||
// The config argument is made available to all of the DynamicDependerModule
|
||||
// objects via the Config method on the DynamicDependerModuleContext objects
|
||||
// passed to their DynamicDependencies method.
|
||||
func (c *Context) ResolveDependencies(config interface{}) []error {
|
||||
errs := c.runEarlyMutators(config)
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
errs = c.resolveDependencies(config)
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
errs = c.updateDependencies()
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
errs = c.runMutators(config)
|
||||
errs := c.runMutators(config)
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
@ -1086,74 +1075,24 @@ func (c *Context) ResolveDependencies(config interface{}) []error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// moduleDeps adds dependencies to a module. If the module implements the
|
||||
// Default dependencies handling. If the module implements the (deprecated)
|
||||
// DynamicDependerModule interface then this set consists of the union of those
|
||||
// module names listed in its "deps" property, those returned by its
|
||||
// DynamicDependencies method, and those added by calling AddDependencies or
|
||||
// AddVariationDependencies on DynamicDependencyModuleContext. Otherwise it
|
||||
// is simply those names listed in its "deps" property.
|
||||
func (c *Context) moduleDeps(module *moduleInfo,
|
||||
config interface{}) (errs []error) {
|
||||
func blueprintDepsMutator(ctx BottomUpMutatorContext) {
|
||||
ctx.AddDependency(ctx.Module(), ctx.moduleInfo().properties.Deps...)
|
||||
|
||||
depNamesSet := make(map[string]bool)
|
||||
depNames := []string{}
|
||||
if dynamicDepender, ok := ctx.Module().(DynamicDependerModule); ok {
|
||||
dynamicDeps := dynamicDepender.DynamicDependencies(ctx)
|
||||
|
||||
for _, depName := range module.properties.Deps {
|
||||
if !depNamesSet[depName] {
|
||||
depNamesSet[depName] = true
|
||||
depNames = append(depNames, depName)
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.AddDependency(ctx.Module(), dynamicDeps...)
|
||||
}
|
||||
|
||||
dynamicDepender, ok := module.logicModule.(DynamicDependerModule)
|
||||
if ok {
|
||||
ddmctx := &dynamicDependerModuleContext{
|
||||
baseModuleContext: baseModuleContext{
|
||||
context: c,
|
||||
config: config,
|
||||
module: module,
|
||||
},
|
||||
module: module,
|
||||
}
|
||||
|
||||
dynamicDeps := dynamicDepender.DynamicDependencies(ddmctx)
|
||||
|
||||
if len(ddmctx.errs) > 0 {
|
||||
return ddmctx.errs
|
||||
}
|
||||
|
||||
for _, depName := range dynamicDeps {
|
||||
if !depNamesSet[depName] {
|
||||
depNamesSet[depName] = true
|
||||
depNames = append(depNames, depName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, depName := range depNames {
|
||||
newErrs := c.addDependency(module, depName)
|
||||
if len(newErrs) > 0 {
|
||||
errs = append(errs, newErrs...)
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// resolveDependencies populates the directDeps list for every module. In doing so it checks for
|
||||
// missing dependencies and self-dependant modules.
|
||||
func (c *Context) resolveDependencies(config interface{}) (errs []error) {
|
||||
for _, group := range c.moduleGroups {
|
||||
for _, module := range group.modules {
|
||||
module.directDeps = make([]*moduleInfo, 0, len(module.properties.Deps))
|
||||
|
||||
newErrs := c.moduleDeps(module, config)
|
||||
if len(newErrs) > 0 {
|
||||
errs = append(errs, newErrs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// findMatchingVariant searches the moduleGroup for a module with the same variant as module,
|
||||
|
@ -1545,10 +1484,20 @@ func (c *Context) runEarlyMutators(config interface{}) (errs []error) {
|
|||
}
|
||||
}
|
||||
|
||||
errs = c.updateDependencies()
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) runMutators(config interface{}) (errs []error) {
|
||||
errs = c.runEarlyMutators(config)
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
for _, mutator := range c.mutatorInfo {
|
||||
if mutator.topDownMutator != nil {
|
||||
errs = c.runTopDownMutator(config, mutator.name, mutator.topDownMutator)
|
||||
|
|
|
@ -92,7 +92,7 @@ func TestContextParse(t *testing.T) {
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
errs = ctx.resolveDependencies(nil)
|
||||
errs = ctx.ResolveDependencies(nil)
|
||||
if len(errs) > 0 {
|
||||
t.Errorf("unexpected dep errors:")
|
||||
for _, err := range errs {
|
||||
|
@ -100,16 +100,6 @@ func TestContextParse(t *testing.T) {
|
|||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
errs = ctx.updateDependencies()
|
||||
if len(errs) > 0 {
|
||||
t.Errorf("unexpected dep cycle errors:")
|
||||
for _, err := range errs {
|
||||
t.Errorf(" %s", err)
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// |---B===D - represents a non-walkable edge
|
||||
|
|
116
module_ctx.go
116
module_ctx.go
|
@ -34,10 +34,11 @@ import (
|
|||
//
|
||||
// The Module implementation can access the build configuration as well as any
|
||||
// modules on which on which it depends (as defined by the "deps" property
|
||||
// specified in the Blueprints file or dynamically added by implementing the
|
||||
// DynamicDependerModule interface) using the ModuleContext passed to
|
||||
// GenerateBuildActions. This ModuleContext is also used to create Ninja build
|
||||
// actions and to report errors to the user.
|
||||
// specified in the Blueprints file, dynamically added by implementing the
|
||||
// (deprecated) DynamicDependerModule interface, or dynamically added by a
|
||||
// BottomUpMutator) using the ModuleContext passed to GenerateBuildActions.
|
||||
// This ModuleContext is also used to create Ninja build actions and to report
|
||||
// errors to the user.
|
||||
//
|
||||
// In addition to implementing the GenerateBuildActions method, a Module should
|
||||
// implement methods that provide dependant modules and singletons information
|
||||
|
@ -93,6 +94,8 @@ type Module interface {
|
|||
// appear in its "deps" property. Any Module that implements this interface
|
||||
// will have its DynamicDependencies method called by the Context that created
|
||||
// it during generate phase.
|
||||
//
|
||||
// Deprecated, use a BottomUpMutator instead
|
||||
type DynamicDependerModule interface {
|
||||
Module
|
||||
|
||||
|
@ -114,14 +117,11 @@ type BaseModuleContext interface {
|
|||
ModuleErrorf(fmt string, args ...interface{})
|
||||
PropertyErrorf(property, fmt string, args ...interface{})
|
||||
Failed() bool
|
||||
|
||||
moduleInfo() *moduleInfo
|
||||
}
|
||||
|
||||
type DynamicDependerModuleContext interface {
|
||||
BaseModuleContext
|
||||
|
||||
AddVariationDependencies([]Variation, ...string)
|
||||
AddFarVariationDependencies([]Variation, ...string)
|
||||
}
|
||||
type DynamicDependerModuleContext BottomUpMutatorContext
|
||||
|
||||
type ModuleContext interface {
|
||||
BaseModuleContext
|
||||
|
@ -157,6 +157,10 @@ type baseModuleContext struct {
|
|||
errs []error
|
||||
}
|
||||
|
||||
func (d *baseModuleContext) moduleInfo() *moduleInfo {
|
||||
return d.module
|
||||
}
|
||||
|
||||
func (d *baseModuleContext) ModuleName() string {
|
||||
return d.module.properties.Name
|
||||
}
|
||||
|
@ -315,49 +319,6 @@ func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// DynamicDependerModuleContext
|
||||
//
|
||||
|
||||
type dynamicDependerModuleContext struct {
|
||||
baseModuleContext
|
||||
|
||||
module *moduleInfo
|
||||
}
|
||||
|
||||
// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
|
||||
// argument to select which variant of the dependency to use. A variant of the dependency must
|
||||
// exist that matches the all of the non-local variations of the current module, plus the variations
|
||||
// argument.
|
||||
func (mctx *dynamicDependerModuleContext) AddVariationDependencies(variations []Variation,
|
||||
deps ...string) {
|
||||
|
||||
for _, dep := range deps {
|
||||
errs := mctx.context.addVariationDependency(mctx.module, variations, dep, false)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
|
||||
// variations argument to select which variant of the dependency to use. A variant of the
|
||||
// dependency must exist that matches the variations argument, but may also have other variations.
|
||||
// For any unspecified variation the first variant will be used.
|
||||
//
|
||||
// Unlike AddVariationDependencies, the variations of the current module are ignored - the
|
||||
// depdendency only needs to match the supplied variations.
|
||||
func (mctx *dynamicDependerModuleContext) AddFarVariationDependencies(variations []Variation,
|
||||
deps ...string) {
|
||||
|
||||
for _, dep := range deps {
|
||||
errs := mctx.context.addVariationDependency(mctx.module, variations, dep, true)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// MutatorContext
|
||||
//
|
||||
|
@ -393,11 +354,13 @@ type TopDownMutatorContext interface {
|
|||
type BottomUpMutatorContext interface {
|
||||
baseMutatorContext
|
||||
|
||||
AddDependency(module Module, name string)
|
||||
AddDependency(module Module, name ...string)
|
||||
AddReverseDependency(module Module, name string)
|
||||
CreateVariations(...string) []Module
|
||||
CreateLocalVariations(...string) []Module
|
||||
SetDependencyVariation(string)
|
||||
AddVariationDependencies([]Variation, ...string)
|
||||
AddFarVariationDependencies([]Variation, ...string)
|
||||
}
|
||||
|
||||
// A Mutator function is called for each Module, and can use
|
||||
|
@ -473,10 +436,12 @@ func (mctx *mutatorContext) Module() Module {
|
|||
// Add a dependency to the given module.
|
||||
// Does not affect the ordering of the current mutator pass, but will be ordered
|
||||
// correctly for all future mutator passes.
|
||||
func (mctx *mutatorContext) AddDependency(module Module, depName string) {
|
||||
errs := mctx.context.addDependency(mctx.context.moduleInfo[module], depName)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
func (mctx *mutatorContext) AddDependency(module Module, deps ...string) {
|
||||
for _, dep := range deps {
|
||||
errs := mctx.context.addDependency(mctx.context.moduleInfo[module], dep)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -484,12 +449,45 @@ func (mctx *mutatorContext) AddDependency(module Module, depName string) {
|
|||
// Does not affect the ordering of the current mutator pass, but will be ordered
|
||||
// correctly for all future mutator passes.
|
||||
func (mctx *mutatorContext) AddReverseDependency(module Module, destName string) {
|
||||
errs := mctx.context.addReverseDependency(mctx.context.moduleInfo[module], destName)
|
||||
errs := mctx.context.addReverseDependency(mctx.module, destName)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
}
|
||||
}
|
||||
|
||||
// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
|
||||
// argument to select which variant of the dependency to use. A variant of the dependency must
|
||||
// exist that matches the all of the non-local variations of the current module, plus the variations
|
||||
// argument.
|
||||
func (mctx *mutatorContext) AddVariationDependencies(variations []Variation,
|
||||
deps ...string) {
|
||||
|
||||
for _, dep := range deps {
|
||||
errs := mctx.context.addVariationDependency(mctx.module, variations, dep, false)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
|
||||
// variations argument to select which variant of the dependency to use. A variant of the
|
||||
// dependency must exist that matches the variations argument, but may also have other variations.
|
||||
// For any unspecified variation the first variant will be used.
|
||||
//
|
||||
// Unlike AddVariationDependencies, the variations of the current module are ignored - the
|
||||
// depdendency only needs to match the supplied variations.
|
||||
func (mctx *mutatorContext) AddFarVariationDependencies(variations []Variation,
|
||||
deps ...string) {
|
||||
|
||||
for _, dep := range deps {
|
||||
errs := mctx.context.addVariationDependency(mctx.module, variations, dep, true)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) VisitDirectDeps(visit func(Module)) {
|
||||
mctx.context.visitDirectDeps(mctx.module, visit)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue