structurizr / cli

A command line utility for Structurizr.
https://docs.structurizr.com/cli
Apache License 2.0
492 stars 75 forks source link

"Unexpected tokens" error at validating nested groups example from the DSL Cookbook #110

Closed vbakokr closed 1 year ago

vbakokr commented 1 year ago

I am trying out the examples shown in DSL Cookbook, nested groups (https://github.com/structurizr/dsl/tree/master/docs/cookbook/groups)

System is a Debian 11 Linux box (not a virtual machine). I have installed the Structurizr CLI command line utility as described in the repository (https://github.com/structurizr/cli).

I am getting an error message with structurizr.sh version 1.28.0 and 1.27.0 executing the following command:

$ structurizr.sh validate -w workspace.dsl

The content of the workspace.dsl I have copied over the nested groups example from the DSL Cookbook.

workspace.dsl:

workspace {

    model {
        properties {
            "structurizr.groupSeparator" "/"
        }

        group "Company 1" {
            group "Department 1" {
                a = softwareSystem "A"
            }

            group "Department 2" {
                b = softwareSystem "B"
            }
        }

        a -> b
    }

    views {
        systemLandscape {
            include *
            autolayout lr
        }

        styles {
            element "Group:Company 1/Department 1" {
                color #ff0000
            }
            element "Group:Company 1/Department 2" {
                color #0000ff
            }
        }
    }

}

The issued error message is bellow:

$ structurizr.sh validate -w workspace.dsl
Validating workspace at workspace.dsl
com.structurizr.dsl.StructurizrDslParserException: Unexpected tokens (expected: enterprise, group, person, softwareSystem, deploymentEnvironment, element, ->) at line 4: properties {
    at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:832)
    at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:127)
    at com.structurizr.cli.AbstractCommand.loadWorkspace(AbstractCommand.java:65)
    at com.structurizr.cli.ValidateCommand.run(ValidateCommand.java:42)
    at com.structurizr.cli.StructurizrCliApplication.run(StructurizrCliApplication.java:77)
    at com.structurizr.cli.StructurizrCliApplication.main(StructurizrCliApplication.java:112)

Commenting out the "properties" entry and repeating the validation, I have got a similar error message:

workspace.dsl:

workspace {

    model {
//        properties {
//            "structurizr.groupSeparator" "/"
//        }

        group "Company 1" {
            group "Department 1" {
                a = softwareSystem "A"
            }

            group "Department 2" {
                b = softwareSystem "B"
            }
        }

        a -> b
    }

    views {
        systemLandscape {
            include *
            autolayout lr
        }

        styles {
            element "Group:Company 1/Department 1" {
                color #ff0000
            }
            element "Group:Company 1/Department 2" {
                color #0000ff
            }
        }
    }

}

Error message:

$ structurizr.sh validate -w workspace.dsl
Validating workspace at workspace.dsl
com.structurizr.dsl.StructurizrDslParserException: Unexpected tokens (expected: enterprise, group, person, softwareSystem, deploymentEnvironment, element, ->) at line 9: group "Department 1" {
    at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:832)
    at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:127)
    at com.structurizr.cli.AbstractCommand.loadWorkspace(AbstractCommand.java:65)
    at com.structurizr.cli.ValidateCommand.run(ValidateCommand.java:42)
    at com.structurizr.cli.StructurizrCliApplication.run(StructurizrCliApplication.java:77)
    at com.structurizr.cli.StructurizrCliApplication.main(StructurizrCliApplication.java:112)

Thank you and regards.

simonbrowndotje commented 1 year ago

Nested groups isn't supported by the current version of the CLI, but making a new release is on my todo list for next week. You can build from source though with the following command:

./gradlew clean build getDeps buildZip
vbakokr commented 1 year ago

Thank you Mr. Brown. It worked. Regards

vbakokr commented 1 year ago

Regarding the new version 1.29.0 of the Structurizr CLI command line utility, I though have another issue. If I mix the nested groups with normal groups, after adding more than one normal group, the generated plantuml file ist incomplete/false.

The workspace file looks like bellow:

workspace {

    model {
        properties {
            "structurizr.groupSeparator" "/"
        }

        group "users" {
            user1 = person "User1"
            user2 = person "User2"
        }

        group "exteral users" {
            extuser1 = person "ExtUser1"
            extuser2 = person "ExtUser2"
        }

        group "Company 1" {
            group "Department 1" {
                a = softwareSystem "A"
            }

            group "Department 2" {
                b = softwareSystem "B"
            }
        }

        a -> b
    }

    views {
        systemLandscape {
            include *
            autolayout lr
        }

        styles {
            element "Group:Company 1/Department 1" {
                color #ff0000
            }
            element "Group:Company 1/Department 2" {
                color #0000ff
            }
        }
    }

}

The generated file (in this case the c4plantuml version, because is shorter):

structurizr.sh export -f plantuml/c4plantuml -w workspace.dsl

result:

@startuml
set separator none
title System Landscape

left to right direction

!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4.puml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

Boundary(group_1, "Company 1") {
    Boundary(group_2, "Department 1") {
      System(A, "A", "", $tags="")
    }

    Boundary(group_3, "Department 2") {
      System(B, "B", "", $tags="")
    }

}

Boundary(group_4, "exteral users") {
  Person(ExtUser1, "ExtUser1", "", $tags="")
  Person(ExtUser2, "ExtUser2", "", $tags="")
  Boundary(group_5, "users") {
    Person(User1, "User1", "", $tags="")
    Person(User2, "User2", "", $tags="")
  }

Rel_D(A, B, "", $tags="")

SHOW_LEGEND(true)
@enduml

The result has following problems:

The order in wich I define the normal groups does not have any influnce (before or after the nested groups).

Same happens if I generate plantulm/structurizr.

structurizr.sh export -f plantuml/structurizr -w workspace.dsl

Output:

@startuml
set separator none
title System Landscape

left to right direction

skinparam {
  shadowing false
  arrowFontSize 10
  defaultTextAlignment center
  wrapWidth 200
  maxMessageSize 100
}

hide stereotype

skinparam rectangle<<A>> {
  BackgroundColor #dddddd
  FontColor #000000
  BorderColor #9a9a9a
}
skinparam rectangle<<B>> {
  BackgroundColor #dddddd
  FontColor #000000
  BorderColor #9a9a9a
}
skinparam rectangle<<ExtUser1>> {
  BackgroundColor #dddddd
  FontColor #000000
  BorderColor #9a9a9a
}
skinparam rectangle<<ExtUser2>> {
  BackgroundColor #dddddd
  FontColor #000000
  BorderColor #9a9a9a
}
skinparam rectangle<<User1>> {
  BackgroundColor #dddddd
  FontColor #000000
  BorderColor #9a9a9a
}
skinparam rectangle<<User2>> {
  BackgroundColor #dddddd
  FontColor #000000
  BorderColor #9a9a9a
}

rectangle "Company 1" <<group1>> {
  skinparam RectangleBorderColor<<group1>> #cccccc
  skinparam RectangleFontColor<<group1>> #cccccc

    rectangle "Department 1" <<group2>> {
      skinparam RectangleBorderColor<<group2>> #ff0000
      skinparam RectangleFontColor<<group2>> #ff0000

      rectangle "==A\n<size:10>[Software System]</size>" <<A>> as A
    }

    rectangle "Department 2" <<group3>> {
      skinparam RectangleBorderColor<<group3>> #0000ff
      skinparam RectangleFontColor<<group3>> #0000ff

      rectangle "==B\n<size:10>[Software System]</size>" <<B>> as B
    }

}

rectangle "exteral users" <<group4>> {
  skinparam RectangleBorderColor<<group4>> #cccccc
  skinparam RectangleFontColor<<group4>> #cccccc

  rectangle "==ExtUser1\n<size:10>[Person]</size>" <<ExtUser1>> as ExtUser1
  rectangle "==ExtUser2\n<size:10>[Person]</size>" <<ExtUser2>> as ExtUser2
  rectangle "users" <<group5>> {
    skinparam RectangleBorderColor<<group5>> #cccccc
    skinparam RectangleFontColor<<group5>> #cccccc

    rectangle "==User1\n<size:10>[Person]</size>" <<User1>> as User1
    rectangle "==User2\n<size:10>[Person]</size>" <<User2>> as User2
  }

A .[#707070,thickness=2].> B : "<color:#707070>"
@enduml

Thank you.

vbakokr commented 1 year ago

Additional comment It seams, if the properties entry

        properties {
            "structurizr.groupSeparator" "/"
        }

is present, the issue describe above happens. As it would be that one must use the normal or the nested groups, but not mixed. Is this feature planned like this?

Thanks, Vasile

simonbrowndotje commented 1 year ago

There are a number of problems with structurizr-export:1.12.x, which is why there has been no CLI release yet. I think most of these are resolved -> https://github.com/structurizr/export/blob/main/docs/changelog.md#1130-unreleased

You can build the export library from source and patch your CLI installation if you need this in a hurry.

simonbrowndotje commented 1 year ago

This is the result from the unreleased version of the structurizr-export library, which I think is as expected:

image

vbakokr commented 1 year ago

Hi Simon (may I address you like that?).

Your hint helped. I just tested the issue myself (after recompile). It works as expected.

Thank you very much.

Regards, Vasile

simonbrowndotje commented 1 year ago

v1.29.0 of the CLI is now available.