From 1c02f7a76e84bfb175b8aa18bf19dec4f776b756 Mon Sep 17 00:00:00 2001 From: Sergii Gnatiuk Date: Sun, 22 Mar 2026 01:18:18 +0200 Subject: [PATCH 1/2] Add entityCountThreshold to skip violations on small diffs Add `entityCountThreshold` parameter to `` configuration. When the number of changed entities (instructions, lines, or branches) is below the threshold, the coverage check for that entity is skipped. Useful to avoid build failures on PRs with few changed lines. Closes #40 Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 5 ++ README.md | 10 ++- .../diffFile.patch | 14 ++++ src/it/violation-rule-threshold-check/pom.xml | 71 +++++++++++++++++++ .../src/main/java/com/test/Example.java | 14 ++++ .../src/test/java/com/test/ExampleTest.java | 11 +++ .../violation-rule-threshold-check/verify.bsh | 9 +++ .../surpsg/DiffCoverageConfiguration.kt | 4 +- .../io/github/surpsg/DiffCoverageMojo.kt | 12 +++- 9 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 src/it/violation-rule-threshold-check/diffFile.patch create mode 100644 src/it/violation-rule-threshold-check/pom.xml create mode 100644 src/it/violation-rule-threshold-check/src/main/java/com/test/Example.java create mode 100644 src/it/violation-rule-threshold-check/src/test/java/com/test/ExampleTest.java create mode 100644 src/it/violation-rule-threshold-check/verify.bsh diff --git a/CHANGELOG.md b/CHANGELOG.md index 71b8be3..624666c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Diff-Coverage Maven plugin +## 1.2.0 + +### Added +- `entityCountThreshold` parameter in `violations` configuration: if the number of changed entities is below the threshold, the coverage check for that entity is skipped + ## 1.1.0 - Added Java 25 class files support diff --git a/README.md b/README.md index edff23b..60dcfe6 100644 --- a/README.md +++ b/README.md @@ -43,18 +43,24 @@ The plugin does the next steps: - + true 0.7 - + 0.1 0.7 1.0 + + + 20 diff --git a/src/it/violation-rule-threshold-check/diffFile.patch b/src/it/violation-rule-threshold-check/diffFile.patch new file mode 100644 index 0000000..1119d91 --- /dev/null +++ b/src/it/violation-rule-threshold-check/diffFile.patch @@ -0,0 +1,14 @@ +=================================================================== +--- a/src/main/java/com/test/Example.java (revision 9e78667391946d3461759f5589b67d3a676d8ce7) ++++ b/src/main/java/com/test/Example.java (date 1593433398791) +@@ -5,7 +5,10 @@ + public void sayHello(boolean a) { + if (a) { + System.out.println("if"); ++ } else { ++ System.out.println("else"); + } ++ System.out.println("return"); + } + + } diff --git a/src/it/violation-rule-threshold-check/pom.xml b/src/it/violation-rule-threshold-check/pom.xml new file mode 100644 index 0000000..05066d3 --- /dev/null +++ b/src/it/violation-rule-threshold-check/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + jacoco + it-threshold-check-passes + 1.0-SNAPSHOT + + + 1.8 + 1.8 + + + + + junit + junit + 4.13.2 + test + + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.14 + + + + prepare-agent + + + + + + io.github.surpsg + diff-coverage-maven-plugin + + + + diffFile.patch + + + + true + 1.0 + 20 + + + + + console + false + + + + + + + + diffCoverage + + + + + + + diff --git a/src/it/violation-rule-threshold-check/src/main/java/com/test/Example.java b/src/it/violation-rule-threshold-check/src/main/java/com/test/Example.java new file mode 100644 index 0000000..439c90a --- /dev/null +++ b/src/it/violation-rule-threshold-check/src/main/java/com/test/Example.java @@ -0,0 +1,14 @@ +package com.test; + +public class Example { + + public void sayHello(boolean a) { + if (a) { + System.out.println("if"); + } else { + System.out.println("else"); + } + System.out.println("return"); + } + +} diff --git a/src/it/violation-rule-threshold-check/src/test/java/com/test/ExampleTest.java b/src/it/violation-rule-threshold-check/src/test/java/com/test/ExampleTest.java new file mode 100644 index 0000000..d64cc3c --- /dev/null +++ b/src/it/violation-rule-threshold-check/src/test/java/com/test/ExampleTest.java @@ -0,0 +1,11 @@ +package com.test; +import org.junit.Test; + +public class ExampleTest { + + @Test + public void test() { + new Example().sayHello(true); + } + +} diff --git a/src/it/violation-rule-threshold-check/verify.bsh b/src/it/violation-rule-threshold-check/verify.bsh new file mode 100644 index 0000000..3847cc1 --- /dev/null +++ b/src/it/violation-rule-threshold-check/verify.bsh @@ -0,0 +1,9 @@ +import java.io.*; +import org.codehaus.plexus.util.*; + +String expectedIgnoredMsg = "was ignored because threshold=20"; + +String buildLog = FileUtils.fileRead( new File( basedir, "build.log" ) ); +if ( !buildLog.contains( expectedIgnoredMsg ) ) { + throw new RuntimeException( "Expected coverage violations to be ignored due to entityCountThreshold, but message not found: " + expectedIgnoredMsg ); +} diff --git a/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt b/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt index 930fb72..5379e66 100644 --- a/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt +++ b/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt @@ -19,7 +19,9 @@ class ViolationsConfiguration( var minBranches: Double = 0.0, var minInstructions: Double = 0.0, - var minCoverage: Double = MIN_COVERAGE_PROPERTY_DEFAULT + var minCoverage: Double = MIN_COVERAGE_PROPERTY_DEFAULT, + + var entityCountThreshold: Int = 0 ) class Report( diff --git a/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt b/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt index 92f3ecd..7215389 100644 --- a/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt +++ b/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt @@ -114,7 +114,11 @@ class DiffCoverageMojo : AbstractMojo() { failOnViolation = violations.failOnViolation violationRules += if (isMinCoverageSet) { CoverageEntity.entries.map { entity -> - ViolationRule { coverageEntity = entity; minCoverageRatio = violations.minCoverage } + ViolationRule { + coverageEntity = entity + minCoverageRatio = violations.minCoverage + entityCountThreshold = violations.entityCountThreshold.takeIf { it > 0 } + } } } else { buildCoverageRules() @@ -139,7 +143,11 @@ class DiffCoverageMojo : AbstractMojo() { ) .filter { it.second > 0.0 } .map { (entity, value) -> - ViolationRule { coverageEntity = entity; minCoverageRatio = value } + ViolationRule { + coverageEntity = entity + minCoverageRatio = value + entityCountThreshold = violations.entityCountThreshold.takeIf { it > 0 } + } } .toSet() From 59d0055c30c135f768ba2dbb9510543dd1b95d7e Mon Sep 17 00:00:00 2001 From: Sergii Gnatiuk Date: Sun, 22 Mar 2026 01:38:26 +0200 Subject: [PATCH 2/2] fix --- .../kotlin/io/github/surpsg/DiffCoverageConfiguration.kt | 5 ++++- src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt b/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt index 5379e66..3cb0d5d 100644 --- a/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt +++ b/src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt @@ -22,7 +22,10 @@ class ViolationsConfiguration( var minCoverage: Double = MIN_COVERAGE_PROPERTY_DEFAULT, var entityCountThreshold: Int = 0 -) +) { + val entityCountThresholdOrNull: Int? + get() = entityCountThreshold.takeIf { it > 0 } +} class Report( var type: String? = null, diff --git a/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt b/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt index 7215389..8c2dffa 100644 --- a/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt +++ b/src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt @@ -117,7 +117,7 @@ class DiffCoverageMojo : AbstractMojo() { ViolationRule { coverageEntity = entity minCoverageRatio = violations.minCoverage - entityCountThreshold = violations.entityCountThreshold.takeIf { it > 0 } + entityCountThreshold = violations.entityCountThresholdOrNull } } } else { @@ -146,7 +146,7 @@ class DiffCoverageMojo : AbstractMojo() { ViolationRule { coverageEntity = entity minCoverageRatio = value - entityCountThreshold = violations.entityCountThreshold.takeIf { it > 0 } + entityCountThreshold = violations.entityCountThresholdOrNull } } .toSet()