Last active
July 18, 2020 21:55
-
-
Save realdadfish/52e6d79ffaf913ab6a87b1a321727a47 to your computer and use it in GitHub Desktop.
PMD CPD Kotlin Plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.android.build.gradle.BaseExtension | |
import com.android.build.gradle.api.BaseVariant | |
import com.android.build.gradle.internal.tasks.factory.dependsOn | |
import de.aaschmid.gradle.plugins.cpd.Cpd | |
import de.aaschmid.gradle.plugins.cpd.CpdExtension | |
import org.gradle.api.GradleException | |
import org.gradle.api.Plugin | |
import org.gradle.api.Project | |
import org.gradle.api.internal.HasConvention | |
import org.gradle.api.plugins.JavaPluginConvention | |
import org.gradle.api.tasks.SourceSet | |
import org.gradle.api.tasks.TaskProvider | |
import org.gradle.kotlin.dsl.apply | |
import org.gradle.kotlin.dsl.closureOf | |
import org.gradle.kotlin.dsl.configure | |
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet | |
class CpdPlugin : Plugin<Project> { | |
override fun apply(project: Project) { | |
project.configure(project, closureOf<Project> { | |
apply(plugin = "cpd") | |
configure<CpdExtension> { | |
language = "kotlin" | |
toolVersion = "6.25.0" | |
minimumTokenCount = 50 | |
} | |
registerTasks() | |
}) | |
} | |
private fun Project.registerTasks() { | |
project.plugins.withId("kotlin-android") { | |
// There is not a single Android plugin, but each registers an extension based on BaseExtension, | |
// so we catch them all by looking for this one | |
project.afterEvaluate { | |
val androidExtension = project.extensions.findByType(BaseExtension::class.java) | |
androidExtension?.let { | |
val mainTaskProvider = project.tasks.register("${CPD_CHECK_TASK}Main") { | |
group = "verification" | |
description = "Run CPD check for all production sources" | |
} | |
val testTaskProvider = project.tasks.register("${CPD_CHECK_TASK}Test") { | |
group = "verification" | |
description = "Run CPD check for all test sources" | |
} | |
androidExtension.variants?.forEach { variant -> | |
// register individual tasks and add those to the common tasks above | |
// to run all checks on all variants at once | |
project.registerAndroidCpdTask(variant).also { provider -> | |
mainTaskProvider.dependsOn(provider) | |
} | |
variant.testVariants.forEach { testVariant -> | |
project.registerAndroidCpdTask(testVariant).also { provider -> | |
testTaskProvider.dependsOn(provider) | |
} | |
} | |
} | |
project.dependOnQuickCheck() | |
} | |
} | |
} | |
// Kotlin JVM plugin | |
project.plugins.withId("org.jetbrains.kotlin.jvm") { | |
project.afterEvaluate { | |
project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.forEach { sourceSet -> | |
project.registerJvmCpdTask(sourceSet) | |
} | |
} | |
} | |
} | |
private fun Project.registerAndroidCpdTask(variant: BaseVariant): TaskProvider<Cpd> = | |
registerCpdTask(CPD_CHECK_TASK + variant.name.capitalize()) { | |
setSource(variant.sourceSets.map { it.javaDirectories }) | |
group = "verification" | |
description = "Run CPD check for variant ${variant.name}" | |
} | |
private fun Project.registerJvmCpdTask(sourceSet: SourceSet): TaskProvider<Cpd> { | |
val kotlinSourceSet = (sourceSet as HasConvention).convention.plugins["kotlin"] as? KotlinSourceSet | |
?: throw GradleException("Kotlin source set not found.") | |
return registerCpdTask(CPD_CHECK_TASK + sourceSet.name.capitalize()) { | |
setSource(kotlinSourceSet.kotlin.files) | |
group = "verification" | |
description = "Run CPD check for source set ${sourceSet.name}" | |
} | |
} | |
private fun Project.registerCpdTask( | |
name: String, | |
configuration: Cpd.() -> Unit | |
): TaskProvider<Cpd> = | |
tasks.register(name, Cpd::class.java) { | |
reports.text.isEnabled = true | |
reports.xml.isEnabled = true | |
configuration(this) | |
} | |
companion object { | |
private const val CPD_CHECK_TASK = "cpdCheck" | |
} | |
} | |
internal val BaseExtension.variants: DomainObjectSet<out BaseVariant>? | |
get() = when (this) { | |
is AppExtension -> applicationVariants | |
is LibraryExtension -> libraryVariants | |
is TestExtension -> applicationVariants | |
else -> null | |
} | |
internal val BaseVariant.testVariants: List<BaseVariant> | |
get() = if (this is TestedVariant) listOfNotNull(testVariant, unitTestVariant) | |
else emptyList() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment