com.autonomousapps.tasks.GraphViewTask.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dependency-analysis-gradle-plugin Show documentation
Show all versions of dependency-analysis-gradle-plugin Show documentation
Analyzes dependency usage in Android and JVM projects
// Copyright (c) 2024. Tony Robalik.
// SPDX-License-Identifier: Apache-2.0
package com.autonomousapps.tasks
import com.autonomousapps.internal.externalArtifactsFor
import com.autonomousapps.internal.graph.GraphViewBuilder
import com.autonomousapps.internal.graph.GraphWriter
import com.autonomousapps.internal.utils.bufferWriteJson
import com.autonomousapps.internal.utils.getAndDelete
import com.autonomousapps.internal.utils.mapNotNullToSet
import com.autonomousapps.internal.utils.toCoordinates
import com.autonomousapps.model.Coordinates
import com.autonomousapps.model.CoordinatesContainer
import com.autonomousapps.model.DependencyGraphView
import com.autonomousapps.model.declaration.SourceSetKind
import com.autonomousapps.model.declaration.Variant
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.FileCollectionDependency
import org.gradle.api.artifacts.result.ResolvedComponentResult
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.*
@CacheableTask
abstract class GraphViewTask : DefaultTask() {
init {
description = "Constructs a variant-specific view of this project's dependency graph"
}
@get:Internal
abstract val compileClasspathName: Property
@get:Internal
abstract val compileClasspathResult: Property
@get:Internal
abstract val compileClasspathFileCoordinates: SetProperty
@get:Internal
abstract val runtimeClasspathName: Property
@get:Internal
abstract val runtimeClasspathResult: Property
@get:Internal
abstract val runtimeClasspathFileCoordinates: SetProperty
@get:PathSensitive(PathSensitivity.NAME_ONLY)
@get:InputFiles
abstract val compileFiles: ConfigurableFileCollection
@get:PathSensitive(PathSensitivity.NAME_ONLY)
@get:InputFiles
abstract val runtimeFiles: ConfigurableFileCollection
/**
* Unused, except to influence the up-to-date-ness of this task. Declaring a transitive dependency doesn't change the
* compile classpath, but it must influence the output of this task.
*/
@get:PathSensitive(PathSensitivity.NONE)
@get:InputFile
abstract val declarations: RegularFileProperty
/** Needed to make sure task gives the same result if the build configuration in a composite changed between runs. */
@get:Input
abstract val buildPath: Property
/** Needed to disambiguate other projects that might have otherwise identical inputs. */
@get:Input
abstract val projectPath: Property
@get:Input
abstract val variant: Property
@get:Input
abstract val kind: Property
/** Output in json format for compile classpath graph. */
@get:OutputFile
abstract val output: RegularFileProperty
/** Output in json format for compile classpath dependencies (the graph's nodes). */
@get:OutputFile
abstract val outputNodes: RegularFileProperty
/** Output in graphviz format for compile classpath graph. */
@get:OutputFile
abstract val outputDot: RegularFileProperty
/** Output in json format for runtime classpath graph. */
@get:OutputFile
abstract val outputRuntime: RegularFileProperty
/** Output in graphviz format for runtime classpath graph. */
@get:OutputFile
abstract val outputRuntimeDot: RegularFileProperty
internal fun configureTask(
project: Project,
compileClasspath: Configuration,
runtimeClasspath: Configuration,
jarAttr: String,
) {
compileClasspathName.set(compileClasspath.name)
compileClasspathResult.set(compileClasspath.incoming.resolutionResult.rootComponent)
compileClasspathFileCoordinates.set(project.provider {
compileClasspath.allDependencies
.filterIsInstance()
.mapNotNullToSet { it.toCoordinates() }
})
runtimeClasspathName.set(runtimeClasspath.name)
runtimeClasspathResult.set(runtimeClasspath.incoming.resolutionResult.rootComponent)
runtimeClasspathFileCoordinates.set(project.provider {
runtimeClasspath.allDependencies
.filterIsInstance()
.mapNotNullToSet { it.toCoordinates() }
})
compileFiles.setFrom(project.provider { compileClasspath.externalArtifactsFor(jarAttr).artifactFiles })
runtimeFiles.setFrom(project.provider { runtimeClasspath.externalArtifactsFor(jarAttr).artifactFiles })
}
@TaskAction fun action() {
val output = output.getAndDelete()
val outputDot = outputDot.getAndDelete()
val outputNodes = outputNodes.getAndDelete()
val outputRuntime = outputRuntime.getAndDelete()
val outputRuntimeDot = outputRuntimeDot.getAndDelete()
val variant = variant.get()
val kind = kind.get()
val compileGraph = GraphViewBuilder(compileClasspathResult.get(), compileClasspathFileCoordinates.get()).graph
val compileGraphView = DependencyGraphView(
variant = Variant(variant, kind),
configurationName = compileClasspathName.get(),
graph = compileGraph
)
val runtimeGraph = GraphViewBuilder(runtimeClasspathResult.get(), runtimeClasspathFileCoordinates.get()).graph
val runtimeGraphView = DependencyGraphView(
variant = Variant(variant, kind),
configurationName = runtimeClasspathName.get(),
graph = runtimeGraph
)
output.bufferWriteJson(compileGraphView)
outputDot.writeText(GraphWriter.toDot(compileGraph))
outputNodes.bufferWriteJson(CoordinatesContainer(compileGraphView.nodes))
outputRuntime.bufferWriteJson(runtimeGraphView)
outputRuntimeDot.writeText(GraphWriter.toDot(runtimeGraph))
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy