diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 4d6aa3137..11765c577 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -97,6 +97,7 @@ func (c *compiler) compileBoardsField(g *d2graph.Graph, ir *d2ir.Map, fieldName continue } g2 := d2graph.NewGraph() + g2.Parent = g g2.AST = g.AST c.compileBoard(g2, f.Map()) g2.Name = f.Name diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index b546d9e64..a5f3e5022 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2036,7 +2036,7 @@ layers: { } }`, assertions: func(t *testing.T, g *d2graph.Graph) { - tassert.Equal(t, g.Layers[0].Name, g.Objects[0].LinkedBoard.Name) + tassert.Equal(t, ".layers.x", g.Objects[0].LinkedBoard.AbsID()) }, }, { @@ -2056,7 +2056,7 @@ scenarios: { } }`, assertions: func(t *testing.T, g *d2graph.Graph) { - tassert.Equal(t, g.Layers[0].Name, g.Objects[0].LinkedBoard.Name) + tassert.Equal(t, ".layers.cat", g.Objects[0].LinkedBoard.AbsID()) }, }, { @@ -2089,7 +2089,7 @@ layers: { } }`, assertions: func(t *testing.T, g *d2graph.Graph) { - tassert.Equal(t, g.Layers[0].Layers[0], g.Objects[0].LinkedBoard) + tassert.Equal(t, ".layers.x.layers.x", g.Objects[0].LinkedBoard.AbsID()) }, }, } diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index cc4401abf..1defc43de 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -28,7 +28,8 @@ const DEFAULT_SHAPE_SIZE = 100. const MIN_SHAPE_SIZE = 5 type Graph struct { - Name string `json:"name"` + Parent *Graph `json:"-"` + Name string `json:"name"` // IsFolderOnly indicates a board or scenario itself makes no modifications from its // base. Folder only boards do not have a render and are used purely for organizing // the board tree. @@ -55,6 +56,28 @@ func NewGraph() *Graph { return d } +func (g *Graph) AbsID() string { + if g.Parent == nil { + return g.Name + } + for _, l := range g.Parent.Layers { + if l.Name == g.Name { + return g.Parent.AbsID() + ".layers." + g.Name + } + } + for _, s := range g.Parent.Scenarios { + if s.Name == g.Name { + return g.Parent.AbsID() + ".scenarios." + g.Name + } + } + for _, s := range g.Parent.Steps { + if s.Name == g.Name { + return g.Parent.AbsID() + ".steps." + g.Name + } + } + return "" +} + // TODO consider having different Scalar types // Right now we'll hold any types in Value and just convert, e.g. floats type Scalar struct {