diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index d5eb8c8d8..7817d0afa 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -27,6 +27,7 @@ - fixes globs not applying to spread substitutions [#2426](https://github.com/terrastruct/d2/issues/2426) - fixes panic when classes were mixed with layers incorrectly [#2448](https://github.com/terrastruct/d2/pull/2448) - CLI: fetch and render remote images of mimetype octet-stream correctly [#2370](https://github.com/terrastruct/d2/pull/2370) +- Composition: spread importing scenarios/steps was not inheriting correctly [#2460](https://github.com/terrastruct/d2/pull/2460) - Markdown: fixes nested var substitutions not working [#2456](https://github.com/terrastruct/d2/pull/2456) - d2js: handle unicode characters [#2393](https://github.com/terrastruct/d2/pull/2393) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 5b44dcfe1..bb939a807 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -1714,6 +1714,55 @@ steps: { assert.Equal(t, 1, len(g.Layers[0].Steps)) }, }, + { + name: "import-scenario", + + text: `a + +...@test +`, + files: map[string]string{ + "test.d2": ` +x + +scenarios: { + production: { + x.tooltip: foo + } +} + +`, + }, + assertions: func(t *testing.T, g *d2graph.Graph) { + assert.Equal(t, 2, len(g.Scenarios[0].Objects)) + }, + }, + { + name: "import-steps", + + text: `a + +...@test +`, + files: map[string]string{ + "test.d2": ` +x + +steps: { + 1: { + x.tooltip: foo + } + 2: { + x.tooltip: do + } +} +`, + }, + assertions: func(t *testing.T, g *d2graph.Graph) { + assert.Equal(t, 2, len(g.Steps[0].Objects)) + assert.Equal(t, 2, len(g.Steps[1].Objects)) + }, + }, { name: "import-classes-boards", diff --git a/d2ir/compile.go b/d2ir/compile.go index 3a2e2996c..c7bf15e9d 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -604,6 +604,20 @@ func (c *compiler) compileMap(dst *Map, ast, scopeAST *d2ast.Map) { c.ensureGlobContext(gctx2.refctx) } + scenariosField := impn.Map().GetField(d2ast.FlatUnquotedString("scenarios")) + if scenariosField != nil && scenariosField.Map() != nil { + for _, sf := range scenariosField.Map().Fields { + c.overlay(dst, sf) + } + } + + stepsField := impn.Map().GetField(d2ast.FlatUnquotedString("steps")) + if stepsField != nil && stepsField.Map() != nil { + for _, sf := range stepsField.Map().Fields { + c.overlay(dst, sf) + } + } + OverlayMap(dst, impn.Map()) impDir := n.Import.Dir() c.extendLinks(dst, ParentField(dst), impDir) diff --git a/testdata/d2compiler/TestCompile/import-scenario.exp.json b/testdata/d2compiler/TestCompile/import-scenario.exp.json new file mode 100644 index 000000000..9f6c22826 --- /dev/null +++ b/testdata/d2compiler/TestCompile/import-scenario.exp.json @@ -0,0 +1,417 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-3:0:12", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "import": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,2:0:3-2:8:11", + "spread": true, + "pre": "", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,2:4:7-2:8:11", + "value": [ + { + "string": "test", + "raw_string": "test" + } + ] + } + } + ] + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "scenarios": [ + { + "name": "production", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,0:0:0-1:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:6:39-5:13:46", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:15:48-5:18:51", + "value": [ + { + "string": "foo", + "raw_string": "foo" + } + ] + } + }, + "value": {} + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-scenario.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:4:37-5:13:46", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:4:37-5:5:38", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:6:39-5:13:46", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "tooltip": { + "value": "foo" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/import-steps.exp.json b/testdata/d2compiler/TestCompile/import-steps.exp.json new file mode 100644 index 000000000..23d9a9323 --- /dev/null +++ b/testdata/d2compiler/TestCompile/import-steps.exp.json @@ -0,0 +1,692 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-3:0:12", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "import": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,2:0:3-2:8:11", + "spread": true, + "pre": "", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,2:4:7-2:8:11", + "value": [ + { + "string": "test", + "raw_string": "test" + } + ] + } + } + ] + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "steps": [ + { + "name": "1", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,0:0:0-1:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:6:26-5:13:33", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:15:35-5:18:38", + "value": [ + { + "string": "foo", + "raw_string": "foo" + } + ] + } + }, + "value": {} + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:4:24-5:13:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:4:24-5:5:25", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:6:26-5:13:33", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "tooltip": { + "value": "foo" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + { + "name": "2", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,0:0:0-1:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:6:26-5:13:33", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,8:15:65-8:17:67", + "value": [ + { + "string": "do", + "raw_string": "do" + } + ] + } + }, + "value": {} + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-steps.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,1:0:1-1:1:2", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:4:24-5:13:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:4:24-5:5:25", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,5:6:26-5:13:33", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,8:4:54-8:13:63", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,8:4:54-8:5:55", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/test.d2,8:6:56-8:13:63", + "value": [ + { + "string": "tooltip", + "raw_string": "tooltip" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "tooltip": { + "value": "do" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + } + ] + }, + "err": null +}