Skip to content

Commit

Permalink
Merge pull request #2051 from alixander/fix-glob-edge
Browse files Browse the repository at this point in the history
d2ir: fix edge glob edge case
  • Loading branch information
alixander authored Aug 6, 2024
2 parents ddf68ca + df0648a commit 9201649
Show file tree
Hide file tree
Showing 5 changed files with 3,653 additions and 1,920 deletions.
1 change: 1 addition & 0 deletions ci/release/changelogs/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@

- Sequence diagram multi-line edge labels no longer can collide with other elements [#2049](https://github.com/terrastruct/d2/pull/2049)
- Sequence diagram long self-referential edge labels no longer can collide neighboring actors (or its own) lifeline edges [#2050](https://github.com/terrastruct/d2/pull/2050)
- Globs: An edge case was fixed where globs used in edges were creating nodes when it shouldn't have [#2051](https://github.com/terrastruct/d2/pull/2051)
49 changes: 44 additions & 5 deletions d2ir/d2ir.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ func (eid *EdgeID) resolve(m *Map) (_ *EdgeID, _ *Map, common []string, _ error)
}

for len(eid.SrcPath) > 1 && len(eid.DstPath) > 1 {
if !strings.EqualFold(eid.SrcPath[0], eid.DstPath[0]) || eid.SrcPath[0] == "*" {
if !strings.EqualFold(eid.SrcPath[0], eid.DstPath[0]) || strings.Contains(eid.SrcPath[0], "*") {
return eid, m, common, nil
}
common = append(common, eid.SrcPath[0])
Expand Down Expand Up @@ -1218,19 +1218,19 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, gctx *globContext, c *
eid2.SrcPath = RelIDA(m, src)
eid2.DstPath = RelIDA(m, dst)

e, err := m.createEdge2(eid2, refctx, gctx, c, src, dst)
es, err := m.createEdge2(eid2, refctx, gctx, c, src, dst)
if err != nil {
return err
}
if e != nil {
for _, e := range es {
*ea = append(*ea, e)
}
}
}
return nil
}

func (m *Map) createEdge2(eid *EdgeID, refctx *RefContext, gctx *globContext, c *compiler, src, dst *Field) (*Edge, error) {
func (m *Map) createEdge2(eid *EdgeID, refctx *RefContext, gctx *globContext, c *compiler, src, dst *Field) ([]*Edge, error) {
if NodeBoardKind(src) != "" {
return nil, d2parser.Errorf(refctx.Edge.Src, "cannot create edges between boards")
}
Expand All @@ -1241,6 +1241,45 @@ func (m *Map) createEdge2(eid *EdgeID, refctx *RefContext, gctx *globContext, c
return nil, d2parser.Errorf(refctx.Edge, "cannot create edges between boards")
}

eid, m, common, err := eid.resolve(m)
if err != nil {
return nil, d2parser.Errorf(refctx.Edge, err.Error())
}
if len(common) > 0 {
commonKP := d2ast.MakeKeyPath(common)
lastMatch := 0
for i, el := range commonKP.Path {
for j := lastMatch; j < len(refctx.Edge.Src.Path); j++ {
realEl := refctx.Edge.Src.Path[j]
if el.ScalarString() == realEl.ScalarString() {
commonKP.Path[i] = realEl
lastMatch += j + 1
}
}
}
fa, err := m.EnsureField(commonKP, nil, true, c)
if err != nil {
return nil, err
}
var edges []*Edge
for _, f := range fa {
if _, ok := f.Composite.(*Array); ok {
return nil, d2parser.Errorf(refctx.Edge.Src, "cannot index into array")
}
if f.Map() == nil {
f.Composite = &Map{
parent: f,
}
}
edges2, err := f.Map().createEdge2(eid, refctx, gctx, c, src, dst)
if err != nil {
return nil, err
}
edges = append(edges, edges2...)
}
return edges, nil
}

eid.Index = nil
eid.Glob = true
ea := m.GetEdges(eid, nil, nil)
Expand Down Expand Up @@ -1276,7 +1315,7 @@ func (m *Map) createEdge2(eid *EdgeID, refctx *RefContext, gctx *globContext, c

m.Edges = append(m.Edges, e)

return e, nil
return []*Edge{e}, nil
}

func (s *Scalar) AST() d2ast.Node {
Expand Down
18 changes: 18 additions & 0 deletions d2ir/pattern_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,24 @@ sh*.an* -> sh*.an*`)
assertQuery(t, m, 0, 0, nil, "shared.(animal -> animate)[0]")
},
},
{
name: "edge/4",
run: func(t testing.TB) {
m, err := compile(t, `app_a: {
x
}
app_b: {
y
}
app_*.x -> app_*.y`)
assert.Success(t, err)
assertQuery(t, m, 6, 4, nil, "")
assertQuery(t, m, 2, 1, nil, "app_a")
assertQuery(t, m, 2, 1, nil, "app_b")
},
},
{
name: "edge-glob-index",
run: func(t testing.TB) {
Expand Down
Loading

0 comments on commit 9201649

Please sign in to comment.