structurizr / dsl

Structurizr DSL
https://docs.structurizr.com/dsl
Apache License 2.0
1.41k stars 266 forks source link

Element with relationship breaks exports #147

Closed pcolby closed 2 years ago

pcolby commented 2 years ago

It seems that the use of an element with a relationship results in exports that are invalid.

Here's the simplest example I could reduce it to:

workspace {
  model { 
    enterprise "EnterpriseName" {
      softwareSystem = softwaresystem "SoftwareSystemName"
    }
    element "ElementName" {
      this -> softwareSystem
    }
  }
  views {
    systemlandscape SystemLandscape {
      include *
    }
  }
}

The above example works perfectly in https://structurizr.com/dsl

However, using the structurizr-cli version:

structurizr --version
Structurizr CLI v1.19.0
Structurizr DSL v1.19.1

When I run:

structurizr export -workspace ./example.dsl -format dsl --output tmp

The resulting DSL is:

workspace "Name" "Description" {

    !impliedRelationships "false" 
    !identifiers "hierarchical" 

    model {
        enterprise "EnterpriseName" {
            SoftwareSystemName = softwareSystem "SoftwareSystemName" 
        }
        2 -> SoftwareSystemName 
    }

    views {
        systemLandscape "SystemLandscape" {
            include SoftwareSystemName 
            include 2 
        }

    }

}

Which then results in errors (in other structurizr-cli calls, and https://structurizr.com/dsl) like:

The source element "2" does not exist at line 10: 2 -> SoftwareSystemName

or

java.lang.RuntimeException: The source element "2" does not exist
        at com.structurizr.dsl.ExplicitRelationshipParser.parse(ExplicitRelationshipParser.java:37)
        at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:204)
        at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:124)
        at com.structurizr.cli.ExportCommand.run(ExportCommand.java:112)
        at com.structurizr.cli.StructurizrCliApplication.run(StructurizrCliApplication.java:36)
        at com.structurizr.cli.StructurizrCliApplication.main(StructurizrCliApplication.java:81)
com.structurizr.dsl.StructurizrDslParserException: The source element "2" does not exist at line 10: 2 -> SoftwareSystemName
        at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:757)
        at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:124)
        at com.structurizr.cli.ExportCommand.run(ExportCommand.java:112)
        at com.structurizr.cli.StructurizrCliApplication.run(StructurizrCliApplication.java:36)
        at com.structurizr.cli.StructurizrCliApplication.main(StructurizrCliApplication.java:81)

But everything works well (in much more complicated models) if I just comment out the element's relationship, like:

    element "ElementName" {
      # this -> softwareSystem
    }

Let me know if you need any more info.

Thanks.

pcolby commented 2 years ago

Actually, here's a very slightly simpler version:

Input (valid):

workspace {
  model { 
    softwareSystem = softwaresystem "SoftwareSystemName"
    element "ElementName" {
      this -> softwareSystem
    }  
  }    
  views {
    systemlandscape SystemLandscape {
      include *
    }  
  }  
}

Output (invalid):

workspace "Name" "Description" {

    !impliedRelationships "false" 
    !identifiers "hierarchical" 

    model {
        SoftwareSystemName = softwareSystem "SoftwareSystemName" 
        2 -> SoftwareSystemName 
    }

    views {
        systemLandscape "SystemLandscape" {
            include SoftwareSystemName 
            include 2 
        }

    }

}
simonbrowndotje commented 2 years ago

The DSL export was designed to help people migrate from the Structurizr cloud service/on-premises browser-based workspace editor (that was discontinued last year) to the DSL. The workspace editor didn't support arbitrary elements, so this facility wasn't built into the DSL exporter.

It can certainly be added, but I'm curious to know what your use case for the DSL export is.

pcolby commented 2 years ago

Thanks @simonbrowndotje, I have a few use cases, but two where I want structurizr-cli to read DSL are:

  1. to combine multiple files into a single DSL via the !include keyword, so I can then pass the combined DSL to services such as Kroki; and
  2. to convert a DSL to JSON, so I can reliably extract the list of views via jq, instead of having to pass the DSL directly (again, so I can pass the information to services such as Kroki).

Of course, I can do both things other ways, with a little bit of scripting. But as strucutirz-cli already knows how to parse the Structurizr DSL natively, then it makes sense to use it 😄

PS - I meant to create this issue in the structurizr/cli repo, not this DSL repo. Sorry 😕

Thanks.

simonbrowndotje commented 2 years ago
  1. to combine multiple files into a single DSL via the !include keyword, so I can then pass the combined DSL to services such as Kroki; and

I'd recommend writing a script to inline the !include statements. The DSL export is a like decompiling Java code from bytecode, where the decompiled Java code doesn't match the original source. In this case, the DSL export is going to be much more verbose than the DSL source. In short, I'd recommend not using the DSL export.

PS - I meant to create this issue in the structurizr/cli repo, not this DSL repo. Sorry 😕

No problem. I transferred the issue to the DSL repo, since the issue is about the DSL export feature, which is implemented in this repo.

simonbrowndotje commented 2 years ago

I've just looked at the new version of the CLI that I have locally (the changes haven't been pushed to GitHub yet because I need to release new versions of the structurizr-dsl and structurizr-export libraries to Maven Central first). When a workspace is created using the DSL (whether using Structurizr Lite, the CLI, or the browser-based DSL editor), the resulting (JSON) workspace includes a copy of the DSL that's been used to create the workspace ... it's a Base64 encoded string that you'll spot if you open up the JSON version of a workspace in a text editor. The new CLI has a feature that will allow you to extract/export that DSL, decode it, and save it to disk. So, with that in mind, you'll actually be able to do this with the new CLI:

./structurizr.sh export -workspace workspace.dsl -export dsl -output somedir

This will process the DSL, create the workspace, and export the DSL that was used to create that workspace ... with !include statements removed and replaced with the included content.

pcolby commented 2 years ago

Thanks excellent! Thanks @simonbrowndotje, I shall await the new release 😄

simonbrowndotje commented 2 years ago

A new CLI release is now available.