added renderDependencies task

This commit is contained in:
2020-04-05 19:25:51 +01:00
parent 0d4983a364
commit e0d5e3c6bb
5 changed files with 106 additions and 29 deletions

View File

@@ -23,6 +23,10 @@ exportDependencies {
configurationName = 'runtime' configurationName = 'runtime'
} }
renderDependencies {
format = "svg"
}
dependencies { dependencies {
runtime("org.hibernate:hibernate-core:5.4.13.Final") runtime("org.hibernate:hibernate-core:5.4.13.Final")
} }

View File

@@ -9,7 +9,8 @@ buildscript {
} }
} }
import net.woggioni.plugins.DependencyExportPluginExtension import net.woggioni.plugins.ExportDependenciesPluginExtension
import net.woggioni.plugins.RenderDependenciesPluginExtension
plugins { plugins {
kotlin("jvm") version "1.3.71" kotlin("jvm") version "1.3.71"
@@ -25,6 +26,10 @@ dependencies {
runtime("org.hibernate:hibernate-core:5.4.13.Final") runtime("org.hibernate:hibernate-core:5.4.13.Final")
} }
configure<DependencyExportPluginExtension> { configure<ExportDependenciesPluginExtension> {
configurationName = "runtime" configurationName = "runtime"
} }
configure<RenderDependenciesPluginExtension> {
format = "svg"
}

View File

@@ -3,6 +3,7 @@
*/ */
package net.woggioni.plugins package net.woggioni.plugins
import org.gradle.api.GradleException
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.component.ModuleComponentIdentifier import org.gradle.api.artifacts.component.ModuleComponentIdentifier
@@ -13,26 +14,63 @@ import org.gradle.api.artifacts.result.UnresolvedDependencyResult
import java.io.BufferedWriter import java.io.BufferedWriter
import java.io.OutputStreamWriter import java.io.OutputStreamWriter
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.reflect.KMutableProperty0
open class DependencyExportPluginExtension {
open class ExportDependenciesPluginExtension(project: Project) {
var configurationName: String = "default" var configurationName: String = "default"
var outputFile = project.buildDir.toPath().resolve("dependencies.dot")
}
open class RenderDependenciesPluginExtension(project: Project) {
var format: String = "xlib"
var outputFile = project.buildDir.toPath().resolve("renderedDependencies")
var graphvizExecutable: String = "dot"
}
private class Overrider(private val properties : Map<String, Any?>, private val prefix: String) {
inline fun <reified T> identity(arg: T): T {
return arg
}
fun overrideProperty(
property: KMutableProperty0<String>) {
overrideProperty(property, ::identity)
}
inline fun <reified V> overrideProperty(
property: KMutableProperty0<V>,
valueFactory: (String) -> V) {
val propertyKey = prefix + "." + property.name
val propertyValue = properties[propertyKey] as String?
if (propertyValue != null) {
property.set(valueFactory(propertyValue))
}
}
} }
object DependencyExporter { object DependencyExporter {
fun graphviz(project: Project, configurationName : String) { fun exportDot(project: Project, ext: ExportDependenciesPluginExtension) {
val overrider = Overrider(project.properties, "exportDependencies")
overrider.overrideProperty(ext::configurationName)
overrider.overrideProperty(ext::outputFile) { value -> Paths.get(value) }
var sequence = 0 var sequence = 0
val map = HashMap<ResolvedComponentResult, Int>() val map = HashMap<ResolvedComponentResult, Int>()
val resolutionResult = project.configurations.single { val resolutionResult = project.configurations.single {
it.name == configurationName it.name == ext.configurationName
}.incoming.resolutionResult }.incoming.resolutionResult
project.buildDir.toPath().let { if(!ext.outputFile.isAbsolute) {
Files.createDirectories(it) ext.outputFile = project.buildDir.toPath().resolve(ext.outputFile)
}.let { }
Files.createDirectories(ext.outputFile.parent)
BufferedWriter( BufferedWriter(
OutputStreamWriter( OutputStreamWriter(
Files.newOutputStream(project.buildDir.toPath().resolve("dependencies.dot")))) Files.newOutputStream(ext.outputFile))).use { writer ->
}.use { writer ->
writer.write("digraph G {") writer.write("digraph G {")
writer.newLine() writer.newLine()
writer.write(" #rankdir=\"LR\";") writer.write(" #rankdir=\"LR\";")
@@ -83,17 +121,47 @@ object DependencyExporter {
} }
} }
object DependencyRenderer {
fun render(project: Project, ext: RenderDependenciesPluginExtension, sourceFile : Path) {
val overrider = Overrider(project.properties, "renderDependencies")
overrider.overrideProperty(ext::format)
overrider.overrideProperty(ext::graphvizExecutable)
overrider.overrideProperty(ext::outputFile) { value -> Paths.get(value) }
if(!ext.outputFile.isAbsolute) {
ext.outputFile = project.buildDir.toPath().resolve(ext.outputFile)
}
val cmd: List<String> = listOf(
ext.graphvizExecutable,
"-T${ext.format}",
"-o${ext.outputFile}",
sourceFile.toString()
)
val returnCode = ProcessBuilder(cmd).inheritIO().start().waitFor()
if (returnCode != 0) {
throw GradleException("Error invoking graphviz")
}
}
}
class DependencyExportPlugin : Plugin<Project> { class DependencyExportPlugin : Plugin<Project> {
override fun apply(project: Project) { override fun apply(project: Project) {
val extension = DependencyExportPluginExtension() val dependencyExportExtension = ExportDependenciesPluginExtension(project)
project.extensions.add(DependencyExportPluginExtension::class.java, "exportDependencies", extension) project.extensions.add(ExportDependenciesPluginExtension::class.java, "exportDependencies", dependencyExportExtension)
project.tasks.register("exportDependencies") { val exportDependenciesTask = project.tasks.register("exportDependencies") {
it.doLast { it.doLast {
val propertyKey = "exportDependencies.configurationName" DependencyExporter.exportDot(project, dependencyExportExtension)
val properties = project.properties }
val configurationName = properties.getOrDefault(propertyKey, extension.configurationName) as String }.get()
DependencyExporter.graphviz(project, configurationName = configurationName)
} val renderDependenciesPluginExtension = RenderDependenciesPluginExtension(project)
} project.extensions.add(RenderDependenciesPluginExtension::class.java, "renderDependencies", renderDependenciesPluginExtension)
val renderDependenciesTask = project.tasks.register("renderDependencies") {
it.dependsOn(exportDependenciesTask)
it.doLast {
DependencyRenderer.render(project, renderDependenciesPluginExtension, dependencyExportExtension.outputFile)
}
}.get()
} }
} }