From 39773defd1b2164640cbd4f576777d8e0ed9aaef Mon Sep 17 00:00:00 2001 From: Josef Raska <6277721+jraska@users.noreply.github.com> Date: Tue, 18 Jan 2022 16:48:34 +0100 Subject: [PATCH] Add module alias to Graphviz export (#159) --- .../com/jraska/module/graph/GraphvizWriter.kt | 11 ++-- .../graph/assertion/DependencyToAssert.kt | 37 ------------ .../graph/assertion/ModuleDependency.kt | 56 +++++++++++++++++++ .../assertion/ModuleGraphAssertionsPlugin.kt | 1 + .../graph/assertion/OnlyAllowedAssert.kt | 6 +- .../assertion/RestrictedDependenciesAssert.kt | 4 +- .../tasks/GenerateModulesGraphTask.kt | 5 +- .../jraska/module/graph/GraphvizWriterTest.kt | 43 ++++++++++---- ...oAssertTest.kt => ModuleDependencyTest.kt} | 8 +-- 9 files changed, 110 insertions(+), 61 deletions(-) delete mode 100644 plugin/src/main/kotlin/com/jraska/module/graph/assertion/DependencyToAssert.kt create mode 100644 plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleDependency.kt rename plugin/src/test/kotlin/com/jraska/module/graph/assertion/{DependencyToAssertTest.kt => ModuleDependencyTest.kt} (56%) diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/GraphvizWriter.kt b/plugin/src/main/kotlin/com/jraska/module/graph/GraphvizWriter.kt index cfa22af..316effe 100644 --- a/plugin/src/main/kotlin/com/jraska/module/graph/GraphvizWriter.kt +++ b/plugin/src/main/kotlin/com/jraska/module/graph/GraphvizWriter.kt @@ -1,7 +1,9 @@ package com.jraska.module.graph +import com.jraska.module.graph.assertion.mapAlias + object GraphvizWriter { - fun toGraphviz(dependencyGraph: DependencyGraph): String { + fun toGraphviz(dependencyGraph: DependencyGraph, aliases: Map = emptyMap()): String { val longestPathConnections = dependencyGraph.longestPath() .nodeNames.zipWithNext() @@ -18,12 +20,13 @@ object GraphvizWriter { } dependencyPairs + .map { aliases.mapAlias(it) } .forEach { connection -> - stringBuilder.append("\"${connection.first}\"") + stringBuilder.append("\"${connection.fromDocText()}\"") .append(" -> ") - .append("\"${connection.second}\"") + .append("\"${connection.toDocText()}\"") - if (longestPathConnections.contains(connection)) { + if (longestPathConnections.contains(connection.dependencyPair)) { stringBuilder.append(" [color=red style=bold]") } diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/DependencyToAssert.kt b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/DependencyToAssert.kt deleted file mode 100644 index bea44dc..0000000 --- a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/DependencyToAssert.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.jraska.module.graph.assertion - -class DependencyToAssert( - private val dependencyPair: Pair, - private val fromAlias: String?, - private val toAlias: String? -) { - fun pairToAssert(): Pair { - if (fromAlias != null || toAlias != null) { - return (fromAlias ?: dependencyPair.first) to (toAlias ?: dependencyPair.second) - } else { - return dependencyPair - } - } - - fun displayText(): String { - val stringBuilder = StringBuilder() - - if (fromAlias != null) { - stringBuilder.append("\"$fromAlias\"") - stringBuilder.append("('${dependencyPair.first}')") - } else { - stringBuilder.append("'${dependencyPair.first}'") - } - - stringBuilder.append(" -> ") - - if (toAlias != null) { - stringBuilder.append("\"$toAlias\"") - stringBuilder.append("('${dependencyPair.second}')") - } else { - stringBuilder.append("'${dependencyPair.second}'") - } - - return stringBuilder.toString() - } -} diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleDependency.kt b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleDependency.kt new file mode 100644 index 0000000..e7916b5 --- /dev/null +++ b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleDependency.kt @@ -0,0 +1,56 @@ +package com.jraska.module.graph.assertion + +class ModuleDependency( + val dependencyPair: Pair, + private val fromAlias: String?, + private val toAlias: String? +) { + private val from get() = dependencyPair.first + private val to get() = dependencyPair.second + + fun pairToAssert(): Pair { + if (fromAlias != null || toAlias != null) { + return (fromAlias ?: from) to (toAlias ?: to) + } else { + return dependencyPair + } + } + + fun assertDisplayText(): String { + val stringBuilder = StringBuilder() + + if (fromAlias != null) { + stringBuilder.append("\"$fromAlias\"") + stringBuilder.append("('${from}')") + } else { + stringBuilder.append("'${from}'") + } + + stringBuilder.append(" -> ") + + if (toAlias != null) { + stringBuilder.append("\"$toAlias\"") + stringBuilder.append("('${to}')") + } else { + stringBuilder.append("'${to}'") + } + + return stringBuilder.toString() + } + + fun fromDocText(): String { + return if (fromAlias != null) { + "$from('$fromAlias')" + } else { + from + } + } + + fun toDocText() : String { + return if (toAlias != null) { + "$to('$toAlias')" + } else { + to + } + } +} diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleGraphAssertionsPlugin.kt b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleGraphAssertionsPlugin.kt index c09b644..5d3d286 100644 --- a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleGraphAssertionsPlugin.kt +++ b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/ModuleGraphAssertionsPlugin.kt @@ -63,6 +63,7 @@ class ModuleGraphAssertionsPlugin : Plugin { private fun Project.addModuleGraphGeneration(graphRules: GraphRulesExtension) { tasks.register(Tasks.GENERATE_GRAPHVIZ, GenerateModulesGraphTask::class.java) { it.configurationsToLook = graphRules.configurations + it.aliases = aliases } } diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/OnlyAllowedAssert.kt b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/OnlyAllowedAssert.kt index a039f9c..479d9e9 100644 --- a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/OnlyAllowedAssert.kt +++ b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/OnlyAllowedAssert.kt @@ -14,7 +14,7 @@ class OnlyAllowedAssert( val disallowedDependencies = dependencyGraph.dependencyPairs() .map { aliasMap.mapAlias(it) } .filterNot { dependency -> matchers.any { it.matches(dependency.pairToAssert()) } } - .map { it.displayText() } + .map { it.assertDisplayText() } if (disallowedDependencies.isNotEmpty()) { val allowedRules = allowedDependencies.joinToString(", ") { "'$it'" } @@ -23,9 +23,9 @@ class OnlyAllowedAssert( } } -fun Map.mapAlias(dependencyPair: Pair): DependencyToAssert { +fun Map.mapAlias(dependencyPair: Pair): ModuleDependency { val fromAlias = this[dependencyPair.first] val toAlias = this[dependencyPair.second] - return DependencyToAssert(dependencyPair, fromAlias, toAlias) + return ModuleDependency(dependencyPair, fromAlias, toAlias) } diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/RestrictedDependenciesAssert.kt b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/RestrictedDependenciesAssert.kt index 1dd4403..a0e8a88 100644 --- a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/RestrictedDependenciesAssert.kt +++ b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/RestrictedDependenciesAssert.kt @@ -24,10 +24,10 @@ class RestrictedDependenciesAssert( } } - private fun buildErrorMessage(failedDependencies: List>>): String { + private fun buildErrorMessage(failedDependencies: List>>): String { return failedDependencies.map { val violatedRules = it.second.map { "'$it'" }.joinToString(", ") - "Dependency '${it.first.displayText()} violates: $violatedRules" + "Dependency '${it.first.assertDisplayText()} violates: $violatedRules" }.joinToString("\n") } } diff --git a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/tasks/GenerateModulesGraphTask.kt b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/tasks/GenerateModulesGraphTask.kt index a625933..af1d900 100644 --- a/plugin/src/main/kotlin/com/jraska/module/graph/assertion/tasks/GenerateModulesGraphTask.kt +++ b/plugin/src/main/kotlin/com/jraska/module/graph/assertion/tasks/GenerateModulesGraphTask.kt @@ -14,11 +14,14 @@ open class GenerateModulesGraphTask : DefaultTask() { @Input lateinit var configurationsToLook: Set + @Input + lateinit var aliases: Map + @TaskAction fun run() { val dependencyGraph = project.createDependencyGraph(configurationsToLook) - val graphviz = GraphvizWriter.toGraphviz(dependencyGraph) + val graphviz = GraphvizWriter.toGraphviz(dependencyGraph, aliases) if (shouldOutputFile()) { getOutputFile().apply { diff --git a/plugin/src/test/kotlin/com/jraska/module/graph/GraphvizWriterTest.kt b/plugin/src/test/kotlin/com/jraska/module/graph/GraphvizWriterTest.kt index d538021..c52385f 100644 --- a/plugin/src/test/kotlin/com/jraska/module/graph/GraphvizWriterTest.kt +++ b/plugin/src/test/kotlin/com/jraska/module/graph/GraphvizWriterTest.kt @@ -4,16 +4,6 @@ import org.junit.Test class GraphvizWriterTest { - val EXPECTED_OUTPUT = """digraph G { -"app" -> "feature" [color=red style=bold] -"app" -> "feature-about" -"app" -> "lib" -"feature" -> "lib" [color=red style=bold] -"feature-about" -> "lib" -"feature-about" -> "core" -"lib" -> "core" [color=red style=bold] -}""" - @Test fun testPrintsProperly() { val graphvizText = GraphvizWriter.toGraphviz(testGraph()) @@ -21,6 +11,19 @@ class GraphvizWriterTest { assert(graphvizText == EXPECTED_OUTPUT) } + @Test + fun testPrintsProperlyWithAliases() { + val aliases = mapOf( + "app" to "App", + "lib" to "Api", + "feature-about" to "Implementation" + ) + + val graphvizText = GraphvizWriter.toGraphviz(testGraph(), aliases) + + assert(graphvizText == EXPECTED_OUTPUT_WITH_ALISASES) + } + private fun testGraph(): DependencyGraph { return DependencyGraph.create( "app" to "feature", @@ -33,3 +36,23 @@ class GraphvizWriterTest { ) } } + +private const val EXPECTED_OUTPUT = """digraph G { +"app" -> "feature" [color=red style=bold] +"app" -> "feature-about" +"app" -> "lib" +"feature" -> "lib" [color=red style=bold] +"feature-about" -> "lib" +"feature-about" -> "core" +"lib" -> "core" [color=red style=bold] +}""" + +private const val EXPECTED_OUTPUT_WITH_ALISASES = """digraph G { +"app('App')" -> "feature" [color=red style=bold] +"app('App')" -> "feature-about('Implementation')" +"app('App')" -> "lib('Api')" +"feature" -> "lib('Api')" [color=red style=bold] +"feature-about('Implementation')" -> "lib('Api')" +"feature-about('Implementation')" -> "core" +"lib('Api')" -> "core" [color=red style=bold] +}""" diff --git a/plugin/src/test/kotlin/com/jraska/module/graph/assertion/DependencyToAssertTest.kt b/plugin/src/test/kotlin/com/jraska/module/graph/assertion/ModuleDependencyTest.kt similarity index 56% rename from plugin/src/test/kotlin/com/jraska/module/graph/assertion/DependencyToAssertTest.kt rename to plugin/src/test/kotlin/com/jraska/module/graph/assertion/ModuleDependencyTest.kt index c6bab34..be33ac8 100644 --- a/plugin/src/test/kotlin/com/jraska/module/graph/assertion/DependencyToAssertTest.kt +++ b/plugin/src/test/kotlin/com/jraska/module/graph/assertion/ModuleDependencyTest.kt @@ -2,24 +2,24 @@ package com.jraska.module.graph.assertion import org.junit.Test -class DependencyToAssertTest { +class ModuleDependencyTest { @Test fun displayTextWorksWithAliases() { - val displayText = DependencyToAssert(":feature" to ":core-api", "Impl", "Api").displayText() + val displayText = ModuleDependency(":feature" to ":core-api", "Impl", "Api").assertDisplayText() assert(displayText == """"Impl"(':feature') -> "Api"(':core-api')""") } @Test fun displayTextWorksWithOneAlias() { - val displayText = DependencyToAssert(":feature" to ":core-api", null, "Api").displayText() + val displayText = ModuleDependency(":feature" to ":core-api", null, "Api").assertDisplayText() assert(displayText == """':feature' -> "Api"(':core-api')""") } @Test fun displayTextWorksWithNoAliases() { - val displayText = DependencyToAssert(":feature" to ":core-api", null, null).displayText() + val displayText = ModuleDependency(":feature" to ":core-api", null, null).assertDisplayText() assert(displayText == "':feature' -> ':core-api'") }