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'
}
renderDependencies {
format = "svg"
}
dependencies {
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 {
kotlin("jvm") version "1.3.71"
@@ -25,6 +26,10 @@ dependencies {
runtime("org.hibernate:hibernate-core:5.4.13.Final")
}
configure<DependencyExportPluginExtension> {
configure<ExportDependenciesPluginExtension> {
configurationName = "runtime"
}
configure<RenderDependenciesPluginExtension> {
format = "svg"
}

View File

@@ -3,6 +3,7 @@
*/
package net.woggioni.plugins
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
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.OutputStreamWriter
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 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 {
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
val map = HashMap<ResolvedComponentResult, Int>()
val resolutionResult = project.configurations.single {
it.name == configurationName
it.name == ext.configurationName
}.incoming.resolutionResult
project.buildDir.toPath().let {
Files.createDirectories(it)
}.let {
if(!ext.outputFile.isAbsolute) {
ext.outputFile = project.buildDir.toPath().resolve(ext.outputFile)
}
Files.createDirectories(ext.outputFile.parent)
BufferedWriter(
OutputStreamWriter(
Files.newOutputStream(project.buildDir.toPath().resolve("dependencies.dot"))))
}.use { writer ->
Files.newOutputStream(ext.outputFile))).use { writer ->
writer.write("digraph G {")
writer.newLine()
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> {
override fun apply(project: Project) {
val extension = DependencyExportPluginExtension()
project.extensions.add(DependencyExportPluginExtension::class.java, "exportDependencies", extension)
project.tasks.register("exportDependencies") {
val dependencyExportExtension = ExportDependenciesPluginExtension(project)
project.extensions.add(ExportDependenciesPluginExtension::class.java, "exportDependencies", dependencyExportExtension)
val exportDependenciesTask = project.tasks.register("exportDependencies") {
it.doLast {
val propertyKey = "exportDependencies.configurationName"
val properties = project.properties
val configurationName = properties.getOrDefault(propertyKey, extension.configurationName) as String
DependencyExporter.graphviz(project, configurationName = configurationName)
}
}
DependencyExporter.exportDot(project, dependencyExportExtension)
}
}.get()
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()
}
}