From a346542465c09285f317875b63326e8e4b83b1de Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Wed, 22 Feb 2023 12:15:59 -0800 Subject: [PATCH] add error for dagre container-child edge --- d2graph/d2graph.go | 10 ++++++++++ d2plugin/plugin_elk.go | 1 + d2plugin/plugin_features.go | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 385a6b2ed..d1a06cf52 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1586,3 +1586,13 @@ func (g *Graph) SortEdgesByAST() { }) g.Edges = edges } + +func (obj *Object) IsDescendantOf(ancestor *Object) bool { + if obj == ancestor { + return true + } + if obj.Parent == nil { + return false + } + return obj.Parent.IsDescendantOf(ancestor) +} diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index 3b2113c6d..d28fba3cb 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -89,6 +89,7 @@ func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) { Type: "bundled", Features: []PluginFeature{ CONTAINER_DIMENSIONS, + DESCENDANT_EDGES, }, ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.", LongHelp: fmt.Sprintf(`ELK is a layout engine offered by Eclipse. diff --git a/d2plugin/plugin_features.go b/d2plugin/plugin_features.go index f41462b37..20bdb4d95 100644 --- a/d2plugin/plugin_features.go +++ b/d2plugin/plugin_features.go @@ -18,6 +18,9 @@ const CONTAINER_DIMENSIONS PluginFeature = "container_dimensions" // When this is true, objects can specify their `top` and `left` keywords const TOP_LEFT PluginFeature = "top_left" +// When this is true, containers can have connections to descendants +const DESCENDANT_EDGES PluginFeature = "descendant_edges" + func FeatureSupportCheck(info *PluginInfo, g *d2graph.Graph) error { // Older version of plugin. Skip checking. if info.Features == nil { @@ -50,5 +53,12 @@ func FeatureSupportCheck(info *PluginInfo, g *d2graph.Graph) error { } } } + if _, ok := featureMap[DESCENDANT_EDGES]; !ok { + for _, e := range g.Edges { + if e.Src.IsDescendantOf(e.Dst) || e.Dst.IsDescendantOf(e.Src) { + return fmt.Errorf(`Connection "%s" goes from a container to a descendant, but layout engine "%s" does not support this.`, e.AbsID(), info.Name) + } + } + } return nil }