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

com.autonomousapps.tasks.classAnalysisTasks.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.internal.ClassSetReader
import com.autonomousapps.internal.JarReader
import com.autonomousapps.internal.utils.*
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
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

abstract class ClassAnalysisTask(private val objects: ObjectFactory) : DefaultTask() {

  @get:PathSensitive(PathSensitivity.NONE)
  @get:InputFile
  abstract val variantFiles: RegularFileProperty

  /**
   * Android layout XML files.
   */
  @get:PathSensitive(PathSensitivity.RELATIVE)
  @get:InputFiles
  abstract val layoutFiles: ConfigurableFileCollection

  /**
   * Files from test source-sets (src/test).
   */
  @get:Optional
  @get:PathSensitive(PathSensitivity.RELATIVE)
  @get:InputFiles
  abstract val testJavaClassesDir: DirectoryProperty

  /**
   * Files from test source-sets (src/test).
   */
  @get:Optional
  @get:PathSensitive(PathSensitivity.RELATIVE)
  @get:InputFiles
  abstract val testKotlinClassesDir: DirectoryProperty

  @get:OutputFile
  abstract val output: RegularFileProperty

  @get:OutputFile
  abstract val outputPretty: RegularFileProperty

  internal fun layouts(files: List) {
    for (file in files) {
      layoutFiles.from(
        objects.fileTree().from(file)
          .matching {
            include { it.path.contains("layout") }
          }.files
      )
    }
  }

  @Internal
  protected fun getTestFiles(): Set {
    val testJavaClasses = testJavaClassesDir.orNull?.asFileTree?.files ?: emptySet()
    val testKtClasses = testKotlinClassesDir.orNull?.asFileTree?.files ?: emptySet()
    return testJavaClasses + testKtClasses
  }
}

/**
 * Produces a report of all classes referenced by a given jar.
 */
@CacheableTask
abstract class JarAnalysisTask @Inject constructor(
  objects: ObjectFactory,
  private val workerExecutor: WorkerExecutor
) : ClassAnalysisTask(objects) {

  init {
    group = TASK_GROUP_DEP
    description = "Produces a report of all classes referenced by a given jar"
  }

  @get:Classpath
  abstract val jar: RegularFileProperty

  @TaskAction fun action() {
    // Output
    val reportFile = output.getAndDelete()
    val reportPrettyFile = outputPretty.getAndDelete()

    val jarFile = jar.get().asFile
    logger.debug("jar path = ${jarFile.path}")

    workerExecutor.noIsolation().submit(JarAnalysisWorkAction::class.java) {
      variantFiles.set([email protected])
      jar = jarFile
      layouts = layoutFiles.files
      testFiles = getTestFiles()
      report = reportFile
      reportPretty = reportPrettyFile
    }
  }
}

interface JarAnalysisParameters : WorkParameters {
  val variantFiles: RegularFileProperty
  var jar: File
  var layouts: Set
  var testFiles: Set
  var report: File
  var reportPretty: File
}

abstract class JarAnalysisWorkAction : WorkAction {

  private val logger = getLogger()

  override fun execute() {
    val classNames = JarReader(
      variantFiles = parameters.variantFiles.fromJsonSet(),
      jarFile = parameters.jar,
      layouts = parameters.layouts,
      testFiles = parameters.testFiles
    ).analyze()

    parameters.report.writeText(classNames.toJson())
    parameters.reportPretty.writeText(classNames.toPrettyString())

    logger.log("Report:\n${parameters.report.readText()}")
  }
}

/**
 * Produces a report of all classes referenced by a given set of class files.
 */
@CacheableTask
abstract class ClassListAnalysisTask @Inject constructor(
  objects: ObjectFactory,
  private val workerExecutor: WorkerExecutor
) : ClassAnalysisTask(objects) {

  init {
    group = TASK_GROUP_DEP
    description = "Produces a report of all classes referenced by a given set of class files"
  }

  /**
   * Class files generated by Kotlin source. May be empty.
   */
  @get:Classpath
  @get:InputFiles
  abstract val kotlinClasses: ConfigurableFileCollection

  /**
   * Class files generated by Java source. May be empty.
   */
  @get:Classpath
  @get:InputFiles
  abstract val javaClasses: ConfigurableFileCollection

  @TaskAction fun action() {
    // Output
    val reportFile = output.getAndDelete()
    val reportPrettyFile = outputPretty.getAndDelete()

    val inputClassFiles = javaClasses.asFileTree.plus(kotlinClasses)
      .filterToClassFiles()
      .files

    logger.log("Java class files:${javaClasses.joinToString(prefix = "\n- ", separator = "\n- ") { it.path }}")
    logger.log("Kotlin class files:${kotlinClasses.joinToString(prefix = "\n- ", separator = "\n- ") { it.path }}")

    workerExecutor.noIsolation().submit(ClassListAnalysisWorkAction::class.java) {
      classes = inputClassFiles
      variantFiles.set([email protected])
      layouts = layoutFiles.files
      testFiles = getTestFiles()
      report = reportFile
      reportPretty = reportPrettyFile
    }
  }
}

interface ClassListAnalysisParameters : WorkParameters {
  var classes: Set
  val variantFiles: RegularFileProperty
  var layouts: Set
  var testFiles: Set
  var report: File
  var reportPretty: File
}

abstract class ClassListAnalysisWorkAction : WorkAction {

  private val logger = getLogger()

  override fun execute() {
    val usedClasses = ClassSetReader(
      classes = parameters.classes,
      variantFiles = parameters.variantFiles.fromJsonSet(),
      layouts = parameters.layouts,
      testFiles = parameters.testFiles
    ).analyze()

    parameters.report.writeText(usedClasses.toJson())
    parameters.reportPretty.writeText(usedClasses.toPrettyString())

    logger.log("Class list usage report: ${parameters.report.path}")
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy