diff --git a/kover-gradle-plugin/api/kover-gradle-plugin.api b/kover-gradle-plugin/api/kover-gradle-plugin.api index ebeb8728..df2eaa65 100644 --- a/kover-gradle-plugin/api/kover-gradle-plugin.api +++ b/kover-gradle-plugin/api/kover-gradle-plugin.api @@ -44,6 +44,7 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverBinaryTaskC public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverCurrentProjectVariantsConfig : kotlinx/kover/gradle/plugin/dsl/KoverVariantConfig { public abstract fun copyVariant (Ljava/lang/String;Ljava/lang/String;)V public abstract fun createVariant (Ljava/lang/String;Lorg/gradle/api/Action;)V + public abstract fun getInstrumentation ()Lkotlinx/kover/gradle/plugin/dsl/KoverProjectInstrumentation; public abstract fun instrumentation (Lorg/gradle/api/Action;)V public abstract fun providedVariant (Ljava/lang/String;Lorg/gradle/api/Action;)V public abstract fun totalVariant (Lorg/gradle/api/Action;)V @@ -151,7 +152,10 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverProjectExte public fun excludeJavaCode ()V public fun excludeSourceSets (Lorg/gradle/api/Action;)V public fun excludeTests (Lorg/gradle/api/Action;)V + public abstract fun getCurrentProject ()Lkotlinx/kover/gradle/plugin/dsl/KoverCurrentProjectVariantsConfig; public abstract fun getJacocoVersion ()Lorg/gradle/api/provider/Property; + public abstract fun getMerge ()Lkotlinx/kover/gradle/plugin/dsl/KoverMergingConfig; + public abstract fun getReports ()Lkotlinx/kover/gradle/plugin/dsl/KoverReportsConfig; public abstract fun getUseJacoco ()Lorg/gradle/api/provider/Property; public abstract fun merge (Lorg/gradle/api/Action;)V public abstract fun reports (Lorg/gradle/api/Action;)V @@ -173,6 +177,9 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverReportFilte public abstract fun classes (Lorg/gradle/api/provider/Provider;)V public abstract fun classes ([Ljava/lang/String;)V public abstract fun classes ([Lorg/gradle/api/provider/Provider;)V + public abstract fun getAnnotatedBy ()Lorg/gradle/api/provider/SetProperty; + public abstract fun getClasses ()Lorg/gradle/api/provider/SetProperty; + public abstract fun getInheritedFrom ()Lorg/gradle/api/provider/SetProperty; public abstract fun getProjects ()Lorg/gradle/api/provider/SetProperty; public abstract fun inheritedFrom ([Ljava/lang/String;)V public abstract fun inheritedFrom ([Lorg/gradle/api/provider/Provider;)V @@ -184,6 +191,8 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverReportFilte public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverReportFiltersConfig { public abstract fun excludes (Lorg/gradle/api/Action;)V + public abstract fun getExcludes ()Lkotlinx/kover/gradle/plugin/dsl/KoverReportFilter; + public abstract fun getIncludes ()Lkotlinx/kover/gradle/plugin/dsl/KoverReportFilter; public abstract fun includes (Lorg/gradle/api/Action;)V } @@ -191,6 +200,12 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverReportSetCo public abstract fun binary (Lorg/gradle/api/Action;)V public abstract fun filters (Lorg/gradle/api/Action;)V public abstract fun filtersAppend (Lorg/gradle/api/Action;)V + public abstract fun getBinary ()Lkotlinx/kover/gradle/plugin/dsl/KoverBinaryTaskConfig; + public abstract fun getFilters ()Lkotlinx/kover/gradle/plugin/dsl/KoverReportFiltersConfig; + public abstract fun getHtml ()Lkotlinx/kover/gradle/plugin/dsl/KoverHtmlTaskConfig; + public abstract fun getLog ()Lkotlinx/kover/gradle/plugin/dsl/KoverLogTaskConfig; + public abstract fun getVerify ()Lkotlinx/kover/gradle/plugin/dsl/KoverVerifyTaskConfig; + public abstract fun getXml ()Lkotlinx/kover/gradle/plugin/dsl/KoverXmlTaskConfig; public abstract fun html (Lorg/gradle/api/Action;)V public abstract fun log (Lorg/gradle/api/Action;)V public fun mergeWith (Ljava/lang/String;)V @@ -203,6 +218,9 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverReportsConf public fun androidReports (Ljava/lang/String;Lorg/gradle/api/Action;)V public fun defaults (Lorg/gradle/api/Action;)V public abstract fun filters (Lorg/gradle/api/Action;)V + public abstract fun getFilters ()Lkotlinx/kover/gradle/plugin/dsl/KoverReportFiltersConfig; + public abstract fun getTotal ()Lkotlinx/kover/gradle/plugin/dsl/KoverReportSetConfig; + public abstract fun getVerify ()Lkotlinx/kover/gradle/plugin/dsl/KoverVerificationRulesConfig; public abstract fun total (Lorg/gradle/api/Action;)V public abstract fun variant (Ljava/lang/String;Lorg/gradle/api/Action;)V public abstract fun verify (Lorg/gradle/api/Action;)V @@ -214,6 +232,7 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverTestsExclus } public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverVariantConfig { + public abstract fun getSources ()Lkotlinx/kover/gradle/plugin/dsl/KoverVariantSources; public abstract fun sources (Lorg/gradle/api/Action;)V } diff --git a/kover-gradle-plugin/examples/android/multiproject/app/build.gradle.kts b/kover-gradle-plugin/examples/android/multiproject/app/build.gradle.kts index afbedb27..7b55c52c 100644 --- a/kover-gradle-plugin/examples/android/multiproject/app/build.gradle.kts +++ b/kover-gradle-plugin/examples/android/multiproject/app/build.gradle.kts @@ -56,29 +56,21 @@ dependencies { kover { reports { // filters for all report types of all build variants - filters { - excludes { - androidGeneratedClasses() - } - } + filters.excludes.androidGeneratedClasses() variant("release") { // verification only for 'release' build variant - verify { - rule { - minBound(50) - } + verify.rule { + minBound(50) } // filters for all report types only for 'release' build variant - filters { - excludes { - androidGeneratedClasses() - classes( - // excludes debug classes - "*.DebugUtil" - ) - } + filters.excludes { + androidGeneratedClasses() + classes( + // excludes debug classes + "*.DebugUtil" + ) } } diff --git a/kover-gradle-plugin/examples/android/variantUsage/app/build.gradle.kts b/kover-gradle-plugin/examples/android/variantUsage/app/build.gradle.kts index 704f6d06..38ecef6c 100644 --- a/kover-gradle-plugin/examples/android/variantUsage/app/build.gradle.kts +++ b/kover-gradle-plugin/examples/android/variantUsage/app/build.gradle.kts @@ -68,9 +68,7 @@ kover { reports { // filters for all report types of all build variants filters { - excludes { - androidGeneratedClasses() - } + excludes.androidGeneratedClasses() } variant("release") { diff --git a/kover-gradle-plugin/examples/jvm/merged/build.gradle.kts b/kover-gradle-plugin/examples/jvm/merged/build.gradle.kts index 076db869..1aa6b196 100644 --- a/kover-gradle-plugin/examples/jvm/merged/build.gradle.kts +++ b/kover-gradle-plugin/examples/jvm/merged/build.gradle.kts @@ -11,23 +11,17 @@ dependencies { kover(project(":subproject")) } -kover { - reports { - filters { - excludes { - classes("kotlinx.kover.examples.merged.utils.*", "kotlinx.kover.examples.merged.subproject.utils.*") - } - includes { - classes("kotlinx.kover.examples.merged.*") - } - } +kover.reports { + filters { + excludes.classes("kotlinx.kover.examples.merged.utils.*", "kotlinx.kover.examples.merged.subproject.utils.*") + includes.classes("kotlinx.kover.examples.merged.*") + } - verify { - rule { - bound { - minValue.set(50) - maxValue.set(75) - } + verify { + rule { + bound { + minValue.set(50) + maxValue.set(75) } } } diff --git a/kover-gradle-plugin/examples/jvm/single-kmp/build.gradle.kts b/kover-gradle-plugin/examples/jvm/single-kmp/build.gradle.kts index 7d5ff2f2..91c6f9ab 100644 --- a/kover-gradle-plugin/examples/jvm/single-kmp/build.gradle.kts +++ b/kover-gradle-plugin/examples/jvm/single-kmp/build.gradle.kts @@ -13,12 +13,6 @@ dependencies { commonTestImplementation(kotlin("test")) } -kover { - reports { - verify { - rule { - minBound(50) - } - } - } -} \ No newline at end of file +kover.reports.verify.rule { + minBound(50) +} diff --git a/kover-gradle-plugin/examples/jvm/single/build.gradle.kts b/kover-gradle-plugin/examples/jvm/single/build.gradle.kts index 96c0d512..afeb2465 100644 --- a/kover-gradle-plugin/examples/jvm/single/build.gradle.kts +++ b/kover-gradle-plugin/examples/jvm/single/build.gradle.kts @@ -7,12 +7,6 @@ dependencies { testImplementation(kotlin("test")) } -kover { - reports { - verify { - rule { - minBound(50) - } - } - } +kover.reports.verify.rule { + minBound(50) } \ No newline at end of file diff --git a/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/MergingTests.kt b/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/MergingTests.kt index be140a26..19451a94 100644 --- a/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/MergingTests.kt +++ b/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/MergingTests.kt @@ -61,6 +61,35 @@ internal class MergingTests { } } + @GeneratedTest + fun BuildConfigurator.testRootSubprojectsWithProperty() { + addProjectWithKover { + sourcesFrom("simple") + kover { + // merge with all subprojects + merge.subprojects() + } + } + addProjectWithKover(":one") { + sourcesFrom("one") + } + addProjectWithKover(":two") { + sourcesFrom("two") + } + + run(":koverXmlReport") { + checkOutcome(":koverGenerateArtifact", "SUCCESS") + checkOutcome(":one:koverGenerateArtifact", "SUCCESS") + checkOutcome(":two:koverGenerateArtifact", "SUCCESS") + + xmlReport { + classCounter("org.jetbrains.ExampleClass").assertCovered() + classCounter("org.jetbrains.one.OneClass").assertCovered() + classCounter("org.jetbrains.two.TwoClass").assertCovered() + } + } + } + @GeneratedTest fun BuildConfigurator.testRootSubprojectsByPath() { addProjectWithKover { diff --git a/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/ReportAnnotationFilterTests.kt b/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/ReportAnnotationFilterTests.kt index da4f7f20..5aa06ce9 100644 --- a/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/ReportAnnotationFilterTests.kt +++ b/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/ReportAnnotationFilterTests.kt @@ -51,9 +51,7 @@ internal class ReportAnnotationFilterTests { classes("*ByName") annotatedBy("org.jetbrains.Exclude") } - includes { - annotatedBy("*.Include") - } + includes.annotatedBy("*.Include") } } } diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/sourcesets-mpp/build.gradle.kts b/kover-gradle-plugin/src/functionalTest/templates/builds/sourcesets-mpp/build.gradle.kts index 013605c7..9ba7f2d6 100644 --- a/kover-gradle-plugin/src/functionalTest/templates/builds/sourcesets-mpp/build.gradle.kts +++ b/kover-gradle-plugin/src/functionalTest/templates/builds/sourcesets-mpp/build.gradle.kts @@ -3,13 +3,7 @@ plugins { id("org.jetbrains.kotlinx.kover") version "0.7.0" } -kover { - currentProject { - sources { - excludedSourceSets.add("extra") - } - } -} +kover.currentProject.sources.excludedSourceSets.add("extra") sourceSets.create("extra") diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/FinalizeKover.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/FinalizeKover.kt index 26431ed3..e6f5fd78 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/FinalizeKover.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/FinalizeKover.kt @@ -58,18 +58,25 @@ internal fun KoverContext.finalizing(origins: AllVariantOrigins) { jvmVariant?.let { variantArtifacts[JVM_VARIANT_NAME] = it } androidVariants.forEach { variantArtifacts[it.variantName] = it } + val availableVariants = variantArtifacts.keys + projectExtension.currentProject.customVariants.keys + projectExtension.reports.byName.forEach { (requestedVariant, _) -> + if (requestedVariant !in availableVariants) { + throw KoverIllegalConfigException("It is not possible to configure the '$requestedVariant' variant because it does not exist") + } + } + val totalVariant = TotalVariantArtifacts(project, toolProvider, koverBucketConfiguration, variantConfig(TOTAL_VARIANT_NAME), projectExtension) variantArtifacts.values.forEach { totalVariant.mergeWith(it) } totalReports.assign(totalVariant) - projectExtension.current.providedVariants.forEach { (name, _) -> + projectExtension.currentProject.providedVariants.forEach { (name, _) -> if (name !in variantArtifacts) { throw KoverIllegalConfigException("It is unacceptable to configure provided variant '$name', since there is no such variant in the project.\nAcceptable variants: ${variantArtifacts.keys}") } } - projectExtension.current.customVariants.forEach { (name, config) -> + projectExtension.currentProject.customVariants.forEach { (name, config) -> if (name == JVM_VARIANT_NAME) { throw KoverIllegalConfigException("It is unacceptable to create a custom reports variant '$JVM_VARIANT_NAME', because this name is reserved for JVM code") } @@ -108,7 +115,7 @@ internal fun KoverContext.finalizing(origins: AllVariantOrigins) { ).assign(customVariant) } - projectExtension.current.variantsToCopy.forEach { (name, originVariantName) -> + projectExtension.currentProject.variantsToCopy.forEach { (name, originVariantName) -> val originalVariant = variantArtifacts[originVariantName] ?: throw KoverIllegalConfigException("Cannot create a variant '$name': the original variant '$originVariantName' does not exist.") @@ -136,16 +143,16 @@ internal fun KoverContext.finalizing(origins: AllVariantOrigins) { } projectExtension.reports.byName.forEach { (requestedVariant, _) -> - if (requestedVariant !in variantArtifacts && requestedVariant !in projectExtension.current.variantsToCopy) { + if (requestedVariant !in variantArtifacts && requestedVariant !in projectExtension.currentProject.variantsToCopy) { throw KoverIllegalConfigException("It is not possible to configure the '$requestedVariant' variant because it does not exist") } } } private fun KoverContext.variantConfig(variantName: String): KoverVariantCreateConfigImpl { - return projectExtension.current.customVariants.getOrElse(variantName) { - val variantConfig = projectExtension.current.objects.newInstance(variantName) - variantConfig.deriveFrom(projectExtension.current) + return projectExtension.currentProject.customVariants.getOrElse(variantName) { + val variantConfig = projectExtension.currentProject.objects.newInstance(variantName) + variantConfig.deriveFrom(projectExtension.currentProject) variantConfig } } @@ -160,7 +167,7 @@ private fun JvmVariantOrigin.createVariant( koverContext: KoverContext, config: KoverVariantCreateConfigImpl, ): JvmVariantArtifacts { - tests.instrument(koverContext, koverContext.projectExtension.koverDisabled, koverContext.projectExtension.current) + tests.instrument(koverContext, koverContext.projectExtension.koverDisabled, koverContext.projectExtension.currentProject) return JvmVariantArtifacts( koverContext.project, koverContext.toolProvider, @@ -175,7 +182,7 @@ private fun AndroidVariantOrigin.createVariant( koverContext: KoverContext, config: KoverVariantCreateConfigImpl, ): AndroidVariantArtifacts { - tests.instrument(koverContext, koverContext.projectExtension.koverDisabled, koverContext.projectExtension.current) + tests.instrument(koverContext, koverContext.projectExtension.koverDisabled, koverContext.projectExtension.currentProject) return AndroidVariantArtifacts( koverContext.project, buildVariant.buildVariant, diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/KoverMerge.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/KoverMerge.kt index 067883ec..38f70ee0 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/KoverMerge.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/KoverMerge.kt @@ -15,7 +15,7 @@ import org.gradle.api.provider.SetProperty import org.gradle.api.specs.Spec internal fun KoverContext.prepareMerging() { - if (!projectExtension.isMerged) return + if (!projectExtension.merge.configured) return val projects = selectProjects() configSelectedProjects(projects) @@ -23,7 +23,7 @@ internal fun KoverContext.prepareMerging() { private fun KoverContext.selectProjects(): List { - val result = linkedMapOf(project.path to project) + val result = linkedMapOf(project.path to project) fun addProjectIfFiltered(project: Project, filters: List>) { if (result.containsKey(project.path)) return @@ -83,10 +83,10 @@ private fun KoverProjectExtensionImpl.configBeforeFinalize(targetProject: Projec targetExtension.jacocoVersion.set(jacocoVersion) } - merge.sourcesAction?.execute(targetExtension.current.sources.wrap(targetProject)) - merge.instrumentationAction?.execute(targetExtension.current.instrumentation.wrap(targetProject)) + merge.sourcesAction?.execute(targetExtension.currentProject.sources.wrap(targetProject)) + merge.instrumentationAction?.execute(targetExtension.currentProject.instrumentation.wrap(targetProject)) merge.variantsAction.forEach { (variantName, action) -> - targetExtension.current.createVariant(variantName) { + targetExtension.currentProject.createVariant(variantName) { action.execute(wrap(targetProject)) } } @@ -111,6 +111,7 @@ private fun KoverProjectInstrumentation.wrap(project: Project): KoverMergingInst } private fun KoverVariantCreateConfig.wrap(project: Project): KoverMergingVariantCreate { return object : KoverMergingVariantCreate { + override val sources: KoverVariantSources = this@wrap.sources override fun sources(block: Action) = this@wrap.sources(block) override fun add(vararg variantNames: String, optional: Boolean) = this@wrap.add(*variantNames, optional = optional) override fun addWithDependencies(vararg variantNames: String, optional: Boolean) = this@wrap.addWithDependencies(*variantNames, optional = optional) diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/artifacts/AbstractVariantArtifacts.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/artifacts/AbstractVariantArtifacts.kt index 8cc582d0..5c0e7589 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/artifacts/AbstractVariantArtifacts.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/artifacts/AbstractVariantArtifacts.kt @@ -68,8 +68,8 @@ internal sealed class AbstractVariantArtifacts( } protected fun fromOrigin(origin: VariantOrigin, compilationFilter: (String) -> Boolean = { true }) { - val excludedTasks = projectExtension.current.instrumentation.disabledForTestTasks - val disabledInstrumentation = projectExtension.current.instrumentation.disabledForAll + val excludedTasks = projectExtension.currentProject.instrumentation.disabledForTestTasks + val disabledInstrumentation = projectExtension.currentProject.instrumentation.disabledForAll val tests = origin.tests.matching { !disabledInstrumentation.get() diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/tasks/VariantReportsSet.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/tasks/VariantReportsSet.kt index 19f4ac87..75ff57c1 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/tasks/VariantReportsSet.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/appliers/tasks/VariantReportsSet.kt @@ -212,14 +212,14 @@ internal class VariantReportsSet( private fun KoverReportFiltersConfigImpl.convert(): Provider { return project.provider { ReportFilters( - includesImpl.classes.get(), - includesImpl.annotations.get(), - includesImpl.inheritedFrom.get(), - includesImpl.projects.get(), - excludesImpl.classes.get(), - excludesImpl.annotations.get(), - excludesImpl.inheritedFrom.get(), - excludesImpl.projects.get() + includes.classes.get(), + includes.annotatedBy.get(), + includes.inheritedFrom.get(), + includes.projects.get(), + excludes.classes.get(), + excludes.annotatedBy.get(), + excludes.inheritedFrom.get(), + excludes.projects.get() ) } } diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverProjectExtension.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverProjectExtension.kt index de87a638..6483f0cb 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverProjectExtension.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverProjectExtension.kt @@ -80,6 +80,13 @@ public interface KoverProjectExtension { */ public fun currentProject(block: Action) + /** + * Instance to configuring of report variants shared by the current project. + * + * See details in [currentProject]. + */ + public val currentProject: KoverCurrentProjectVariantsConfig + /** * Configuration of Kover reports. * @@ -120,6 +127,13 @@ public interface KoverProjectExtension { */ public fun reports(block: Action) + /** + * Instance to configuring of Kover reports. + * + * See details in [reports]. + */ + public val reports: KoverReportsConfig + /** * Configuring a merged report. * @@ -201,6 +215,13 @@ public interface KoverProjectExtension { */ public fun merge(block: Action) + /** + * Instance to configuring a merged report. + * + * See details in [merge]. + */ + public val merge: KoverMergingConfig + @Deprecated( message = "Function excludeJavaCode was removed, to exclude all Java sources write here `currentProject { sources { excludeJava = true } }` or `currentProject { sources { excludeJava.set(true) } } instead. Please refer to migration guide in order to migrate: ${KoverMigrations.MIGRATION_0_7_TO_0_8}", level = DeprecationLevel.ERROR diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverReportsConfig.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverReportsConfig.kt index ea774a30..a16375e8 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverReportsConfig.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverReportsConfig.kt @@ -91,6 +91,12 @@ public interface KoverReportsConfig { */ public fun filters(config: Action) + /** + * Instance to configuring of common filters for all report variants. + * + * See details in [filters]. + */ + public val filters: KoverReportFiltersConfig /** * Specify common verification rules for all report variants: JVM and Android build variants. @@ -112,6 +118,13 @@ public interface KoverReportsConfig { */ public fun verify(config: Action) + /** + * Instance to configuring of common verification rules for all report variants. + * + * See details in [verify]. + */ + public val verify: KoverVerificationRulesConfig + @Deprecated( message = "Default reports was removed, the concepts of total and custom reports are now used. Please refer to migration guide in order to migrate: ${KoverMigrations.MIGRATION_0_7_TO_0_8}", level = DeprecationLevel.ERROR @@ -156,6 +169,13 @@ public interface KoverReportsConfig { */ public fun total(config: Action) + /** + * Instance to configuring of reports for all code of current project and `kover` dependencies. + * + * See details in [total]. + */ + public val total: KoverReportSetConfig + /** * Configure reports for classes of specified named Kover report variant. * @@ -229,6 +249,13 @@ public interface KoverReportSetConfig { */ public fun filters(config: Action) + /** + * Instance to configuring of common report filters. + * + * See details in [filters]. + */ + public val filters: KoverReportFiltersConfig + /** * Specify common report filters, these filters will be inherited in HTML/XML/verification and other reports. * @@ -267,6 +294,13 @@ public interface KoverReportSetConfig { */ public fun html(config: Action) + /** + * Instance to configuring of HTML report for current report variant. + * + * See details in [html]. + */ + public val html: KoverHtmlTaskConfig + /** * Configure XML report for current report variant. * ``` @@ -284,6 +318,13 @@ public interface KoverReportSetConfig { */ public fun xml(config: Action) + /** + * Instance to configuring of XML report for current report variant. + * + * See details in [xml]. + */ + public val xml: KoverXmlTaskConfig + /** * Configure Kover binary report for current report variant. * ``` @@ -300,6 +341,13 @@ public interface KoverReportSetConfig { */ public fun binary(config: Action) + /** + * Instance to configuring of Kover binary report for current report variant. + * + * See details in [binary]. + */ + public val binary: KoverBinaryTaskConfig + /** * Configure coverage verification for current report variant. * @@ -325,6 +373,13 @@ public interface KoverReportSetConfig { */ public fun verify(config: Action) + /** + * Instance to configuring of coverage verification for current report variant. + * + * See details in [verify]. + */ + public val verify: KoverVerifyTaskConfig + /** * Configure coverage verification for current report variant. * @@ -366,6 +421,13 @@ public interface KoverReportSetConfig { */ public fun log(config: Action) + /** + * Instance to configuring of coverage printing to the log for current report variant. + * + * See details in [log]. + */ + public val log: KoverLogTaskConfig + @Deprecated( message = "Block mergeWith was removed, create custom reports variant and merge with specified variant. Please refer to migration guide in order to migrate: ${KoverMigrations.MIGRATION_0_7_TO_0_8}", level = DeprecationLevel.ERROR @@ -475,6 +537,13 @@ public interface KoverReportFiltersConfig { */ public fun excludes(config: Action) + /** + * Instance to configuring of class filter in order to exclude classes and functions. + * + * See details in [excludes]. + */ + public val excludes: KoverReportFilter + /** * Configures class filter in order to include classes. * @@ -490,6 +559,13 @@ public interface KoverReportFiltersConfig { * Excludes have priority over includes. */ public fun includes(config: Action) + + /** + * Instance to configuring of class filter in order to include classes. + * + * See details in [includes]. + */ + public val includes: KoverReportFilter } /** @@ -579,6 +655,19 @@ public interface KoverReportFilter { */ public fun classes(names: Provider>) + /** + * Classes of current filter. + * + * It is acceptable to use `*` and `?` wildcards, + * `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character. + * + * Example: + * ``` + * classes.addAll("*.foo.Bar", "*.M?Class") + * ``` + */ + public val classes: SetProperty + /** * Add all classes in specified package and its subpackages to current filters. * @@ -689,6 +778,25 @@ public interface KoverReportFilter { */ public fun annotatedBy(vararg annotationName: Provider) + /** + * Filters for classes and functions marked by specified annotations. + * + * Use cases: + * - in case of exclusion filters all classes or function marked by at least one of the specified annotation will be excluded from the report + * - in case of inclusion filters only classes marked by at least one of the specified annotations will be included in the report + * + * It is acceptable to use `*` and `?` wildcards, + * `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character. + * + * **_Does not work for JaCoCo_** + * + * Example: + * ``` + * annotatedBy.addAll("*Generated*", "com.example.KoverExclude") + * ``` + */ + public val annotatedBy: SetProperty + /** * Add all classes in specified project. Only the project path is used (starts with a colon). * @@ -756,6 +864,32 @@ public interface KoverReportFilter { */ public fun inheritedFrom(vararg typeName: Provider) + /** + * Filter classes extending at least one of the specified classes or implementing at least one of the interfaces. + * The class itself with the specified name is not taken into account. + * + * The entire inheritance tree is analyzed; a class may inherit the specified class/interface indirectly and still be included in the report, unless the specified class/interface is located outside of the application (see below). + * + * The following classes and interfaces can be specified in arguments: + * - classes and interfaces declared in the application + * - classes and interfaces declared outside the application, however they are directly inherited or implemented by any type from the application + * + * Due to technical limitations, if a specified class or interface is not declared in the application and not extended/implemented directly by one of the application types, such a filter will have no effect. + * + * If this filter is specified, then the generation of the report may slow down, because it becomes necessary to analyze the inheritance tree. + * + * It is acceptable to use `*` and `?` wildcards, + * `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character. + * + * **_Does not work for JaCoCo_** + * + * Example: + * ``` + * inheritedFrom.add("*Repository") + * ``` + */ + public val inheritedFrom: SetProperty + /** * Add all classes generated by Android plugin to filters. * diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverVariantConfig.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverVariantConfig.kt index db0d0139..f8cbcc14 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverVariantConfig.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/KoverVariantConfig.kt @@ -6,6 +6,7 @@ package kotlinx.kover.gradle.plugin.dsl import kotlinx.kover.gradle.plugin.commons.KoverIllegalConfigException import org.gradle.api.Action +import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.provider.Property import org.gradle.api.provider.SetProperty @@ -95,6 +96,13 @@ public interface KoverCurrentProjectVariantsConfig: KoverVariantConfig { * ``` */ public fun instrumentation(block: Action) + + /** + * Instance to configuring of instrumentation for the current Gradle project. + * + * See details in [instrumentation]. + */ + public val instrumentation: KoverProjectInstrumentation } /** @@ -120,6 +128,13 @@ public interface KoverVariantConfig { * ``` */ public fun sources(block: Action) + + /** + * Instance to limit the classes that will be included in the reports. + * + * See details in [sources]. + */ + public val sources: KoverVariantSources } /** diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/KoverProjectExtensionImpl.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/KoverProjectExtensionImpl.kt index 073bdfbd..f7c0cb54 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/KoverProjectExtensionImpl.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/KoverProjectExtensionImpl.kt @@ -4,8 +4,10 @@ package kotlinx.kover.gradle.plugin.dsl.internal -import kotlinx.kover.gradle.plugin.commons.KoverIllegalConfigException -import kotlinx.kover.gradle.plugin.dsl.* +import kotlinx.kover.gradle.plugin.dsl.KoverCurrentProjectVariantsConfig +import kotlinx.kover.gradle.plugin.dsl.KoverMergingConfig +import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension +import kotlinx.kover.gradle.plugin.dsl.KoverReportsConfig import kotlinx.kover.gradle.plugin.dsl.KoverVersions.JACOCO_TOOL_DEFAULT_VERSION import org.gradle.api.Action import org.gradle.api.file.ProjectLayout @@ -20,13 +22,13 @@ internal abstract class KoverProjectExtensionImpl @Inject constructor( layout: ProjectLayout, projectPath: String ): KoverProjectExtension { - internal val current: KoverCurrentProjectVariantsConfigImpl = objects.newInstance() - internal val reports: KoverReportsConfigImpl = objects.newInstance(objects, layout, projectPath) - internal val merge: KoverMergingConfigImpl = objects.newInstance() internal abstract val koverDisabled: Property - internal var isMerged: Boolean = false internal val finalizeActions: MutableList<() -> Unit> = mutableListOf() + override val reports: KoverReportsConfigImpl = objects.newInstance(objects, layout, projectPath) + override val merge: KoverMergingConfigImpl = objects.newInstance() + override val currentProject: KoverCurrentProjectVariantsConfigImpl = objects.newInstance() + init { @Suppress("LeakingThis") useJacoco.convention(false) @@ -50,7 +52,7 @@ internal abstract class KoverProjectExtensionImpl @Inject constructor( } override fun currentProject(block: Action) { - block.execute(current) + block.execute(currentProject) } override fun reports(block: Action) { @@ -58,11 +60,9 @@ internal abstract class KoverProjectExtensionImpl @Inject constructor( } override fun merge(block: Action) { - if (isMerged) { - throw KoverIllegalConfigException("An attempt to re-invoke the 'merge' block. Only one merging config is allowed") - } - isMerged = true block.execute(merge) + + merge.configured = true } internal fun beforeFinalize(action: () -> Unit) { diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/MergeImpl.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/MergeImpl.kt index 5b07b319..82846a5a 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/MergeImpl.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/MergeImpl.kt @@ -17,25 +17,31 @@ internal abstract class KoverMergingConfigImpl: KoverMergingConfig { internal var instrumentationAction: Action? = null internal val variantsAction: MutableMap> = mutableMapOf() + internal var configured: Boolean = false override fun subprojects() { subprojectsFilters += Spec { true } + configured = true } override fun subprojects(filter: Spec) { subprojectsFilters += filter + configured = true } override fun allProjects() { allProjectsFilters += Spec { true } + configured = true } override fun allProjects(filter: Spec) { allProjectsFilters += filter + configured = true } override fun projects(vararg projectNameOrPath: String) { allProjectsFilters += Spec { project -> project.name in projectNameOrPath || project.path in projectNameOrPath } + configured = true } override fun sources(config: Action) { @@ -43,6 +49,7 @@ internal abstract class KoverMergingConfigImpl: KoverMergingConfig { throw KoverIllegalConfigException("An attempt to re-invoke the 'sources' block in merging config. Only one usage is allowed") } sourcesAction = config + configured = true } override fun instrumentation(config: Action) { @@ -50,6 +57,7 @@ internal abstract class KoverMergingConfigImpl: KoverMergingConfig { throw KoverIllegalConfigException("An attempt to re-invoke the 'instrumentation' block in merging config. Only one usage is allowed") } instrumentationAction = config + configured = true } override fun createVariant(variantName: String, config: Action) { @@ -57,6 +65,7 @@ internal abstract class KoverMergingConfigImpl: KoverMergingConfig { if (prev != null) { throw KoverIllegalConfigException("Variant '$variantName' has already been added in merging config. Re-creating a variant with the same name is not allowed") } + configured = true } } diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/ReportsImpl.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/ReportsImpl.kt index 61848d9a..b45072aa 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/ReportsImpl.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/ReportsImpl.kt @@ -23,19 +23,18 @@ internal abstract class KoverReportsConfigImpl @Inject constructor( private val layout: ProjectLayout, private val projectPath: String ) : KoverReportsConfig { - private val rootFilters: KoverReportFiltersConfigImpl = objects.newInstance() - private val rootVerify: KoverVerificationRulesConfigImpl = objects.newInstance() - - internal val total: KoverReportSetConfigImpl = createReportSet(TOTAL_VARIANT_NAME, projectPath) + override val filters: KoverReportFiltersConfigImpl = objects.newInstance() + override val verify: KoverVerificationRulesConfigImpl = objects.newInstance() + override val total: KoverReportSetConfigImpl = createReportSet(TOTAL_VARIANT_NAME, projectPath) internal val byName: MutableMap = mutableMapOf() override fun filters(config: Action) { - rootFilters.also { config(it) } + filters.also { config(it) } } override fun verify(config: Action) { - rootVerify.also { config(it) } + verify.also { config(it) } } override fun total(config: Action) { @@ -53,8 +52,8 @@ internal abstract class KoverReportsConfigImpl @Inject constructor( val block = objects.newInstance(objects, layout.buildDirectory, variantName, projectPath) - block.filters.extendsFrom(rootFilters) - block.verify.extendFrom(rootVerify) + block.filters.extendsFrom(filters) + block.verify.extendFrom(verify) return block } @@ -66,13 +65,13 @@ internal abstract class KoverReportSetConfigImpl @Inject constructor( variantName: String, projectPath: String ) : KoverReportSetConfig { - internal val filters: KoverReportFiltersConfigImpl = objects.newInstance() - internal val verify: KoverVerifyTaskConfigImpl = objects.newInstance() + override val filters: KoverReportFiltersConfigImpl = objects.newInstance() + override val verify: KoverVerifyTaskConfigImpl = objects.newInstance() - internal val html: KoverHtmlTaskConfig = objects.newInstance() - internal val xml: KoverXmlTaskConfig = objects.newInstance() - internal val binary: KoverBinaryTaskConfig = objects.newInstance() - internal val log: KoverLogTaskConfig = objects.newInstance() + override val html: KoverHtmlTaskConfig = objects.newInstance() + override val xml: KoverXmlTaskConfig = objects.newInstance() + override val binary: KoverBinaryTaskConfig = objects.newInstance() + override val log: KoverLogTaskConfig = objects.newInstance() init { xml.xmlFile.convention(buildDir.file(xmlReportPath(variantName))) @@ -244,33 +243,33 @@ internal abstract class KoverVerifyRuleImpl @Inject constructor(private val obje internal open class KoverReportFiltersConfigImpl @Inject constructor( objects: ObjectFactory ) : KoverReportFiltersConfig { - internal val excludesImpl: KoverReportFilterImpl = objects.newInstance() - internal val includesImpl: KoverReportFilterImpl = objects.newInstance() + override val excludes: KoverReportFilterImpl = objects.newInstance() + override val includes: KoverReportFilterImpl = objects.newInstance() override fun excludes(config: Action) { - config(excludesImpl) + config(excludes) } override fun includes(config: Action) { - config(includesImpl) + config(includes) } internal fun clean() { - excludesImpl.clean() - includesImpl.clean() + excludes.clean() + includes.clean() } internal fun extendsFrom(other: KoverReportFiltersConfigImpl) { - excludesImpl.extendsFrom(other.excludesImpl) - includesImpl.extendsFrom(other.includesImpl) + excludes.extendsFrom(other.excludes) + includes.extendsFrom(other.includes) } } internal abstract class KoverReportFilterImpl: KoverReportFilter { - internal abstract val classes: SetProperty - internal abstract val annotations: SetProperty - internal abstract val inheritedFrom: SetProperty + abstract override val classes: SetProperty + abstract override val annotatedBy: SetProperty + abstract override val inheritedFrom: SetProperty override fun classes(vararg names: String) { classes.addAll(*names) @@ -315,12 +314,12 @@ internal abstract class KoverReportFilterImpl: KoverReportFilter { } override fun annotatedBy(vararg annotationName: String) { - annotations.addAll(*annotationName) + annotatedBy.addAll(*annotationName) } override fun annotatedBy(vararg annotationName: Provider) { annotationName.forEach { nameProvider -> - annotations.add(nameProvider) + annotatedBy.add(nameProvider) } } override fun inheritedFrom(vararg typeName: String) { @@ -335,14 +334,14 @@ internal abstract class KoverReportFilterImpl: KoverReportFilter { internal fun extendsFrom(other: KoverReportFilterImpl) { classes.addAll(other.classes) - annotations.addAll(other.annotations) + annotatedBy.addAll(other.annotatedBy) projects.addAll(other.projects) inheritedFrom.addAll(other.inheritedFrom) } internal fun clean() { classes.empty() - annotations.empty() + annotatedBy.empty() inheritedFrom.empty() projects.empty() } diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/VariantsImpl.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/VariantsImpl.kt index e4a9bae1..842d4c91 100644 --- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/VariantsImpl.kt +++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/dsl/internal/VariantsImpl.kt @@ -17,7 +17,8 @@ internal abstract class KoverCurrentProjectVariantsConfigImpl @Inject constructo internal val customVariants: MutableMap = mutableMapOf() internal val providedVariants: MutableMap = mutableMapOf() internal val variantsToCopy: MutableMap = mutableMapOf() - internal val instrumentation: KoverProjectInstrumentation = objects.newInstance() + + final override val instrumentation: KoverProjectInstrumentation = objects.newInstance() init { sources.excludeJava.convention(false) @@ -80,7 +81,7 @@ internal abstract class KoverCurrentProjectVariantsConfigImpl @Inject constructo } internal abstract class KoverVariantConfigImpl @Inject constructor(objects: ObjectFactory) : KoverVariantConfig { - internal val sources: KoverVariantSources = objects.newInstance() + override val sources: KoverVariantSources = objects.newInstance() override fun sources(block: Action) { block.execute(sources)