Refactoring: cleanup gradle plugin

This commit is contained in:
Alexey Tsvetkov
2016-07-27 22:50:12 +03:00
parent 81bc2701fa
commit aff5dd1691
7 changed files with 40 additions and 64 deletions
@@ -31,11 +31,11 @@ import javax.xml.parsers.DocumentBuilderFactory
// Use apply plugin: 'kotlin-android-extensions' to enable Android Extensions in an Android project. // Use apply plugin: 'kotlin-android-extensions' to enable Android Extensions in an Android project.
// Just a marker plugin. // Just a marker plugin.
public class AndroidExtensionsSubpluginIndicator : Plugin<Project> { class AndroidExtensionsSubpluginIndicator : Plugin<Project> {
override fun apply(target: Project?) {} override fun apply(target: Project?) {}
} }
public class AndroidSubplugin : KotlinGradleSubplugin { class AndroidSubplugin : KotlinGradleSubplugin {
private companion object { private companion object {
@Volatile @Volatile
var migrateWarningReported: Boolean = false var migrateWarningReported: Boolean = false
@@ -121,7 +121,7 @@ private fun Project.createKotlinAfterJavaTask(
return kotlinAfterJavaTask return kotlinAfterJavaTask
} }
public class AnnotationProcessingManager( class AnnotationProcessingManager(
private val task: AbstractCompile, private val task: AbstractCompile,
private val javaTask: JavaCompile, private val javaTask: JavaCompile,
private val taskQualifier: String, private val taskQualifier: String,
@@ -298,7 +298,7 @@ public class AnnotationProcessingManager(
private inline fun JavaCompile.modifyCompilerArguments(modifier: (MutableList<String>) -> Unit) { private inline fun JavaCompile.modifyCompilerArguments(modifier: (MutableList<String>) -> Unit) {
val compilerArgs: List<Any> = this.options.compilerArgs val compilerArgs: List<Any> = this.options.compilerArgs
val newCompilerArgs = compilerArgs.mapTo(arrayListOf<String>()) { it.toString() } val newCompilerArgs = compilerArgs.mapTo(arrayListOf<String>(), Any::toString)
modifier(newCompilerArgs) modifier(newCompilerArgs)
options.compilerArgs = newCompilerArgs options.compilerArgs = newCompilerArgs
} }
@@ -337,9 +337,7 @@ public class AnnotationProcessingManager(
withZipFile(file) { zipFile -> withZipFile(file) { zipFile ->
val entry = zipFile.getEntry("META-INF/services/javax.annotation.processing.Processor") val entry = zipFile.getEntry("META-INF/services/javax.annotation.processing.Processor")
if (entry != null) { if (entry != null) {
zipFile.getInputStream(entry).reader().useLines { lines -> zipFile.getInputStream(entry).reader().useLines(::processLines)
processLines(lines)
}
} }
} }
} }
@@ -96,7 +96,7 @@ class CleanUpBuildListener(private val project: Project) : BuildAdapter() {
class CompilerServicesCleanup() { class CompilerServicesCleanup() {
val log = Logging.getLogger(this.javaClass) private val log = Logging.getLogger(this.javaClass)
operator fun invoke(gradleVersion: String) { operator fun invoke(gradleVersion: String) {
log.kotlinDebug("compiler services cleanup") log.kotlinDebug("compiler services cleanup")
@@ -19,15 +19,15 @@ package org.jetbrains.kotlin.gradle.plugin
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Project import org.gradle.api.Project
public open class KaptExtension { open class KaptExtension {
public open var generateStubs: Boolean = false open var generateStubs: Boolean = false
public open var inheritedAnnotations: Boolean = true open var inheritedAnnotations: Boolean = true
private var closure: Closure<*>? = null private var closure: Closure<*>? = null
public open fun arguments(closure: Closure<*>) { open fun arguments(closure: Closure<*>) {
this.closure = closure this.closure = closure
} }
@@ -40,15 +40,15 @@ public open class KaptExtension {
} }
} }
public open class KaptAdditionalArgumentsDelegate( open class KaptAdditionalArgumentsDelegate(
public open val project: Project, open val project: Project,
public open val variant: Any?, open val variant: Any?,
public open val android: Any? open val android: Any?
) { ) {
val additionalCompilerArgs = arrayListOf<String>() val additionalCompilerArgs = arrayListOf<String>()
public open fun arg(name: Any, vararg values: Any) { open fun arg(name: Any, vararg values: Any) {
val valuesString = if (values.isNotEmpty()) values.joinToString(" ", prefix = "=") else "" val valuesString = if (values.isNotEmpty()) values.joinToString(" ", prefix = "=") else ""
additionalCompilerArgs.add("-A$name$valuesString") additionalCompilerArgs.add("-A$name$valuesString")
} }
@@ -7,14 +7,9 @@ import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.model.SourceProvider import com.android.builder.model.SourceProvider
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.file.FileCollection
import org.gradle.api.initialization.dsl.ScriptHandler
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging import org.gradle.api.logging.Logging
import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.JavaBasePlugin
@@ -36,7 +31,6 @@ import java.io.File
import java.net.URL import java.net.URL
import java.util.* import java.util.*
import java.util.jar.Manifest import java.util.jar.Manifest
import javax.inject.Inject
val KOTLIN_AFTER_JAVA_TASK_SUFFIX = "AfterJava" val KOTLIN_AFTER_JAVA_TASK_SUFFIX = "AfterJava"
val KOTLIN_DSL_NAME = "kotlin" val KOTLIN_DSL_NAME = "kotlin"
@@ -57,8 +51,7 @@ abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
val logger = Logging.getLogger(this.javaClass) val logger = Logging.getLogger(this.javaClass)
protected val sourceSetName: String = sourceSet.name protected val sourceSetName: String = sourceSet.name
protected val sourceRootDir: String = "src/${sourceSetName}/kotlin" protected val sourceRootDir: String = "src/$sourceSetName/kotlin"
protected val absoluteSourceRootDir: String = project.projectDir.path + "/" + sourceRootDir
protected val kotlinSourceSet: KotlinSourceSet = createKotlinSourceSet() protected val kotlinSourceSet: KotlinSourceSet = createKotlinSourceSet()
protected val kotlinTask: T = createKotlinCompileTask() protected val kotlinTask: T = createKotlinCompileTask()
protected abstract val defaultKotlinDestinationDir: File protected abstract val defaultKotlinDestinationDir: File
@@ -176,21 +169,12 @@ class Kotlin2JsSourceSetProcessor(
compileTaskNameSuffix = "kotlin2Js" compileTaskNameSuffix = "kotlin2Js"
) { ) {
override val defaultKotlinDestinationDir: File override val defaultKotlinDestinationDir: File
get() = File(project.buildDir, "kotlin2js/${sourceSetName}") get() = File(project.buildDir, "kotlin2js/${sourceSetName}")
val copyKotlinJsTaskName = sourceSet.getTaskName("copy", "kotlinJs")
val clean = project.tasks.findByName("clean")
val build = project.tasks.findByName("build")
private fun kotlinTaskDestinationDir(): File? = kotlinTask.destinationDir private val clean = project.tasks.findByName("clean")
private fun kotlinJsDestinationDir(): File? = (kotlinTask.property("outputFile") as String).let { File(it) }.let { if (it.isDirectory) it else it.parentFile } private val build = project.tasks.findByName("build")
private fun kotlinSourcePathsForSourceMap() = sourceSet.getAllSource()
.map { it.path }
.filter { it.endsWith(".kt") }
.map { it.replace(absoluteSourceRootDir, (kotlinTask.property("sourceMapDestinationDir") as File).path) }
private fun shouldGenerateSourceMap() = kotlinTask.property("sourceMap")
override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile = override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile =
tasksProvider.createKotlinJSTask(project, taskName) tasksProvider.createKotlinJSTask(project, taskName)
@@ -227,14 +211,14 @@ abstract class AbstractKotlinPlugin(val tasksProvider: KotlinTasksProvider, val
configureSourceSetDefaults(project, javaBasePlugin, javaPluginConvention) configureSourceSetDefaults(project, javaBasePlugin, javaPluginConvention)
} }
open protected fun configureSourceSetDefaults(project: Project, open protected fun configureSourceSetDefaults(
javaBasePlugin: JavaBasePlugin, project: Project,
javaPluginConvention: JavaPluginConvention) { javaBasePlugin: JavaBasePlugin,
javaPluginConvention.sourceSets?.all(Action<SourceSet> { sourceSet -> javaPluginConvention: JavaPluginConvention
if (sourceSet != null) { ) {
buildSourceSetProcessor(project, javaBasePlugin, sourceSet).run() javaPluginConvention.sourceSets?.all { sourceSet ->
} buildSourceSetProcessor(project, javaBasePlugin, sourceSet).run()
}) }
} }
} }
@@ -266,7 +250,7 @@ open class KotlinAndroidPlugin(
private val kotlinSourceSetProvider: KotlinSourceSetProvider private val kotlinSourceSetProvider: KotlinSourceSetProvider
) : Plugin<Project> { ) : Plugin<Project> {
val log = Logging.getLogger(this.javaClass) private val log = Logging.getLogger(this.javaClass)
override fun apply(project: Project) { override fun apply(project: Project) {
val ext = project.extensions.getByName("android") as BaseExtension val ext = project.extensions.getByName("android") as BaseExtension
@@ -303,8 +287,8 @@ open class KotlinAndroidPlugin(
project.afterEvaluate { project -> project.afterEvaluate { project ->
if (project != null) { if (project != null) {
val plugin = (project.plugins.findPlugin("android") val plugin = (project.plugins.findPlugin("android")
?: project.plugins.findPlugin("android-library") ?: project.plugins.findPlugin("android-library")
?: project.plugins.findPlugin("com.android.test")) as BasePlugin ?: project.plugins.findPlugin("com.android.test")) as BasePlugin
val variantManager = AndroidGradleWrapper.getVariantDataManager(plugin) val variantManager = AndroidGradleWrapper.getVariantDataManager(plugin)
processVariantData(variantManager.variantDataList, project, processVariantData(variantManager.variantDataList, project,
@@ -454,13 +438,13 @@ private fun loadSubplugins(project: Project): SubpluginEnvironment {
fun Project.getResolvedArtifacts() = buildscript.configurations.getByName("classpath") fun Project.getResolvedArtifacts() = buildscript.configurations.getByName("classpath")
.resolvedConfiguration.resolvedArtifacts .resolvedConfiguration.resolvedArtifacts
val resolvedClasspathArtifacts = project.getResolvedArtifacts().toMutableList() val resolvedClasspathArtifacts = project.getResolvedArtifacts().toMutableList()
val rootProject = project.rootProject val rootProject = project.rootProject
if (rootProject != project) { if (rootProject != project) {
resolvedClasspathArtifacts += rootProject.getResolvedArtifacts() resolvedClasspathArtifacts += rootProject.getResolvedArtifacts()
} }
val subpluginClasspaths = hashMapOf<KotlinGradleSubplugin, List<File>>() val subpluginClasspaths = hashMapOf<KotlinGradleSubplugin, List<File>>()
for (subplugin in subplugins) { for (subplugin in subplugins) {
@@ -483,8 +467,8 @@ private fun loadSubplugins(project: Project): SubpluginEnvironment {
} }
class SubpluginEnvironment( class SubpluginEnvironment(
val subpluginClasspaths: Map<KotlinGradleSubplugin, List<File>>, val subpluginClasspaths: Map<KotlinGradleSubplugin, List<File>>,
val subplugins: List<KotlinGradleSubplugin> val subplugins: List<KotlinGradleSubplugin>
) { ) {
fun addSubpluginArguments(project: Project, kotlinTask: KotlinCompile) { fun addSubpluginArguments(project: Project, kotlinTask: KotlinCompile) {
@@ -493,7 +477,7 @@ class SubpluginEnvironment(
for (subplugin in subplugins) { for (subplugin in subplugins) {
if (!subplugin.isApplicable(project, kotlinTask)) continue if (!subplugin.isApplicable(project, kotlinTask)) continue
with (subplugin) { with(subplugin) {
project.logger.kotlinDebug("Subplugin ${getPluginName()} (${getGroupName()}:${getArtifactName()}) loaded.") project.logger.kotlinDebug("Subplugin ${getPluginName()} (${getGroupName()}:${getArtifactName()}) loaded.")
} }
@@ -507,9 +491,6 @@ class SubpluginEnvironment(
} }
} }
internal operator fun FileCollection.plus(other: FileCollection) = this.plus(other)
internal operator fun FileCollection.minus(other: FileCollection) = this.minus(other)
private fun Project.getAptDirsForSourceSet(sourceSetName: String): Pair<File, File> { private fun Project.getAptDirsForSourceSet(sourceSetName: String): Pair<File, File> {
val aptOutputDir = File(buildDir, "generated/source/kapt") val aptOutputDir = File(buildDir, "generated/source/kapt")
val aptOutputDirForVariant = File(aptOutputDir, sourceSetName) val aptOutputDirForVariant = File(aptOutputDir, sourceSetName)
@@ -543,7 +524,7 @@ private fun loadAndroidPluginVersion(): String? {
// Class not from JAR, unlikely // Class not from JAR, unlikely
return null return null
} }
val manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF"; val manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF"
val jarConnection = URL(manifestPath).openConnection() val jarConnection = URL(manifestPath).openConnection()
jarConnection.useCaches = false jarConnection.useCaches = false
@@ -552,7 +533,7 @@ private fun loadAndroidPluginVersion(): String? {
jarInputStream.close() jarInputStream.close()
return attr.getValue("Plugin-Version") return attr.getValue("Plugin-Version")
} catch (t: Throwable) { } catch (t: Throwable) {
return null; return null
} }
} }
@@ -12,7 +12,7 @@ import javax.inject.Inject
// TODO: simplify: the complicated structure is a leftover from dynamic loading of plugin core, could be significantly simplified now // TODO: simplify: the complicated structure is a leftover from dynamic loading of plugin core, could be significantly simplified now
abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver): Plugin<Project> { abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver): Plugin<Project> {
val log = Logging.getLogger(this.javaClass) private val log = Logging.getLogger(this.javaClass)
override fun apply(project: Project) { override fun apply(project: Project) {
// TODO: consider only set if if daemon or parallel compilation are enabled, though this way it should be safe too // TODO: consider only set if if daemon or parallel compilation are enabled, though this way it should be safe too
@@ -24,11 +24,8 @@ internal fun Any.loadKotlinVersionFromResource(log: Logger): String {
log.kotlinDebug("Loading version information") log.kotlinDebug("Loading version information")
val props = Properties() val props = Properties()
val propFileName = "project.properties" val propFileName = "project.properties"
val inputStream = javaClass.classLoader!!.getResourceAsStream(propFileName) val inputStream = javaClass.classLoader!!.getResourceAsStream(propFileName) ?:
throw FileNotFoundException("property file '$propFileName' not found in the classpath")
if (inputStream == null) {
throw FileNotFoundException("property file '" + propFileName + "' not found in the classpath")
}
props.load(inputStream) props.load(inputStream)