All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.autonomousapps.tasks.AbiAnalysisTask.kt Maven / Gradle / Ivy

There is a newer version: 2.0.2
Show newest version
@file:Suppress("UnstableApiUsage")

package com.autonomousapps.tasks

import com.autonomousapps.TASK_GROUP_DEP
import com.autonomousapps.advice.Dependency
import com.autonomousapps.internal.AbiExclusions
import com.autonomousapps.internal.Component
import com.autonomousapps.internal.kotlin.abiDependencies
import com.autonomousapps.internal.utils.*
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
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 javax.inject.Inject

@CacheableTask
abstract class AbiAnalysisTask @Inject constructor(
  private val workerExecutor: WorkerExecutor
) : DefaultTask() {

  init {
    group = TASK_GROUP_DEP
    description = "Produces a report of the ABI of this project"
  }

  /**
   * Mutually exclusive with [javaClasses] and [kotlinClasses].
   */
  @get:Optional
  @get:Classpath
  abstract val jar: RegularFileProperty

  /**
   * Class files generated by Java source. Mutually exclusive with [jar].
   */
  @get:Optional
  @get:Classpath
  @get:InputFiles
  abstract val javaClasses: ConfigurableFileCollection

  /**
   * Class files generated by Kotlin source. Mutually exclusive with [jar].
   */
  @get:Optional
  @get:Classpath
  @get:InputFiles
  abstract val kotlinClasses: ConfigurableFileCollection

  @get:PathSensitive(PathSensitivity.RELATIVE)
  @get:InputFile
  abstract val dependencies: RegularFileProperty

  @get:Optional
  @get:Input
  abstract val exclusions: Property

  @get:OutputFile
  abstract val output: RegularFileProperty

  @get:OutputFile
  abstract val abiDump: RegularFileProperty

  @TaskAction
  fun action() {
    workerExecutor.noIsolation().submit(AbiAnalysisWorkAction::class.java) {
      jar.set([email protected])
      javaClasses.setFrom([email protected])
      kotlinClasses.setFrom([email protected])
      dependencies.set([email protected])
      exclusions.set([email protected])
      output.set([email protected])
      abiDump.set([email protected])
    }
  }
}

interface AbiAnalysisParameters : WorkParameters {
  val jar: RegularFileProperty
  val javaClasses: ConfigurableFileCollection
  val kotlinClasses: ConfigurableFileCollection
  val dependencies: RegularFileProperty
  val exclusions: Property
  val output: RegularFileProperty
  val abiDump: RegularFileProperty
}

abstract class AbiAnalysisWorkAction : WorkAction {

  private val logger = getLogger()

  override fun execute() {
    // Inputs
    val jarFile = parameters.jar.orNull?.asFile
    val classFiles = allClassFiles()
    val dependencies = parameters.dependencies.fromJsonList()
    val exclusions = parameters.exclusions.orNull?.fromJson() ?: AbiExclusions.NONE

    // Outputs
    val reportFile = parameters.output.getAndDelete()
    val abiDumpFile = parameters.abiDump.getAndDelete()

    val apiDependencies = if (jarFile != null) {
      abiDependencies(jarFile, dependencies, exclusions, abiDumpFile)
    } else {
      abiDependencies(classFiles, dependencies, exclusions, abiDumpFile)
    }

    reportFile.writeText(apiDependencies.toJson())

    logger.debug("Your full API report is at ${reportFile.path}")
    logger.debug(
      "These are your API dependencies (see the report for more detail):\n${apiDependencies.joinToString(
        prefix = "- ",
        separator = "\n- "
      ) { lineItem(it.dependency) }}"
    )
  }

  private fun allClassFiles(): Set =
    parameters.javaClasses.asFileTree.files.plus(parameters.kotlinClasses.asFileTree.files)
      .filterToSet { it.path.endsWith(".class") }

  private fun lineItem(dependency: Dependency): String {
    val advice = if (dependency.configurationName != null) {
      "(is ${dependency.configurationName})"
    } else {
      "(is transitive or unknown)"
    }

    return "${dependency.identifier} $advice"
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy