com.autonomousapps.tasks.CodeSourceExploderTask.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.parse.SourceListener
import com.autonomousapps.internal.utils.bufferWriteJsonSet
import com.autonomousapps.internal.utils.getAndDelete
import com.autonomousapps.model.CodeSource.Kind
import com.autonomousapps.model.intermediates.ExplodingSourceCode
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.*
import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor
import java.io.File
import java.nio.file.Paths
import javax.inject.Inject
@CacheableTask
abstract class CodeSourceExploderTask @Inject constructor(
private val workerExecutor: WorkerExecutor,
private val layout: ProjectLayout
) : DefaultTask() {
init {
description = "Parses Java and Kotlin source to detect source-only usages"
}
/** The Groovy source of the current project. */
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputFiles
abstract val groovySourceFiles: ConfigurableFileCollection
/** The Java source of the current project. */
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputFiles
abstract val javaSourceFiles: ConfigurableFileCollection
/** The Kotlin source of the current project. */
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputFiles
abstract val kotlinSourceFiles: ConfigurableFileCollection
/** The Scala source of the current project. */
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputFiles
abstract val scalaSourceFiles: ConfigurableFileCollection
@get:OutputFile
abstract val output: RegularFileProperty
@TaskAction fun action() {
workerExecutor.noIsolation().submit(CodeSourceExploderWorkAction::class.java) {
projectDir.set(layout.projectDirectory)
groovySourceFiles.from([email protected])
javaSourceFiles.from([email protected])
kotlinSourceFiles.from([email protected])
scalaSourceFiles.from([email protected])
output.set([email protected])
}
}
interface CodeSourceExploderParameters : WorkParameters {
val projectDir: DirectoryProperty
val groovySourceFiles: ConfigurableFileCollection
val javaSourceFiles: ConfigurableFileCollection
val kotlinSourceFiles: ConfigurableFileCollection
val scalaSourceFiles: ConfigurableFileCollection
val output: RegularFileProperty
}
abstract class CodeSourceExploderWorkAction : WorkAction {
override fun execute() {
val reportFile = parameters.output.getAndDelete()
val explodedSource = SourceExploder(
projectDir = parameters.projectDir.get().asFile,
groovySourceFiles = parameters.groovySourceFiles,
javaSourceFiles = parameters.javaSourceFiles,
kotlinSourceFiles = parameters.kotlinSourceFiles,
scalaSourceFiles = parameters.scalaSourceFiles,
).explode()
reportFile.bufferWriteJsonSet(explodedSource)
}
}
}
private class SourceExploder(
private val projectDir: File,
private val groovySourceFiles: ConfigurableFileCollection,
private val javaSourceFiles: ConfigurableFileCollection,
private val kotlinSourceFiles: ConfigurableFileCollection,
private val scalaSourceFiles: ConfigurableFileCollection,
) {
fun explode(): Set {
val destination = sortedSetOf()
javaSourceFiles.mapTo(destination) {
val rel = relativize(it)
ExplodingSourceCode(
relativePath = rel,
className = canonicalClassName(rel),
kind = Kind.JAVA,
imports = SourceListener.parseSourceFileForImports(it)
)
}
kotlinSourceFiles.mapTo(destination) {
val rel = relativize(it)
ExplodingSourceCode(
relativePath = rel,
className = canonicalClassName(rel),
kind = Kind.KOTLIN,
imports = SourceListener.parseSourceFileForImports(it)
)
}
groovySourceFiles.mapTo(destination) {
val rel = relativize(it)
ExplodingSourceCode(
relativePath = rel,
className = canonicalClassName(rel),
kind = Kind.GROOVY,
imports = SourceListener.parseSourceFileForImports(it)
)
}
scalaSourceFiles.mapTo(destination) {
val rel = relativize(it)
ExplodingSourceCode(
relativePath = rel,
className = canonicalClassName(rel),
kind = Kind.SCALA,
imports = SourceListener.parseSourceFileForImports(it)
)
}
return destination
}
private fun relativize(file: File) = file.toRelativeString(projectDir)
private fun canonicalClassName(relativePath: String): String {
return Paths.get(relativePath)
// Hack to drop e.g. `src/main/java`. Would be better if a FileTree exposed that info.
.drop(3)
// com/example/Foo.java -> com.example.Foo.java
.joinToString(separator = ".")
// Drop file extension (.java, .kt, etc.) as well.
.substringBeforeLast('.')
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy