Merge pull request #61 from yuchenericwu2/master
Add walkDeps to context and module_ctx.
diff --git a/context.go b/context.go
index dd2dc1d..982cf72 100644
--- a/context.go
+++ b/context.go
@@ -1825,6 +1825,27 @@
return nil
}
+func (c *Context) walkDeps(topModule *moduleInfo,
+ visit func(Module, Module) bool) {
+
+ visited := make(map[*moduleInfo]bool)
+
+ var walk func(module *moduleInfo)
+ walk = func(module *moduleInfo) {
+ visited[module] = true
+
+ for _, moduleDep := range module.directDeps {
+ if !visited[moduleDep] {
+ if visit(moduleDep.logicModule, module.logicModule) {
+ walk(moduleDep)
+ }
+ }
+ }
+ }
+
+ walk(topModule)
+}
+
func (c *Context) visitDepsDepthFirst(topModule *moduleInfo, visit func(Module)) {
visited := make(map[*moduleInfo]bool)
diff --git a/context_test.go b/context_test.go
index 1c4303b..8877be9 100644
--- a/context_test.go
+++ b/context_test.go
@@ -19,6 +19,10 @@
"testing"
)
+type Walker interface {
+ Walk() bool
+}
+
type fooModule struct {
properties struct {
Foo string
@@ -37,6 +41,10 @@
return f.properties.Foo
}
+func (f *fooModule) Walk() bool {
+ return true
+}
+
type barModule struct {
properties struct {
Bar bool
@@ -55,6 +63,10 @@
return b.properties.Bar
}
+func (b *barModule) Walk() bool {
+ return false
+}
+
func TestContextParse(t *testing.T) {
ctx := NewContext()
ctx.RegisterModuleType("foo_module", newFooModule)
@@ -99,3 +111,30 @@
}
}
+
+// |---B===D - represents a non-walkable edge
+// A = represents a walkable edge
+// |===C---E===G
+// | | A should not be visited because it's the root node.
+// |===F===| B, D and E should not be walked.
+func TestWalkDeps(t *testing.T) {
+ ctx := NewContext()
+ ctx.RegisterModuleType("foo_module", newFooModule)
+ ctx.RegisterModuleType("bar_module", newBarModule)
+ ctx.ParseBlueprintsFiles("context_test_Blueprints")
+ ctx.ResolveDependencies(nil)
+
+ var output string
+ topModule := ctx.moduleGroups["A"].modules[0]
+ ctx.walkDeps(topModule,
+ func(module, parent Module) bool {
+ if module.(Walker).Walk() {
+ output += ctx.ModuleName(module)
+ return true
+ }
+ return false
+ })
+ if output != "CFG" {
+ t.Fatalf("unexpected walkDeps behaviour: %s\nshould be: CFG", output)
+ }
+}
diff --git a/context_test_Blueprints b/context_test_Blueprints
new file mode 100644
index 0000000..6cac8b2
--- /dev/null
+++ b/context_test_Blueprints
@@ -0,0 +1,32 @@
+foo_module {
+ name: "A",
+ deps: ["B", "C"],
+}
+
+bar_module {
+ name: "B",
+ deps: ["D"],
+}
+
+foo_module {
+ name: "C",
+ deps: ["E", "F"],
+}
+
+foo_module {
+ name: "D",
+}
+
+bar_module {
+ name: "E",
+ deps: ["G"],
+}
+
+foo_module {
+ name: "F",
+ deps: ["G"],
+}
+
+foo_module {
+ name: "G",
+}
diff --git a/module_ctx.go b/module_ctx.go
index 6254596..94db01e 100644
--- a/module_ctx.go
+++ b/module_ctx.go
@@ -133,6 +133,7 @@
VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
VisitDepsDepthFirst(visit func(Module))
VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
+ WalkDeps(visit func(Module, Module) bool)
ModuleSubDir() string
@@ -251,6 +252,10 @@
m.context.visitDepsDepthFirstIf(m.module, pred, visit)
}
+func (m *moduleContext) WalkDeps(visit func(Module, Module) bool) {
+ m.context.walkDeps(m.module, visit)
+}
+
func (m *moduleContext) ModuleSubDir() string {
return m.module.variantName
}
@@ -382,6 +387,7 @@
VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
VisitDepsDepthFirst(visit func(Module))
VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
+ WalkDeps(visit func(Module, Module) bool)
}
type BottomUpMutatorContext interface {
@@ -501,3 +507,7 @@
mctx.context.visitDepsDepthFirstIf(mctx.module, pred, visit)
}
+
+func (mctx *mutatorContext) WalkDeps(visit func(Module, Module) bool) {
+ mctx.context.walkDeps(mctx.module, visit)
+}