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

Added links to modules from mermaid #642

Merged
merged 3 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,27 @@ These tests produce a rich execution report, [for example](https://mastercard.gi
```mermaid
graph TB
subgraph com.mastercard.test.flow
api
assert-core
assert-filter
assert-junit4
assert-junit5
builder
coppice
duct
message-core
message-http
message-json
message-sql
message-text
message-web
message-xml
model
report-core
report-ng
validation-core
validation-junit4
validation-junit5
api[<a href='https://github.com/Mastercard/flow/tree/main/api'>api</a>]
assert-core[<a href='https://github.com/Mastercard/flow/tree/main/assert/assert-core'>assert-core</a>]
assert-filter[<a href='https://github.com/Mastercard/flow/tree/main/assert/assert-filter'>assert-filter</a>]
assert-junit4[<a href='https://github.com/Mastercard/flow/tree/main/assert/assert-junit4'>assert-junit4</a>]
assert-junit5[<a href='https://github.com/Mastercard/flow/tree/main/assert/assert-junit5'>assert-junit5</a>]
builder[<a href='https://github.com/Mastercard/flow/tree/main/builder'>builder</a>]
coppice[<a href='https://github.com/Mastercard/flow/tree/main/validation/coppice'>coppice</a>]
duct[<a href='https://github.com/Mastercard/flow/tree/main/report/duct'>duct</a>]
message-core[<a href='https://github.com/Mastercard/flow/tree/main/message/message-core'>message-core</a>]
message-http[<a href='https://github.com/Mastercard/flow/tree/main/message/message-http'>message-http</a>]
message-json[<a href='https://github.com/Mastercard/flow/tree/main/message/message-json'>message-json</a>]
message-sql[<a href='https://github.com/Mastercard/flow/tree/main/message/message-sql'>message-sql</a>]
message-text[<a href='https://github.com/Mastercard/flow/tree/main/message/message-text'>message-text</a>]
message-web[<a href='https://github.com/Mastercard/flow/tree/main/message/message-web'>message-web</a>]
message-xml[<a href='https://github.com/Mastercard/flow/tree/main/message/message-xml'>message-xml</a>]
model[<a href='https://github.com/Mastercard/flow/tree/main/model'>model</a>]
report-core[<a href='https://github.com/Mastercard/flow/tree/main/report/report-core'>report-core</a>]
report-ng[<a href='https://github.com/Mastercard/flow/tree/main/report/report-ng'>report-ng</a>]
validation-core[<a href='https://github.com/Mastercard/flow/tree/main/validation/validation-core'>validation-core</a>]
validation-junit4[<a href='https://github.com/Mastercard/flow/tree/main/validation/validation-junit4'>validation-junit4</a>]
validation-junit5[<a href='https://github.com/Mastercard/flow/tree/main/validation/validation-junit5'>validation-junit5</a>]
end
api --> message-core
api --> builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toSet;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -66,7 +67,8 @@ class ModuleDiagramTest {
*/
@Test
void framework() throws Exception {
Util.insert( Paths.get( "../README.md" ),
Path path = Paths.get( "../README.md" );
Util.insert( path,
"<!-- start_module_diagram:framework -->",
s -> diagram( "TB", l -> l.isTo( "com.mastercard.test.flow" ), s ),
"<!-- end_module_diagram -->" );
Expand All @@ -79,13 +81,15 @@ void framework() throws Exception {
*/
@Test
void example() throws Exception {
Util.insert( Paths.get( "../example/README.md" ),
Path path = Paths.get( "../example/README.md" );
Util.insert( path,
"<!-- start_module_diagram:example -->",
s -> diagram( "LR", l -> l.isTo( "com.mastercard.test.flow.example" ), s ),
"<!-- end_module_diagram -->" );
}

private static String diagram( String orientation, Predicate<Link> inclusion, String existing ) {
private static String diagram( String orientation, Predicate<Link> inclusion,
String existing ) {

PomData root = new PomData( null, Paths.get( "../pom.xml" ) );

Expand Down Expand Up @@ -120,32 +124,37 @@ private static String diagram( String orientation, Predicate<Link> inclusion, St
// remove links that don't fit in the requested diagram
links.values().forEach( ll -> ll.removeIf( l -> !inclusion.test( l ) ) );

// remove artifacts with no dependencies (e.g.: parent poms
groups.values().forEach( arts -> arts
.removeIf( pd -> !links.values().stream()
.map( ll -> ll.stream()
.filter( l -> l.involves( pd ) )
.findAny() )
.filter( Optional::isPresent )
.map( Optional::get )
.findAny().isPresent() ) );
groups.values().removeIf( Set::isEmpty );

Set<String> existingModules = extractModules( existing );
Set<String> desiredModules = groups.values().stream()
.flatMap( Set::stream )
.map( pd -> moduleLink( root.dirPath(), pd ) )
.collect( toCollection( TreeSet::new ) );
Set<String> existingLinks = extractLinks( existing );
Set<String> desiredLinks = links.values().stream()
.flatMap( List::stream )
.map( Link::toString )
.collect( toCollection( TreeSet::new ) );
if( existingLinks.equals( desiredLinks ) ) {
// The existing diagram has all the links we want to show, so let's leave it as
// it is
if( existingModules.equals( desiredModules ) && existingLinks.equals( desiredLinks ) ) {
// The existing diagram has all the modules and links we want to show, so let's
// leave it as it is
return existing;
// This allows us to make manual edits for reasons of layout while still
// ensuring the dependency structure is correct
}

// The existing diagram is not accurate, so overwrite it with one that is

// remove artifacts with no dependencies (e.g.: parent poms
groups.values().forEach( arts -> arts
.removeIf( pd -> !links.values().stream()
.map( ll -> ll.stream()
.filter( l -> l.involves( pd ) )
.findAny() )
.filter( Optional::isPresent )
.map( Optional::get )
.findAny().isPresent() ) );
groups.values().removeIf( Set::isEmpty );

StringBuilder mermaid = new StringBuilder( "```mermaid\ngraph " )
.append( orientation )
.append( "\n" );
Expand All @@ -154,7 +163,8 @@ private static String diagram( String orientation, Predicate<Link> inclusion, St
mermaid.append( " subgraph " ).append( groupId ).append( "\n" );
pomdatas.stream()
.sorted( comparing( PomData::artifactId ) )
.forEach( pd -> mermaid.append( " " ).append( pd.artifactId() ).append( "\n" ) );
.forEach( pd -> mermaid
.append( " " ).append( moduleLink( root.dirPath(), pd ) ).append( "\n" ) );
mermaid.append( " end\n" );
} );

Expand All @@ -165,6 +175,22 @@ private static String diagram( String orientation, Predicate<Link> inclusion, St
return mermaid.toString();
}

private static final String moduleLink( Path root, PomData pom ) {
return String.format( "%s[<a href='https://github.com/Mastercard/flow/tree/main/%s'>%s</a>]",
pom.artifactId(),
root.relativize( pom.dirPath() ).toString().replace( '\\', '/' ),
pom.artifactId() );
}

private static final Set<String> extractModules( String mermaid ) {
Set<String> modules = new TreeSet<>();
Matcher m = Pattern.compile( "\\S+\\[<a href='\\S+'>\\S+</a>\\]" ).matcher( mermaid );
while( m.find() ) {
modules.add( m.group() );
}
return modules;
}

private static final Set<String> extractLinks( String mermaid ) {
Set<String> links = new TreeSet<>();
Matcher m = Pattern.compile( "\\S+ -\\.?-> \\S+" ).matcher( mermaid );
Expand Down
45 changes: 22 additions & 23 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,39 +67,38 @@ graph TD
<!-- start_module_diagram:example -->

```mermaid

graph LR
subgraph core
builder
model
builder[<a href='https://github.com/Mastercard/flow/tree/main/builder'>builder</a>]
model[<a href='https://github.com/Mastercard/flow/tree/main/model'>model</a>]
end
subgraph message
message-http
message-json
message-sql
message-text
message-web
message-http[<a href='https://github.com/Mastercard/flow/tree/main/message/message-http'>message-http</a>]
message-json[<a href='https://github.com/Mastercard/flow/tree/main/message/message-json'>message-json</a>]
message-sql[<a href='https://github.com/Mastercard/flow/tree/main/message/message-sql'>message-sql</a>]
message-text[<a href='https://github.com/Mastercard/flow/tree/main/message/message-text'>message-text</a>]
message-web[<a href='https://github.com/Mastercard/flow/tree/main/message/message-web'>message-web</a>]
end
subgraph validation
validation-junit5
coppice
validation-junit5[<a href='https://github.com/Mastercard/flow/tree/main/validation/validation-junit5'>validation-junit5</a>]
coppice[<a href='https://github.com/Mastercard/flow/tree/main/validation/coppice'>coppice</a>]
end
subgraph assert
assert-junit5
duct
assert-junit5[<a href='https://github.com/Mastercard/flow/tree/main/assert/assert-junit5'>assert-junit5</a>]
duct[<a href='https://github.com/Mastercard/flow/tree/main/report/duct'>duct</a>]
end
subgraph example
app-api
app-assert
app-core
app-framework
app-histogram
app-itest
app-model
app-queue
app-store
app-ui
app-web-ui
app-api[<a href='https://github.com/Mastercard/flow/tree/main/example/app-api'>app-api</a>]
app-assert[<a href='https://github.com/Mastercard/flow/tree/main/example/app-assert'>app-assert</a>]
app-core[<a href='https://github.com/Mastercard/flow/tree/main/example/app-core'>app-core</a>]
app-framework[<a href='https://github.com/Mastercard/flow/tree/main/example/app-framework'>app-framework</a>]
app-histogram[<a href='https://github.com/Mastercard/flow/tree/main/example/app-histogram'>app-histogram</a>]
app-itest[<a href='https://github.com/Mastercard/flow/tree/main/example/app-itest'>app-itest</a>]
app-model[<a href='https://github.com/Mastercard/flow/tree/main/example/app-model'>app-model</a>]
app-queue[<a href='https://github.com/Mastercard/flow/tree/main/example/app-queue'>app-queue</a>]
app-store[<a href='https://github.com/Mastercard/flow/tree/main/example/app-store'>app-store</a>]
app-ui[<a href='https://github.com/Mastercard/flow/tree/main/example/app-ui'>app-ui</a>]
app-web-ui[<a href='https://github.com/Mastercard/flow/tree/main/example/app-web-ui'>app-web-ui</a>]
end
app-api --> app-web-ui
app-api --> app-ui
Expand Down