Description
The official Structurizr DSL reference syntax for containers and components is:
container <name> [description] [technology] [tags]
component <name> [description] [technology] [tags]
Though to be more precise, that is slightly ambiguous, and most Structurizr tooling interpret it as:
container <name> [description [technology [tags]]]
component <name> [description [technology [tags]]]
Which is to say, tags
is the most-optional, followed-by technology
, then description
. This can be seen in ContainerParser::parse() and ComponentParser::parse().
However, when C4PlantUMLExporter::writeElement() generates C4-PlantUML Container(...)
and Component(...)
procedure calls, if technology
is not set, then description
ends up in the technology
argument's positional, and this description
gets rendered as a technology
.
Steps to reproduce
- Consider this example DSL:
workspace {
model {
enterprise "Demo" {
demoSystem = softwaresystem "demoSystem" {
demoContainer = container "demoContainer" "desc" "tech" "tags" {
component "component1" "component1 description" "component1 technology" "component1 tag1,tsg2"
component "component2" "component2 description" "component2 technology"
component "component3" "component3 description"
component "component4"
}
}
}
}
views {
component demoContainer {
include *
}
}
}
-
Render that via Structurizr, and C4-PlantUML, eg via https://structurizr.com/dsl
-
Observe that only component3
, and only in the C4-PlantUML rendering, the component3 description
text appears where the technology text should. See screenshots in the next section.
Screenshot
Here's a sample show how it is correct for the Structurizr output, for all four components:
![image](https://private-user-images.githubusercontent.com/5195222/246327857-f160f468-17e9-4c6e-b327-5f73c6d6c3fd.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjE0MzQ4NzksIm5iZiI6MTcyMTQzNDU3OSwicGF0aCI6Ii81MTk1MjIyLzI0NjMyNzg1Ny1mMTYwZjQ2OC0xN2U5LTRjNmUtYjMyNy01ZjczYzZkNmMzZmQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDcyMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA3MjBUMDAxNjE5WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NjA2MTdhZTU3ZDEwNDVmMDgzODUwNWUxZGZkMGYyOThhYWY4NDM0M2NmNThkYzE1NmQwNTJjNDk1N2ExNjNmMyZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.dyRMDph81vkHhO4HUj04Obs-BMtzbqh2mhj4h-JNpSs)
And here, you can see how for the C4-PlantUML output, component3
's description appears in the technology position:
![image](https://private-user-images.githubusercontent.com/5195222/246328096-0ec87ace-29ee-4789-b2fe-915b1c9c6b48.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjE0MzQ4NzksIm5iZiI6MTcyMTQzNDU3OSwicGF0aCI6Ii81MTk1MjIyLzI0NjMyODA5Ni0wZWM4N2FjZS0yOWVlLTQ3ODktYjJmZS05MTViMWM5YzZiNDgucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDcyMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA3MjBUMDAxNjE5WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9Y2M3OTg1NTYxYzM5ZjQxNDhmNjFkOGQ0NmM5NjM3ZGExNzJiMGU2MDE5YjEzYmQxNWQzNTBhYjdhZDk2MDAwNiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.ixxxMID7GSmAuF4KxfUjF7tayKPLWc1JpAl1FXpP2wk)
Code sample
See "Steps to reproduce" above.
Configuration
No response
Severity
Major
Priority
Low
Resolution
I'm willing to fix this myself and raise a PR
More information
Looking at the generated C4-PlantUML (for the above sample DSL), it includes:
Container_Boundary("demoSystem.demoContainer_boundary", "demoContainer", $tags="") {
Component(demoSystem.demoContainer.component1, "component1", "component1 technology", "component1 description", $tags="")
Component(demoSystem.demoContainer.component2, "component2", "component2 technology", "component2 description", $tags="")
Component(demoSystem.demoContainer.component3, "component3", "component3 description", $tags="")
Component(demoSystem.demoContainer.component4, "component4", "", $tags="")
}
You can see that for component3
, then description has shifted into the technology position.
For convenience, here are links to the relevant current C4-PlantUML procedure definitions:
And here's the code in C4PlantUMLExporter.java
that writes (sometimes incorrectly) those procedure calls (ie this is where I'd say the fixes should go):
Note, the components fix will likely conflict with my existing open PR #60, so I would strongly recommend merging that PR (assuming you're happy with it) before fixing this. Or branch off my PR.
I'd be happy to have a go at fixing this bug too. Just not sure when I'll have time to get to it.
Cheers!