Skip to content

Commit 17c8ace

Browse files
authored
Added extended reports filtering
The following report filtering features have been implemented: - include filter by classes annotated with specified annotations - include and exclude filters by classes that inherit the specified class or implement the specified interface Co-authored-by: Leonid Startsev <[email protected]> Resolves #274 Resolves #454 PR #581
1 parent 742d2ab commit 17c8ace

File tree

21 files changed

+649
-50
lines changed

21 files changed

+649
-50
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[versions]
22

3-
intellij-coverage = "1.0.752"
3+
intellij-coverage = "1.0.753"
44
junit = "5.9.0"
55
kotlinx-bcv = "0.13.2"
66
kotlinx-dokka = "1.8.10"

kover-cli/docs/index.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,22 @@ For information about offline instrumentation, [see](../offline-instrumentation#
2222
| --include <class-name> | instrument only specified classes, wildcards `*` and `?` are acceptable | | + |
2323

2424
### Generating reports
25+
2526
Allows you to generate HTML and XML reports from the existing binary report.
2627

2728
`java -jar kover-cli.jar report [<binary-report-path> ...] --classfiles <class-file-path> [--exclude <class-name>] [--excludeAnnotation <annotation-name>] [--html <html-dir>] [--include <class-name>] --src <sources-path> [--title <html-title>] [--xml <xml-file-path>]`
2829

29-
| Option | Description | Required | Multiple |
30-
|---------------------------------------|---------------------------------------------------------------------------------------------------------|:--------:|:--------:|
31-
| `<binary-report-path>` | list of binary reports files | | + |
32-
| --classfiles <class-file-path> | location of the compiled class-files root (must be original and not instrumented) | + | + |
33-
| --exclude <class-name> | filter to exclude classes, wildcards `*` and `?` are acceptable | | + |
34-
| --excludeAnnotation <annotation-name> | filter to exclude classes and functions marked by this annotation, wildcards `*` and `?` are acceptable | | + |
35-
| --html <html-dir> | generate a HTML report in the specified path | | |
36-
| --include <class-name> | filter to include classes, wildcards `*` and `?` are acceptable | | + |
37-
| --src <sources-path> | location of the source files root | + | + |
38-
| --title <html-title> | title in the HTML report | | |
39-
| --xml <xml-file-path> | generate a XML report in the specified path | | |
30+
| Option | Description | Required | Multiple |
31+
|------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|:--------:|:--------:|
32+
| `<binary-report-path>` | list of binary reports files | | + |
33+
| --classfiles <class-file-path> | location of the compiled class-files root (must be original and not instrumented) | + | + |
34+
| --exclude <class-name> | filter to exclude classes, wildcards `*` and `?` are acceptable | | + |
35+
| --include <class-name> | filter to include classes, wildcards `*` and `?` are acceptable | | + |
36+
| --excludeAnnotation <exclude-annotation-name> | filter to exclude classes and functions marked by this annotation, wildcards `*` and `?` are acceptable. Excludes have priority over includes | | + |
37+
| --includeAnnotation <include-annotation-name> | filter to include classes marked by this annotation, wildcards `*` and `?` are acceptable | | + |
38+
| --excludeInheritedFrom <exclude-ancestor-name> | filter to exclude classes extending the specified class or implementing an interface, wildcards `*` and `?` are acceptable | | + |
39+
| --includeInheritedFrom <include-ancestor-name> | filter to include only classes extending the specified class or implementing an interface, wildcards `*` and `?` are acceptable | | + |
40+
| --html <html-dir> | generate a HTML report in the specified path | | |
41+
| --src <sources-path> | location of the source files root | + | + |
42+
| --title <html-title> | title in the HTML report | | |
43+
| --xml <xml-file-path> | generate a XML report in the specified path | | |

kover-cli/src/main/kotlin/kotlinx/kover/cli/commands/OfflineInstrumentCommand.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ internal class OfflineInstrumentCommand : Command {
6565
val filters = ClassFilters(
6666
includeClasses.toSet(),
6767
excludeClasses.toSet(),
68-
excludeAnnotation.toSet()
68+
excludeAnnotation.toSet(),
69+
emptySet(),
70+
emptySet(),
71+
emptySet()
6972
)
7073

7174
try {

kover-cli/src/main/kotlin/kotlinx/kover/cli/commands/ReportCommand.kt

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,32 @@ internal class ReportCommand : Command {
6565

6666
@Option(
6767
name = "--excludeAnnotation",
68-
usage = "filter to exclude classes and functions marked by this annotation, wildcards `*` and `?` are acceptable",
69-
metaVar = "<annotation-name>"
68+
usage = "filter to exclude classes and functions marked by this annotation, wildcards `*` and `?` are acceptable. Excludes have priority over includes",
69+
metaVar = "<exclude-annotation-name>"
7070
)
7171
private var excludeAnnotation: MutableList<String> = ArrayList()
7272

73+
@Option(
74+
name = "--includeAnnotation",
75+
usage = "filter to include classes marked by this annotation, wildcards `*` and `?` are acceptable. Excludes have priority over includes.",
76+
metaVar = "<include-annotation-name>"
77+
)
78+
private var includeAnnotation: MutableList<String> = ArrayList()
79+
80+
@Option(
81+
name = "--excludeInheritedFrom",
82+
usage = "filter to exclude classes extending the specified class or implementing an interface, wildcards `*` and `?` are acceptable. Excludes have priority over includes",
83+
metaVar = "<exclude-ancestor-name>"
84+
)
85+
private var excludeInheritedFrom: MutableList<String> = ArrayList()
86+
87+
@Option(
88+
name = "--includeInheritedFrom",
89+
usage = "filter to include only classes extending the specified class or implementing an interface, wildcards `*` and `?` are acceptable. Excludes have priority over includes",
90+
metaVar = "<include-ancestor-name>"
91+
)
92+
private var includeInheritedFrom: MutableList<String> = ArrayList()
93+
7394
override val name: String = "report"
7495

7596
override val description: String = "Generates human-readable reports in various formats from binary report files"
@@ -79,7 +100,10 @@ internal class ReportCommand : Command {
79100
val filters = ClassFilters(
80101
includeClasses.toSet(),
81102
excludeClasses.toSet(),
82-
excludeAnnotation.toSet()
103+
includeAnnotation.toSet(),
104+
excludeAnnotation.toSet(),
105+
includeInheritedFrom.toSet(),
106+
excludeInheritedFrom.toSet()
83107
)
84108

85109
var fail = false

kover-features-jvm/api/kover-features-jvm.api

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,22 @@ public final class kotlinx/kover/features/jvm/BoundViolation {
4242
}
4343

4444
public final class kotlinx/kover/features/jvm/ClassFilters {
45-
public fun <init> (Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)V
45+
public fun <init> (Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)V
4646
public final fun component1 ()Ljava/util/Set;
4747
public final fun component2 ()Ljava/util/Set;
4848
public final fun component3 ()Ljava/util/Set;
49-
public final fun copy (Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)Lkotlinx/kover/features/jvm/ClassFilters;
50-
public static synthetic fun copy$default (Lkotlinx/kover/features/jvm/ClassFilters;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ILjava/lang/Object;)Lkotlinx/kover/features/jvm/ClassFilters;
49+
public final fun component4 ()Ljava/util/Set;
50+
public final fun component5 ()Ljava/util/Set;
51+
public final fun component6 ()Ljava/util/Set;
52+
public final fun copy (Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)Lkotlinx/kover/features/jvm/ClassFilters;
53+
public static synthetic fun copy$default (Lkotlinx/kover/features/jvm/ClassFilters;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ILjava/lang/Object;)Lkotlinx/kover/features/jvm/ClassFilters;
5154
public fun equals (Ljava/lang/Object;)Z
5255
public final fun getExcludeAnnotation ()Ljava/util/Set;
5356
public final fun getExcludeClasses ()Ljava/util/Set;
57+
public final fun getExcludeInheritedFrom ()Ljava/util/Set;
58+
public final fun getIncludeAnnotation ()Ljava/util/Set;
5459
public final fun getIncludeClasses ()Ljava/util/Set;
60+
public final fun getIncludeInheritedFrom ()Ljava/util/Set;
5561
public fun hashCode ()I
5662
public fun toString ()Ljava/lang/String;
5763
}

kover-features-jvm/src/main/java/kotlinx/kover/features/jvm/KoverLegacyFeatures.kt

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,56 @@ public data class ClassFilters(
198198
*/
199199
public val excludeClasses: Set<String>,
200200
/**
201-
* Classes that have at least one of the annotations specified in this field are not filtered.
201+
* Classes that have at least one of the annotations specified in this field are present in the report.
202+
* All other classes that are not marked with at least one of the specified annotations are not included in the report.
203+
*
204+
*
205+
* If inclusion and exclusion rules are specified at the same time, then excludes have priority over includes.
206+
* This means that even if a class is annotated with both annotations from 'exclude' and 'include', it will be excluded from the report.
207+
*
208+
*/
209+
public val includeAnnotation: Set<String>,
210+
/**
211+
* Classes that have at least one of the annotations specified in this field are not present in the report.
212+
*
213+
*
214+
* If inclusion and exclusion rules are specified at the same time, then excludes have priority over includes.
215+
* This means that even if a class is annotated with both annotations from 'exclude' and 'include', it will be excluded from the report.
216+
*
217+
*/
218+
public val excludeAnnotation: Set<String>,
219+
/**
220+
*
221+
* Include only classes extending at least one of the specified classes or implementing at least one of the interfaces.
222+
* The class itself with the specified name is not included in the report.
223+
*
224+
*
225+
* 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).
226+
*
227+
*
228+
* The following classes and interfaces can be specified in arguments:
229+
*
230+
* * classes and interfaces declared in the application
231+
* * classes and interfaces declared outside the application, if they are directly inherited or implemented by any type from the application
232+
*
233+
*
234+
* 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.
235+
*/
236+
public val includeInheritedFrom: Set<String>,
237+
/**
238+
*
239+
* Exclude classes extending at least one of the specified classes or implementing at least one of the interfaces.
240+
* The class itself with the specified name is not excluded from the report.
241+
*
242+
* 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).
243+
*
244+
* The following classes and interfaces can be specified in arguments:
245+
*
246+
* * classes and interfaces declared in the application
247+
* * classes and interfaces declared outside the application, however they are directly inherited or implemented by any type from the application
248+
*
249+
*
250+
* 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.
202251
*/
203-
public val excludeAnnotation: Set<String>
252+
public val excludeInheritedFrom: Set<String>
204253
)

kover-features-jvm/src/main/java/kotlinx/kover/features/jvm/impl/Wildcards.kt

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,17 @@ import java.util.regex.Pattern
1010

1111
internal fun ClassFilters.convert(): Filters {
1212
return Filters(
13-
convert(includeClasses),
14-
convert(excludeClasses),
15-
emptyList(),
16-
convert(excludeAnnotation),
17-
emptyList(),
18-
emptyList()
13+
includeClasses.toRegexp(),
14+
excludeClasses.toRegexp(),
15+
includeAnnotation.toRegexp(),
16+
excludeAnnotation.toRegexp(),
17+
includeInheritedFrom.toRegexp(),
18+
excludeInheritedFrom.toRegexp()
1919
)
2020
}
2121

22-
private fun convert(templates: Set<String>): List<Pattern> {
23-
val patterns = ArrayList<Pattern>(templates.size)
24-
for (template in templates) {
25-
patterns.add(Pattern.compile(template.wildcardsToRegex()))
26-
}
27-
return patterns
22+
private fun Collection<String>.toRegexp(): List<Pattern> {
23+
return map { template -> Pattern.compile(template.wildcardsToRegex()) }
2824
}
2925

3026
/**

kover-gradle-plugin/api/kover-gradle-plugin.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverReportFilte
173173
public abstract fun classes ([Ljava/lang/String;)V
174174
public abstract fun classes ([Lorg/gradle/api/provider/Provider;)V
175175
public abstract fun getProjects ()Lorg/gradle/api/provider/SetProperty;
176+
public abstract fun inheritedFrom ([Ljava/lang/String;)V
177+
public abstract fun inheritedFrom ([Lorg/gradle/api/provider/Provider;)V
176178
public abstract fun packages (Ljava/lang/Iterable;)V
177179
public abstract fun packages (Lorg/gradle/api/provider/Provider;)V
178180
public abstract fun packages ([Ljava/lang/String;)V

0 commit comments

Comments
 (0)