Skip to content

Commit

Permalink
Merge pull request #411 from Tapchicoma/agp-41
Browse files Browse the repository at this point in the history
Update Android Gradle plugin to 4.1 version.
  • Loading branch information
Tapchicoma authored Dec 7, 2020
2 parents 8da738a + 47412ac commit 10509e9
Show file tree
Hide file tree
Showing 23 changed files with 354 additions and 506 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
**Breaking** - removed support for following deprecated Kotlin plugins:
1. "kotlin2js"
2. "kotlin-platform-*"
- Updated Android Gradle Plugin to 4.1.0 version.

**Breaking** - removed build variants meta tasks. Minimum supported AGP version is 4.0.0.

### Removed
- ?
Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,6 @@ This plugin adds two maintasks to every source set: `ktlint[source set name]Sour
Additionally, a simple `ktlintCheck` task has also been added that checks all of the source sets for that project.
Similarly, a `ktlintFormat` task has been added that formats all of the source sets.

Android projects, additionally, will have meta tasks for Android variants, that will process all source sets in a variant.
For example, if app has `foo` flavor, following meta tasks will be added:
`ktlintFooDebugCheck`, `ktlintFooReleaseCheck`, `ktlintFooDebugFormat`, `ktlintFooReleaseFormat`.

Additionally plugin adds two task for project kotlin script files: `ktlintKotlinScriptCheck` and `ktlintKotlinScriptFormat`.

### Additional helper tasks
Expand Down
8 changes: 5 additions & 3 deletions buildSrc/src/main/kotlin/SamplesDependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ object SamplesVersions {
val junit = "4.12"

// Android sample dependencies
val androidSupport = "27.0.2"
val espressoRunner = "1.0.1"
val espresso = "3.0.1"
val androidXFragment = "1.2.5"
val androidXRecyclerView = "1.1.0"
val androidMaterial = "1.2.1"
val androidXTestRunner = "1.3.0"
val androidXEspresso = "3.3.0"
}
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
org.gradle.configureondemand=false
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m

android.useAndroidX=true
2 changes: 1 addition & 1 deletion plugin/buildSrc/src/main/kotlin/PluginDependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ object PluginVersions {
val kotlin = "1.4.10"
val ktlintPlugin = "9.3.0"
val gradlePublishPlugin = "0.12.0"
val androidPlugin = "3.6.3"
val androidPlugin = "4.1.0"
val semver = "1.1.1"
val jgit = "5.6.0.201912101111-r"
val gradleWrapper = "6.6.1"
Expand Down
235 changes: 3 additions & 232 deletions plugin/src/main/kotlin/org/jlleitschuh/gradle/ktlint/KtlintPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package org.jlleitschuh.gradle.ktlint

import com.android.build.gradle.BaseExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTree
import org.gradle.api.logging.configuration.ConsoleOutput
import org.gradle.api.tasks.TaskProvider
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import java.util.concurrent.Callable
import org.jlleitschuh.gradle.ktlint.android.applyKtLintToAndroid

/**
* Plugin that provides a wrapper over the `ktlint` project.
Expand Down Expand Up @@ -63,21 +58,8 @@ open class KtlintPlugin : Plugin<Project> {
}

multiplatformExtension.targets.all { kotlinTarget ->
when (kotlinTarget.platformType) {
KotlinPlatformType.androidJvm -> {
val androidConfigureAction: (Plugin<Any>) -> Unit = {
target.extensions.configure(BaseExtension::class.java) { ext ->
ext.addVariantsMetaTasks(target, kotlinTarget.targetName)
}
}
target.plugins.withId("com.android.application", androidConfigureAction)
target.plugins.withId("com.android.library", androidConfigureAction)
target.plugins.withId("com.android.instantapp", androidConfigureAction)
target.plugins.withId("com.android.feature", androidConfigureAction)
target.plugins.withId("com.android.test", androidConfigureAction)
target.plugins.withId("com.android.dynamic-feature", androidConfigureAction)
}
else -> Unit
if (kotlinTarget.platformType == KotlinPlatformType.androidJvm) {
applyKtLintToAndroid()
}
}
}
Expand Down Expand Up @@ -106,146 +88,6 @@ open class KtlintPlugin : Plugin<Project> {
}
}

private fun PluginHolder.applyKtLintToAndroid(): (Plugin<in Any>) -> Unit {
return {
fun createTasks(
sourceSetName: String,
sources: FileCollection
) {
val checkTask = createCheckTask(
this,
sourceSetName,
sources
)

addKtlintCheckTaskToProjectMetaCheckTask(checkTask)
setCheckTaskDependsOnKtlintCheckTask(target, checkTask)

val ktlintSourceSetFormatTask = createFormatTask(
this,
sourceSetName,
sources
)

addKtlintFormatTaskToProjectMetaFormatTask(ktlintSourceSetFormatTask)
}

/*
* Variant manager returns all sources for variant,
* so most probably main source set maybe checked several times.
* This approach creates one check tasks per one source set.
*/
val pluginConfigureAction: (Plugin<Any>) -> Unit = {
target.extensions.configure(BaseExtension::class.java) { ext ->
ext.sourceSets { sourceSet ->
sourceSet.all { androidSourceSet ->
// Passing Callable, so returned FileCollection, will lazy evaluate it
// only when task will need it.
// Solves the problem of having additional source dirs in
// current AndroidSourceSet, that are not available on eager
// evaluation.
createTasks(
androidSourceSet.name,
target.files(Callable { androidSourceSet.java.srcDirs })
)
}
}

ext.addVariantsMetaTasks(target)
}
}

target.plugins.withId("com.android.application", pluginConfigureAction)
target.plugins.withId("com.android.library", pluginConfigureAction)
target.plugins.withId("com.android.instantapp", pluginConfigureAction)
target.plugins.withId("com.android.feature", pluginConfigureAction)
target.plugins.withId("com.android.test", pluginConfigureAction)
target.plugins.withId("com.android.dynamic-feature", pluginConfigureAction)
}
}

private fun PluginHolder.addKtlintCheckTaskToProjectMetaCheckTask(
checkTask: TaskProvider<KtlintCheckTask>
) {
metaKtlintCheckTask.configure { it.dependsOn(checkTask) }
}

private fun PluginHolder.addKtlintFormatTaskToProjectMetaFormatTask(
formatTask: TaskProvider<KtlintFormatTask>
) {
metaKtlintFormatTask.configure { it.dependsOn(formatTask) }
}

private fun createFormatTask(
pluginHolder: PluginHolder,
sourceSetName: String,
kotlinSourceDirectories: Iterable<*>
): TaskProvider<KtlintFormatTask> {
return pluginHolder.target.registerTask(sourceSetName.sourceSetFormatTaskName()) {
description = "Runs a check against all .kt files to ensure that they are formatted according to ktlint."
configurePluginTask(pluginHolder) {
setSource(kotlinSourceDirectories)
}
}
}

private fun createCheckTask(
pluginHolder: PluginHolder,
sourceSetName: String,
kotlinSourceDirectories: Iterable<*>
): TaskProvider<KtlintCheckTask> {
return pluginHolder.target.registerTask(sourceSetName.sourceSetCheckTaskName()) {
description = "Runs a check against all .kt files to ensure that they are formatted according to ktlint."
configurePluginTask(pluginHolder) {
setSource(kotlinSourceDirectories)
}
}
}

private fun BaseKtlintCheckTask.configurePluginTask(
pluginHolder: PluginHolder,
additionalTaskConfig: BaseKtlintCheckTask.() -> Unit
) {
classpath.setFrom(pluginHolder.ktlintConfiguration)
ktlintVersion.set(pluginHolder.extension.version)
verbose.set(pluginHolder.extension.verbose)
additionalEditorconfigFile.set(pluginHolder.extension.additionalEditorconfigFile)
debug.set(pluginHolder.extension.debug)
ignoreFailures.set(pluginHolder.extension.ignoreFailures)
outputToConsole.set(pluginHolder.extension.outputToConsole)
coloredOutput.set(
pluginHolder.extension.coloredOutput.map {
if (pluginHolder.target.isConsolePlain()) {
pluginHolder.target.logger.info("Console type is plain: disabling colored output")
false
} else {
it
}
}
)
outputColorName.set(pluginHolder.extension.outputColorName)
ruleSetsClasspath.setFrom(pluginHolder.ktlintRulesetConfiguration)
reporters.set(pluginHolder.extension.reporterExtension.reporters)
customReportersClasspath.setFrom(pluginHolder.ktlintReporterConfiguration)
customReporters.set(pluginHolder.extension.reporterExtension.customReporters)
android.set(pluginHolder.extension.android)
enableExperimentalRules.set(pluginHolder.extension.enableExperimentalRules)
disabledRules.set(pluginHolder.extension.disabledRules)

additionalTaskConfig()
}

private fun setCheckTaskDependsOnKtlintCheckTask(
project: Project,
ktlintCheck: TaskProvider<KtlintCheckTask>
) {
project.plugins.withType(LifecycleBasePlugin::class.java) {
project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME).configure { task ->
task.dependsOn(ktlintCheck)
}
}
}

private fun PluginHolder.addKotlinScriptTasks() {
val projectDirectoryScriptFiles = target.fileTree(target.projectDir)
projectDirectoryScriptFiles.include("*.kts")
Expand All @@ -258,34 +100,6 @@ open class KtlintPlugin : Plugin<Project> {
addKtlintFormatTaskToProjectMetaFormatTask(formatTask)
}

private fun createKotlinScriptCheckTask(
pluginHolder: PluginHolder,
projectScriptFiles: FileTree
): TaskProvider<KtlintCheckTask> {
return pluginHolder.target.registerTask(KOTLIN_SCRIPT_CHECK_TASK) {
description = "Runs a check against all .kts files in project directory " +
"to ensure that they are formatted according to ktlint."
configurePluginTask(pluginHolder) {
source = projectScriptFiles
}
}
}

private fun createKotlinScriptFormatTask(
pluginHolder: PluginHolder,
projectScriptFiles: FileTree
): TaskProvider<KtlintFormatTask> {
return pluginHolder.target.registerTask(KOTLIN_SCRIPT_FORMAT_TASK) {
description = "Format all .kts files in project directory " +
"to ensure that they are formatted according to ktlint."
configurePluginTask(pluginHolder) {
source = projectScriptFiles
}
}
}

private fun Project.isConsolePlain() = gradle.startParameter.consoleOutput == ConsoleOutput.Plain

internal class PluginHolder(
val target: Project
) {
Expand All @@ -312,46 +126,3 @@ open class KtlintPlugin : Plugin<Project> {
}
}
}

/**
* This is not scoped inside of [KtlintPlugin] because of these issues:
* - https://github.com/JLLeitschuh/ktlint-gradle/issues/201
* - https://github.com/gradle/gradle/issues/8411
*/
private fun BaseExtension.addVariantsMetaTasks(
target: Project,
multiplatformTargetName: String? = null
) {
variants?.all { variant ->
val variantCheckTask = target.createAndroidVariantMetaKtlintCheckTask(
variant.name,
multiplatformTargetName
)
val variantFormatTask = target.createAndroidVariantMetaKtlintFormatTask(
variant.name,
multiplatformTargetName
)
variant.sourceSets.forEach { sourceSet ->
val sourceSetName = "${multiplatformTargetName?.capitalize() ?: ""}${sourceSet.name.capitalize()}"
variantCheckTask.configure { it.dependsOn(sourceSetName.sourceSetCheckTaskName()) }
variantFormatTask.configure { it.dependsOn(sourceSetName.sourceSetFormatTaskName()) }
}
}
}

private fun Project.createAndroidVariantMetaKtlintCheckTask(
variantName: String,
multiplatformTargetName: String? = null
): TaskProvider<Task> = registerTask(variantName.androidVariantMetaCheckTaskName(multiplatformTargetName)) {
group = VERIFICATION_GROUP
description = "Runs ktlint on all kotlin sources for android $variantName variant in this project."
}

private fun Project.createAndroidVariantMetaKtlintFormatTask(
variantName: String,
multiplatformTargetName: String? = null
): TaskProvider<Task> = registerTask(variantName.androidVariantMetaFormatTaskName(multiplatformTargetName)) {
group = FORMATTING_GROUP
description = "Runs ktlint formatter on all kotlin sources for android $variantName" +
" variant in this project."
}
34 changes: 2 additions & 32 deletions plugin/src/main/kotlin/org/jlleitschuh/gradle/ktlint/PluginUtil.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package org.jlleitschuh.gradle.ktlint

import com.android.build.gradle.AppExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.FeatureExtension
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.TestExtension
import com.android.build.gradle.api.BaseVariant
import net.swiftzer.semver.SemVer
import org.gradle.api.DomainObjectSet
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.configuration.ConsoleOutput
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.HelpTasksPlugin
import org.gradle.api.provider.ListProperty
Expand Down Expand Up @@ -130,28 +124,4 @@ internal fun String.sourceSetCheckTaskName() = "ktlint${capitalize()}SourceSetCh
*/
internal fun String.sourceSetFormatTaskName() = "ktlint${capitalize()}SourceSetFormat"

/**
* Create check task name for android variant name with optional android multiplatform target name addition.
*/
internal fun String.androidVariantMetaCheckTaskName(
multiplatformTargetName: String? = null
) = "ktlint${capitalize()}${multiplatformTargetName?.capitalize() ?: ""}Check"

/**
* Create format task name for android variant name with optional android multiplatform target name addition.
*/
internal fun String.androidVariantMetaFormatTaskName(
multiplatformTargetName: String? = null
) = "ktlint${capitalize()}${multiplatformTargetName?.capitalize() ?: ""}Format"

/**
* Get specific android variants from [BaseExtension].
*/
internal val BaseExtension.variants: DomainObjectSet<out BaseVariant>?
get() = when (this) {
is AppExtension -> applicationVariants
is LibraryExtension -> libraryVariants
is FeatureExtension -> featureVariants
is TestExtension -> applicationVariants
else -> null // Instant app extension doesn't provide variants access
}
internal fun Project.isConsolePlain() = gradle.startParameter.consoleOutput == ConsoleOutput.Plain
Loading

0 comments on commit 10509e9

Please sign in to comment.