structurizr / cli

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

Add a merge option to copy layouts from an existing workspace #142

Closed simonwfarrow closed 11 months ago

simonbrowndotje commented 11 months ago

What's your use case for this?

simonwfarrow commented 11 months ago

I am generating a view using autoLayout in the DSL via the CLI. I load the output json into the ui and allow edits. When I update the dsl file I want to retain the modifications to the layout made in the ui

simonbrowndotje commented 11 months ago

You don't say which UI you're using, but Structurizr Lite does this for you automatically ... as does the push command if you're using the cloud service/on-premises installation.

simonwfarrow commented 11 months ago

Sorry, using the structurizr ui directly in a custom web page

simonbrowndotje commented 11 months ago

No problem. I think this deserves a separate command, to avoid confusion ... I've lost count of the number of people who have complained that their PlantUML diagrams are not respecting the layout created by the Structurizr UI! 😂

I've added a merge command, which you can test by cloning the repo and building from source:

./structurizr.sh merge -workspace workspace.dsl -layout workspace.json -output merged.json

Let me know if this works for your use case.

simonwfarrow commented 11 months ago

I feel your pain 😄

Merge command sounds great - I've built and run the code, it works ok until I put autoLayout in the DSL file. My use case here is that initially I want an autoLayout to be applied, I then edit the initial layout to tweak it a bit and save that adjustment as a json file. I then update my DSL to add a new system to the model, I want to copy the layout for existing elements from the tweaked layout file and apply autoLayout for the new elements.

In the PR, I had to nullify the autolayout applied to the view so this following condition would pass and copy over layouts:

public void copyLayoutInformationFrom(ViewSet source) {
        for (CustomView view : customViews) {
            if (view.getAutomaticLayout() == null && view.getMergeFromRemote() == true) {
simonbrowndotje commented 11 months ago

it works ok until I put autoLayout in the DSL file

Yes, the assumption is that if automatic layout is configured for the view, the diagram viewer should initiate automatic layout when the view is rendered. If you're trying to use a different workflow, I'd probably recommend building your own command line app with this custom logic. You might also look into integrating the structurizr-graphviz library, which will provide a way to trigger automatic layout before saving to a JSON file.

simonwfarrow commented 11 months ago

Ah ok - I am using groozy in the DSL to apply graphviz layout:

graphviz = new com.structurizr.graphviz.GraphvizAutomaticLayout();
graphviz.setRankSeparation(300);
graphviz.setNodeSeparation(300);
graphviz.setMargin(400);
graphviz.apply(view)

I might have mis-understood, can I drop the autoLayout line from the DSL if calling graphviz to do the layout?

simonbrowndotje commented 11 months ago

can I drop the autoLayout line from the DSL if calling graphviz to do the layout?

Yes - autolayout in the DSL is an instruction for the renderer to initiate automatic layout, but it's unnecessary since you're running Graphviz from the CLI.

simonwfarrow commented 11 months ago

Ok thanks. If using autoLayout, does the structurizr ui require a call back to the server to run graphviz to get the layout, or does it calculate the layout in the browser?

I am running solely client/browser code and it seems I do need to create the layout via the CLI to feed the UI to enable auto layout.

If so, it does sound like a different workflow and command line app as you suggest.

simonbrowndotje commented 11 months ago

Ok thanks. If using autoLayout, does the structurizr ui require a call back to the server to run graphviz to get the layout, or does it calculate the layout in the browser?

It depends on the value of the implementation property (Graphviz or Dagre). That said, only Structurizr Lite/on-premises/cloud supports the Graphviz implementation, because they all have a server-side component. With the standalone UI that you're using, you're restricted to using the Javascript Dagre implementation.

simonwfarrow commented 11 months ago

Got it. Thank you. I'll try out the Dagre layout to see if that suits.

simonwfarrow commented 11 months ago

This worked by setting the following on the view in the DSL file:

!script groovy {
  view.enableAutomaticLayout();
}

If I just added autoLayout it defaults to Graphviz.

I could then run the following command to auto layout in the browser:

structurizr.diagram.runDagre(...)

So seems I have options of either using Graphviz and CLI to layout before loading to the UI, or set layout to Dagre and run the layout command once loaded into the UI.

The original use case still remains therefore to apply user edits to the layout post auto layout. And for this I think your suggestion is to build a separate workflow to manage merging the layouts.

Thanks for you help