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

format: move layers, scenarios and steps to bottom of scope. #1424

Merged
1 change: 1 addition & 0 deletions ci/release/changelogs/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Display version on CLI help invocation [#1400](https://github.com/terrastruct/d2/pull/1400)
- Improved readability of connection labels when they overlap another connection. [#447](https://github.com/terrastruct/d2/pull/447)
- Error message when `shape` is given a composite [#1415](https://github.com/terrastruct/d2/pull/1415)
- The autoformatter moves board declarations to the bottom of its scope. [#1424](https://github.com/terrastruct/d2/pull/1424)

#### Bugfixes ⛑️

Expand Down
12 changes: 12 additions & 0 deletions d2ast/d2ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,18 @@ func (mb MapNodeBox) Unbox() MapNode {
}
}

func (mb MapNodeBox) IsBoardNode() bool {
if mb.MapKey == nil || mb.MapKey.Key == nil || len(mb.MapKey.Key.Path) != 1 {
return false
}
switch mb.MapKey.Key.Path[0].Unbox().ScalarString() {
case "layers", "scenarios", "steps":
return true
default:
return false
}
}

// ArrayNodeBox is used to box ArrayNode for JSON persistence.
type ArrayNodeBox struct {
Comment *Comment `json:"comment,omitempty"`
Expand Down
36 changes: 36 additions & 0 deletions d2format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,27 @@ func (p *printer) _map(m *d2ast.Map) {
}
}

layerNodes := []d2ast.MapNodeBox{}
scenarioNodes := []d2ast.MapNodeBox{}
stepNodes := []d2ast.MapNodeBox{}

prev := d2ast.Node(m)
for i := 0; i < len(m.Nodes); i++ {
nb := m.Nodes[i]
n := nb.Unbox()
// extract out layer, scenario, and step nodes and skip
if nb.IsBoardNode() {
switch nb.MapKey.Key.Path[0].Unbox().ScalarString() {
case "layers":
layerNodes = append(layerNodes, nb)
case "scenarios":
scenarioNodes = append(scenarioNodes, nb)
case "steps":
stepNodes = append(stepNodes, nb)
}
prev = n
continue
}

// Handle inline comments.
if i > 0 && (nb.Comment != nil || nb.BlockComment != nil) {
Expand Down Expand Up @@ -306,6 +323,25 @@ func (p *printer) _map(m *d2ast.Map) {
prev = n
}

boards := []d2ast.MapNodeBox{}
boards = append(boards, layerNodes...)
boards = append(boards, scenarioNodes...)
boards = append(boards, stepNodes...)

// draw board nodes
for i := 0; i < len(boards); i++ {
n := boards[i].Unbox()
// if this board is the very first line of the file, don't add an extra indent
if n.GetRange().Start.Line != 0 {
p.newline()
}
if len(m.Nodes) > len(boards) {
p.newline()
}
p.node(n)
prev = n
}

if !m.IsFileMap() {
if !m.Range.OneLine() {
p.deindent()
Expand Down
143 changes: 141 additions & 2 deletions d2format/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ meow
representation: {type: jsonb}
diagram: int {constraint: foreign_key}
}

meow <- diagrams.id

steps: {
shape: sql_table
id: {type: int; constraint: primary_key}
representation: {type: jsonb}
diagram: int {constraint: foreign_key}
}
meow <- diagrams.id
}

D2 AST Parser: {
Expand Down Expand Up @@ -657,6 +657,145 @@ x: @../file
x: @"x/../file"
`,
exp: `x: @file
`,
},
{
name: "layers_scenarios_steps_bottom_simple",
in: `layers: {
b: {
e
scenarios: {
p: {
x
}
}
}
}
`,
exp: `layers: {
b: {
e

scenarios: {
p: {
x
}
}
}
}
`,
},
{
name: "layers_scenarios_steps_bottom_complex",
in: `a

scenarios: {



scenario-1: {
steps: {
step-1: {
Test
}
step-2
}
non-step
}
}

layers: {
Test super nested: {
base-layer
layers: {
layers: {
grand-child-layer: {
grand-child-board
}
}
layer-board
}
last-layer
}
}
b
steps: {
1: {
step-1-content
}
}


scenarios: {
scenario-2: {
scenario-2-content
}
}

c
d

only-layers: {
layers: {
X
Y
}
}
`,
exp: `a
b

c
d

only-layers: {
layers: {
X
Y
}
}

layers: {
Test super nested: {
base-layer
last-layer

layers: {
layer-board

layers: {
grand-child-layer: {
grand-child-board
}
}
}
}
}

scenarios: {
scenario-1: {
non-step

steps: {
step-1: {
Test
}
step-2
}
}
}

scenarios: {
scenario-2: {
scenario-2-content
}
}

steps: {
1: {
step-1-content
}
}
`,
},
}
Expand Down