Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix edge glob bug #1857

Merged
merged 3 commits into from
Mar 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/release/changelogs/next.md
Original file line number Diff line number Diff line change
@@ -9,5 +9,6 @@

#### Bugfixes ⛑️

- Fixes styles in connections not overriding styles set by globs [#1857](https://github.com/terrastruct/d2/pull/1857)
- Fixes `null` being set on a nested shape not working in certain cases when connections also pointed to that shape [#1830](https://github.com/terrastruct/d2/pull/1830)
- Fixes edge case of bad import syntax crashing using d2 as a library [#1829](https://github.com/terrastruct/d2/pull/1829)
1 change: 1 addition & 0 deletions d2ast/d2ast.go
Original file line number Diff line number Diff line change
@@ -1025,6 +1025,7 @@ type EdgeIndex struct {
}

func (ei1 *EdgeIndex) Equals(ei2 *EdgeIndex) bool {
// TODO probably should be checking the values, but will wait until something breaks to change
if ei1.Int != ei2.Int {
return false
}
23 changes: 23 additions & 0 deletions d2compiler/compile_test.go
Original file line number Diff line number Diff line change
@@ -4367,6 +4367,29 @@ container_2: {
assert.Equal(t, 4, len(g.Objects))
},
},
{
name: "override-edge/1",
run: func(t *testing.T) {
g, _ := assertCompile(t, `
(* -> *)[*].style.stroke: red
(* -> *)[*].style.stroke: green
a -> b
`, ``)
assert.Equal(t, "green", g.Edges[0].Attributes.Style.Stroke.Value)
},
},
{
name: "override-edge/2",
run: func(t *testing.T) {
g, _ := assertCompile(t, `
(* -> *)[*].style.stroke: red
a -> b: {style.stroke: green}
a -> b
`, ``)
assert.Equal(t, "green", g.Edges[0].Attributes.Style.Stroke.Value)
assert.Equal(t, "red", g.Edges[1].Attributes.Style.Stroke.Value)
},
},
}

for _, tc := range tca {
1 change: 1 addition & 0 deletions d2ir/compile.go
Original file line number Diff line number Diff line change
@@ -413,6 +413,7 @@ func (c *compiler) ampersandFilterMap(dst *Map, ast, scopeAST *d2ast.Map) bool {
ks = d2format.Format(d2ast.MakeKeyPath(BoardIDA(dst)))
}
delete(gctx.appliedFields, ks)
delete(gctx.appliedEdges, ks)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this bug was causing filters on edges to not try to be applied again. which only surfaced because the other bug was fixed that errantly applied multiple times

return false
}
}
2 changes: 1 addition & 1 deletion d2ir/d2ir.go
Original file line number Diff line number Diff line change
@@ -1094,7 +1094,7 @@ func (m *Map) getEdges(eid *EdgeID, refctx *RefContext, gctx *globContext, ea *[
}
gctx.appliedEdges[ks] = struct{}{}
}
*ea = append(*ea, ea2...)
*ea = append(*ea, e)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this bug was causing globs to be applied multiple times

}
}
}
15 changes: 15 additions & 0 deletions d2ir/filter_test.go
Original file line number Diff line number Diff line change
@@ -150,6 +150,21 @@ x -> y
assertQuery(t, m, 0, 0, 0.1, "(x -> y)[1].style.opacity")
},
},
{
name: "label-filter/3",
run: func(t testing.TB) {
m, err := compile(t, `
(* -> *)[*]: {
&label: hi
style.opacity: 0.1
}

x -> y: hi
`)
assert.Success(t, err)
assertQuery(t, m, 0, 0, 0.1, "(x -> y)[0].style.opacity")
},
},
{
name: "lazy-filter",
run: func(t testing.TB) {
2 changes: 1 addition & 1 deletion d2ir/import_test.go
Original file line number Diff line number Diff line change
@@ -232,7 +232,7 @@ label: meow`,
_, err := compileFS(t, "index.d2", map[string]string{
"index.d2": "...@'./../x.d2'",
})
assert.ErrorString(t, err, `index.d2:1:1: failed to import "../x.d2": stat ../x.d2: invalid argument`)
assert.ErrorString(t, err, `index.d2:1:1: failed to import "../x.d2": open ../x.d2: invalid argument`)
},
},
{
27 changes: 17 additions & 10 deletions d2oracle/edit.go
Original file line number Diff line number Diff line change
@@ -497,16 +497,19 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string)
onlyInChain = false
}
}
// If a ref has an exact match on this key, just change the value
tmp1 := *ref.MapKey
tmp2 := *mk
noVal1 := &tmp1
noVal2 := &tmp2
noVal1.Value = d2ast.ValueBox{}
noVal2.Value = d2ast.ValueBox{}
if noVal1.D2OracleEquals(noVal2) {
ref.MapKey.Value = mk.Value
return nil

if ref.MapKey.EdgeIndex == nil || !ref.MapKey.EdgeIndex.Glob {
// If a ref has an exact match on this key, just change the value
tmp1 := *ref.MapKey
tmp2 := *mk
noVal1 := &tmp1
noVal2 := &tmp2
noVal1.Value = d2ast.ValueBox{}
noVal2.Value = d2ast.ValueBox{}
if noVal1.D2OracleEquals(noVal2) {
ref.MapKey.Value = mk.Value
return nil
}
}
}
if onlyInChain {
@@ -575,6 +578,10 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string)
if s.MapKey.Range.Path != baseAST.Range.Path {
return false
}
// Globs are also not writeable
if s.MapKey.HasGlob() {
return false
}
}
return s != nil && s.MapKey != nil && !ir.InClass(s.MapKey)
}
68 changes: 68 additions & 0 deletions d2oracle/edit_test.go
Original file line number Diff line number Diff line change
@@ -2335,6 +2335,48 @@ layers: {
near: bottom-right
}
}
`,
},
{
name: "glob-field/1",

text: `*.style.fill: red
a
b
`,
key: `a.style.fill`,
value: go2.Pointer(`blue`),
exp: `*.style.fill: red
a: {style.fill: blue}
b
`,
},
{
name: "glob-field/2",

text: `(* -> *)[*].style.stroke: red
a -> b
a -> b
`,
key: `(a -> b)[0].style.stroke`,
value: go2.Pointer(`blue`),
exp: `(* -> *)[*].style.stroke: red
a -> b: {style.stroke: blue}
a -> b
`,
},
{
name: "glob-field/3",

text: `(* -> *)[*].style.stroke: red
a -> b: {style.stroke: blue}
a -> b
`,
key: `(a -> b)[0].style.stroke`,
value: go2.Pointer(`green`),
exp: `(* -> *)[*].style.stroke: red
a -> b: {style.stroke: green}
a -> b
`,
},
}
@@ -7445,6 +7487,32 @@ a.style.fill: null
`,
key: `yes.label.near`,
exp: `yes
`,
},
{
name: "connection-glob",

text: `* -> *
a
b
`,
key: `(a -> b)[0]`,
exp: `* -> *
a
b
(a -> b)[0]: null
`,
},
{
name: "glob-child/1",

text: `*.b
a
`,
key: `a.b`,
exp: `*.b
a
a.b: null
`,
},
}
8 changes: 8 additions & 0 deletions d2oracle/get.go
Original file line number Diff line number Diff line change
@@ -142,6 +142,9 @@ func GetParentID(g *d2graph.Graph, boardPath []string, absID string) (string, er

func IsImportedObj(ast *d2ast.Map, obj *d2graph.Object) bool {
for _, ref := range obj.References {
if ref.Key.HasGlob() {
return true
}
if ref.Key.Range.Path != ast.Range.Path {
return true
}
@@ -150,8 +153,13 @@ func IsImportedObj(ast *d2ast.Map, obj *d2graph.Object) bool {
return false
}

// Globs count as imported for now
// TODO Probably rename later
func IsImportedEdge(ast *d2ast.Map, edge *d2graph.Edge) bool {
for _, ref := range edge.References {
if ref.Edge.Src.HasGlob() || ref.Edge.Dst.HasGlob() {
return true
}
if ref.Edge.Range.Path != ast.Range.Path {
return true
}
2 changes: 1 addition & 1 deletion docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ git submodule update --recursive

## Logistics

- Use Go 1.20.
- Use Go 1.22.
- Please sign your commits
([https://github.com/terrastruct/d2/pull/557#issuecomment-1367468730](https://github.com/terrastruct/d2/pull/557#issuecomment-1367468730)).
- D2 uses Issues as TODOs. No auto-closing on staleness.
2 changes: 1 addition & 1 deletion go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading