diff --git a/d2oracle/edit.go b/d2oracle/edit.go index 3bf8ec541..4e6c3f96d 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -2117,7 +2117,7 @@ func updateNear(prevG, g *d2graph.Graph, from, to *string, includeDescendants bo tmpG, _ := recompile(prevG.AST) appendMapKey(tmpG.AST, valueMK) if to == nil { - deltas, err := DeleteIDDeltas(tmpG, *from) + deltas, err := DeleteIDDeltas(tmpG, nil, *from) if err != nil { return err } @@ -2162,7 +2162,7 @@ func updateNear(prevG, g *d2graph.Graph, from, to *string, includeDescendants bo tmpG, _ := recompile(prevG.AST) appendMapKey(tmpG.AST, valueMK) if to == nil { - deltas, err := DeleteIDDeltas(tmpG, *from) + deltas, err := DeleteIDDeltas(tmpG, nil, *from) if err != nil { return err } @@ -2196,23 +2196,34 @@ func deleteFromMap(m *d2ast.Map, mk *d2ast.Key) bool { return false } -func ReparentIDDelta(g *d2graph.Graph, key, parentKey string) (string, error) { +func ReparentIDDelta(g *d2graph.Graph, boardPath []string, key, parentKey string) (string, error) { mk, err := d2parser.ParseMapKey(key) if err != nil { return "", err } - obj, ok := g.Root.HasChild(d2graph.Key(mk.Key)) + + boardG := g + + if len(boardPath) > 0 { + // When compiling a nested board, we can read from boardG but only write to baseBoardG + boardG = GetBoardGraph(g, boardPath) + if boardG == nil { + return "", fmt.Errorf("board %v not found", boardPath) + } + } + + obj, ok := boardG.Root.HasChild(d2graph.Key(mk.Key)) if !ok { return "", errors.New("not found") } - parent := g.Root + parent := boardG.Root if parentKey != "" { mk2, err := d2parser.ParseMapKey(parentKey) if err != nil { return "", err } - parent, ok = g.Root.HasChild(d2graph.Key(mk2.Key)) + parent, ok = boardG.Root.HasChild(d2graph.Key(mk2.Key)) if !ok { return "", errors.New("not found") } @@ -2693,7 +2704,7 @@ func MoveIDDeltas(g *d2graph.Graph, key, newKey string, includeDescendants bool) return deltas, nil } -func DeleteIDDeltas(g *d2graph.Graph, key string) (deltas map[string]string, err error) { +func DeleteIDDeltas(g *d2graph.Graph, boardPath []string, key string) (deltas map[string]string, err error) { defer xdefer.Errorf(&err, "failed to get deltas for deletion of %#v", key) deltas = make(map[string]string) @@ -2703,7 +2714,16 @@ func DeleteIDDeltas(g *d2graph.Graph, key string) (deltas map[string]string, err } edgeTrimCommon(mk) - obj := g.Root + + boardG := g + if len(boardPath) > 0 { + boardG = GetBoardGraph(g, boardPath) + if boardG == nil { + return nil, fmt.Errorf("board %v not found", boardPath) + } + } + + obj := boardG.Root conflictNewIDs := make(map[*d2graph.Object]string) conflictOldIDs := make(map[*d2graph.Object]string) var newIDs []string @@ -2715,7 +2735,7 @@ func DeleteIDDeltas(g *d2graph.Graph, key string) (deltas map[string]string, err } var ok bool - obj, ok = g.Root.HasChild(d2graph.Key(mk.Key)) + obj, ok = boardG.Root.HasChild(d2graph.Key(mk.Key)) if !ok { return nil, nil } @@ -2742,7 +2762,7 @@ func DeleteIDDeltas(g *d2graph.Graph, key string) (deltas map[string]string, err continue } hoistedAbsID := ch2.ID - if obj.Parent != g.Root { + if obj.Parent != boardG.Root { hoistedAbsID = obj.Parent.AbsID() + "." + ch2.ID } siblingsToBeHoisted = append(siblingsToBeHoisted, hoistedAbsID) @@ -2757,7 +2777,7 @@ func DeleteIDDeltas(g *d2graph.Graph, key string) (deltas map[string]string, err continue } hoistedAbsID := ch.ID - if obj.Parent != g.Root { + if obj.Parent != boardG.Root { hoistedAbsID = obj.Parent.AbsID() + "." + ch.ID } hoistedMK, err := d2parser.ParseMapKey(hoistedAbsID) @@ -2773,8 +2793,8 @@ func DeleteIDDeltas(g *d2graph.Graph, key string) (deltas map[string]string, err } } - if conflictingObj, ok := g.Root.HasChild(d2graph.Key(hoistedMK.Key)); (ok && conflictingObj != obj) || conflictsWithNewID { - newKey, _, err := generateUniqueKey(g, hoistedAbsID, ignored, append(newIDs, siblingsToBeHoisted...)) + if conflictingObj, ok := boardG.Root.HasChild(d2graph.Key(hoistedMK.Key)); (ok && conflictingObj != obj) || conflictsWithNewID { + newKey, _, err := generateUniqueKey(boardG, hoistedAbsID, ignored, append(newIDs, siblingsToBeHoisted...)) if err != nil { return nil, err } diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index bf4d864a1..7912546ee 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -7730,8 +7730,9 @@ func TestDeleteIDDeltas(t *testing.T) { testCases := []struct { name string - text string - key string + boardPath []string + text string + key string exp string expErr string @@ -7998,6 +7999,55 @@ Square exp: `{ "x.Square 2": "Square 4", "x.Square 3": "Square 3" +}`, + }, + { + name: "scenarios-basic", + text: `x + +scenarios: { + y: { + a + } +} +`, + boardPath: []string{"y"}, + key: `a`, + + exp: `{}`, + }, + { + name: "scenarios-parent", + text: `x + +scenarios: { + y: { + a.x + } +} +`, + boardPath: []string{"y"}, + key: `a`, + + exp: `{ + "a.x": "x 2" +}`, + }, + { + name: "layers-parent", + text: `x + +layers: { + y: { + a.x + } +} +`, + boardPath: []string{"y"}, + key: `a`, + + exp: `{ + "a.x": "x" }`, }, } @@ -8013,7 +8063,7 @@ Square t.Fatal(err) } - deltas, err := d2oracle.DeleteIDDeltas(g, tc.key) + deltas, err := d2oracle.DeleteIDDeltas(g, tc.boardPath, tc.key) if tc.expErr != "" { if err == nil { t.Fatalf("expected error with: %q", tc.expErr)