├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs └── how-to.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── renovate.json ├── settings.xml └── src ├── it ├── exclude-classes │ ├── diffFile.patch │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ ├── exclude │ │ │ │ ├── ExcludeMe.java │ │ │ │ └── ExcludeMe2.java │ │ │ │ └── include │ │ │ │ └── Example.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── include │ │ │ └── ExampleTest.java │ └── verify.bsh ├── excluded-all-classes │ ├── diffFile.patch │ ├── invoker.properties │ ├── pom.xml │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── include │ │ │ └── Example.java │ └── verify.bsh ├── fail-on-duplicated-coverage-config-check │ ├── diffFile.patch │ ├── invoker.properties │ ├── pom.xml │ └── verify.bsh ├── git-diff-support │ ├── .gitignore │ ├── pom.xml │ ├── setup.bsh │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ ├── Example.java │ │ │ │ └── Example.new │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── ExampleTest.java │ └── verify.bsh ├── include-classes │ ├── diffFile.patch │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ ├── exclude │ │ │ │ └── ExcludeMe.java │ │ │ │ └── include │ │ │ │ └── Example.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── include │ │ │ └── ExampleTest.java │ └── verify.bsh ├── include-exclude-classes │ ├── diffFile.patch │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ ├── exclude │ │ │ │ ├── ExcludeMe.java │ │ │ │ └── ExcludeMe2.java │ │ │ │ └── include │ │ │ │ └── Example.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── include │ │ │ └── ExampleTest.java │ └── verify.bsh ├── multi-module-reports-exclusions-check │ ├── moduleA │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ └── moduleA │ │ │ │ └── ClassA.java │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── moduleA │ │ │ └── ClassATest.java │ ├── moduleB │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ └── moduleB │ │ │ │ └── ClassB.java │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── moduleB │ │ │ └── ClassBTest.java │ ├── pom.xml │ ├── report │ │ ├── diffFile.patch │ │ └── pom.xml │ └── verify.bsh ├── multi-module-reports-generation-check │ ├── moduleA │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ └── moduleA │ │ │ │ └── ClassModuleA.java │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── moduleA │ │ │ └── ClassModuleATest.java │ ├── moduleB │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ └── moduleB │ │ │ │ └── ClassModuleB.java │ │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── moduleB │ │ │ └── ClassModuleBTest.java │ ├── pom.xml │ ├── report │ │ ├── diffFile.patch │ │ └── pom.xml │ └── verify.bsh ├── reports-generation-check │ ├── diffFile.patch │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ └── Example.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── ExampleTest.java │ └── verify.bsh ├── settings.xml ├── url-source-check │ ├── diffFile.patch │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── test │ │ │ │ └── Example.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── ExampleTest.java │ └── verify.bsh └── violation-rules-check │ ├── diffFile.patch │ ├── invoker.properties │ ├── pom.xml │ ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── test │ │ │ └── Example.java │ └── test │ │ └── java │ │ └── com │ │ └── test │ │ └── ExampleTest.java │ └── verify.bsh └── main └── kotlin └── io └── github └── surpsg ├── DiffCoverageConfiguration.kt ├── DiffCoverageMojo.kt └── ReportsMapper.kt /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | push: 9 | branches: [main] 10 | pull_request: 11 | 12 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 13 | jobs: 14 | # This workflow contains a single job called "build" 15 | build: 16 | # The type of runner that the job will run on 17 | runs-on: ubuntu-latest 18 | 19 | # Steps represent a sequence of tasks that will be executed as part of the job 20 | steps: 21 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 22 | - uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: Set up JDK 27 | uses: actions/setup-java@v4 28 | with: 29 | distribution: temurin 30 | java-version: 17 31 | cache: maven 32 | 33 | - name: Build with Maven 34 | run: ./mvnw clean install --file pom.xml -Ddiff.source="refs/remotes/origin/$GITHUB_BASE_REF" -e 35 | 36 | - name: Expose Integration tests build logs 37 | uses: actions/upload-artifact@master 38 | if: always() 39 | with: 40 | name: int-tests-artifacts 41 | path: | 42 | target/it/*/build.log 43 | target/it/*/target/site 44 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Release 4 | on: 5 | release: 6 | types: [prereleased, released] 7 | 8 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 9 | jobs: 10 | # This workflow contains a single job called "build" 11 | release: 12 | # The type of runner that the job will run on 13 | runs-on: ubuntu-latest 14 | 15 | # Steps represent a sequence of tasks that will be executed as part of the job 16 | steps: 17 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 18 | - uses: actions/checkout@v4 19 | with: 20 | fetch-depth: 0 21 | 22 | - name: Set up JDK 23 | uses: actions/setup-java@v4 24 | with: 25 | distribution: 'adopt' 26 | java-version: '11' 27 | cache: 'maven' 28 | 29 | - name: Build with Maven 30 | run: mvn install --file pom.xml -e 31 | 32 | - name: Upload coverage to Codecov 33 | uses: codecov/codecov-action@v5 34 | with: 35 | token: ${{ secrets.CODECOV_TOKEN }} 36 | file: target/site/jacoco-fullCoverage/jacoco.xml 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | *.diff 26 | *.patch 27 | 28 | target/ 29 | build/ 30 | out/ 31 | .idea/ 32 | *.iml 33 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SurpSG/diff-coverage-maven-plugin/5b25f018ec0ec1399fafd13000afdee8e7bf18d0/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Diff-Coverage Maven plugin 2 | 3 | ## 1.0.0 4 | 5 | - Changed group id from `com.github.surpsg` to `io.github.surpsg` 6 | - Min supported Java version is 17 7 | - Migrated to [Delta Coverage engine](https://github.com/gw-kit/delta-coverage-plugin) 8 | - Changed reports output paths: 9 | - HTML `target/site/delta-coverage/aggregated/html` 10 | - XML `target/site/delta-coverage/aggregated/report.xml` 11 | - Added Markdown report available in `target/site/delta-coverage/aggregated/report.md` 12 | - CSV reports is not generated anymore 13 | 14 | ## 0.3.3 15 | 16 | ### Fixes 17 | - Update JaCoCo to be able to use Java 21 18 | 19 | ### Dependencies updates 20 | - JaCoCo 0.8.10 21 | - Updated maven dependency to 3.9.4 22 | - Updated maven wrapper to 3.9.4 23 | - Updated maven plugin tools to 3.9.0 24 | 25 | 26 | ## 0.3.2 27 | 28 | - Support Maven v3.9 29 | 30 | 31 | ## 0.3.1 32 | 33 | ### Fixes 34 | - Fixed build failure when include/exclude is used and subproject doesn't have classes directory #28 35 | 36 | 37 | ## 0.3.0 38 | 39 | ### Added 40 | - The plugin supports exclude/include classes 41 | 42 | ### Dependencies updates 43 | - jacoco-filtering-extension 0.9.5 44 | - JaCoCo 0.8.8 45 | - JGit 6.2.0.202206071550-r 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sergii Gnatiuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # diff-coverage-maven-plugin 2 | 3 | [![Release](https://github.com/SurpSG/diff-coverage-maven-plugin/actions/workflows/release.yml/badge.svg)](https://github.com/SurpSG/diff-coverage-maven-plugin/actions/workflows/release.yml) 4 | [![Maven Central](https://img.shields.io/maven-central/v/com.github.surpsg/diff-coverage-maven-plugin.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.github.surpsg%22%20AND%20a:%22diff-coverage-maven-plugin%22) 5 | [![codecov](https://codecov.io/gh/SurpSG/diff-coverage-maven-plugin/branch/master/graph/badge.svg)](https://codecov.io/gh/SurpSG/diff-coverage-maven-plugin) 6 | 7 | `Diff coverage maven plugin` builds [JaCoCo](https://github.com/jacoco/jacoco) compatible code coverage report of new and modified code based on a provided [diff](https://en.wikipedia.org/wiki/Diff#Unified_format). 8 | 9 | The plugin is able to check and fail a build if code coverage rules are not met. 10 | 11 | ## How it works 12 | `Diff coverage` works in tandem with JaCoCo and requires JaCoCo to be applied to a project as well. 13 | The plugin does the next steps: 14 | * analyzes coverage data('.exec' files generated by JaCoCo) 15 | * cuts off all code coverage data that wasn't modified 16 | * checks violation rules if any are set up 17 | * builds diff coverage HTML report. See [HTML report example](#Report-example) 18 | 19 | ## Install plugin 20 | ```xml 21 | 22 | 23 | 24 | org.jacoco 25 | jacoco-maven-plugin 26 | 0.8.10 27 | 28 | 29 | io.github.surpsg 30 | diff-coverage-maven-plugin 31 | 1.0.0 32 | 33 | 34 | 35 | 36 | path/to/diffFile 37 | 38 | 39 | HEAD 40 | 41 | 42 | http://url.com 43 | 44 | 45 | 46 | 47 | 48 | true 49 | 50 | 51 | 0.7 52 | 53 | 54 | 55 | 0.1 56 | 0.7 57 | 1.0 58 | 59 | 60 | 61 | **/custom/exec/location/*.exec 62 | 63 | 64 | **/custom/**/exclude/*.exec 65 | 66 | 67 | 68 | **/package/** 69 | **/ClassNamePrefix* 70 | 71 | 72 | 73 | **/exclude/**/ClassName.class 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | html 83 | false 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | diffCoverage 92 | 93 | 94 | 95 | 96 | 97 | 98 | ``` 99 | 100 | ## Maven goal description 101 | `Diff Coverage Maven plugin` has a single goal `diffCoverage` that is bind to `verify` phase 102 | ```shell script 103 | # run tests and build diff coverage report 104 | mvn clean verify 105 | 106 | # Invoke the goal explicitly. 107 | # It depends on `test` phase, make sure it's called when coverage data(*.exec files) already generated. 108 | mvn clean test diff-coverage:diffCoverage 109 | ``` 110 | 111 | ## Report example 112 | Maven output on failed violation rules: 113 | ``` 114 | [INFO] File src/main/kotlin/org/example/Hello.kt has 5 modified lines 115 | [INFO] New violation: Rule violated for bundle untitled: instructions covered ratio is 0.4, but expected minimum is 0.7 116 | [INFO] New violation: Rule violated for bundle untitled: lines covered ratio is 0.6, but expected minimum is 0.7 117 | [WARNING] Fail on violations: true. Found violations: 2. 118 | [INFO] ------------------------------------------------------------------------ 119 | [INFO] BUILD FAILURE 120 | [INFO] ------------------------------------------------------------------------ 121 | [INFO] Total time: 9.919 s 122 | [INFO] Finished at: 2020-07-06T00:56:33+03:00 123 | [INFO] ------------------------------------------------------------------------ 124 | [ERROR] Rule violated for bundle TestProj: instructions covered ratio is 0.4, but expected minimum is 0.7 125 | [ERROR] Rule violated for bundle TestProj: lines covered ratio is 0.6, but expected minimum is 0.7 126 | ``` 127 | The plugin creates JaCoCo like HTML, XML and CSV reports in directory `target/site/diffCoverage/`. 128 | 129 | DiffCoverage HTML report 130 | 131 |
132 | JaCoCo HTML report 133 | JaCoCo HTML report 134 |
135 | -------------------------------------------------------------------------------- /docs/how-to.md: -------------------------------------------------------------------------------- 1 | # How-to notes 2 | 3 | ## Signing 4 | 5 | To publish a library to Maven Central, it is required to sign the artifacts with a GPG key. 6 | 7 | 1. Generate a new GPG key 8 | ```bash 9 | gpg --full-generate-key 10 | ``` 11 | > RSA sign only 12 | > size: 3072 13 | > expiration: 4y (4 years) 14 | 15 | Consider the entered password as `` 16 | 17 | 2. List all keys and get the key id 18 | ```bash 19 | gpg --list-keys --keyid-format short 20 | ``` 21 | > Copy the key id (8 characters) from the output 22 | > consider next as 23 | 24 | 3. Publish the key 25 | ```bash 26 | gpg --keyserver hkp://keyserver.ubuntu.com --send-keys 27 | ``` 28 | 29 | 4. Export the private key for signing 30 | ```bash 31 | # ASCII armored 32 | gpg --armor --export-secret-key 33 | # Consider next as SIGNING_KEY 34 | ``` 35 | 36 | ## Publishing the plugin 37 | 38 | ```bash 39 | mvn clean deploy -Dgpg.passphrase="" -Prelease 40 | ``` 41 | where: 42 | - `password` - GPG key passphrase 43 | 44 | ## Setup project for publishing 45 | 46 | [Official guide](https://central.sonatype.org/publish/publish-portal-maven/) 47 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.3.2 23 | # 24 | # Optional ENV vars 25 | # ----------------- 26 | # JAVA_HOME - location of a JDK home dir, required when download maven via java source 27 | # MVNW_REPOURL - repo url base for downloading maven distribution 28 | # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 29 | # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output 30 | # ---------------------------------------------------------------------------- 31 | 32 | set -euf 33 | [ "${MVNW_VERBOSE-}" != debug ] || set -x 34 | 35 | # OS specific support. 36 | native_path() { printf %s\\n "$1"; } 37 | case "$(uname)" in 38 | CYGWIN* | MINGW*) 39 | [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" 40 | native_path() { cygpath --path --windows "$1"; } 41 | ;; 42 | esac 43 | 44 | # set JAVACMD and JAVACCMD 45 | set_java_home() { 46 | # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched 47 | if [ -n "${JAVA_HOME-}" ]; then 48 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 49 | # IBM's JDK on AIX uses strange locations for the executables 50 | JAVACMD="$JAVA_HOME/jre/sh/java" 51 | JAVACCMD="$JAVA_HOME/jre/sh/javac" 52 | else 53 | JAVACMD="$JAVA_HOME/bin/java" 54 | JAVACCMD="$JAVA_HOME/bin/javac" 55 | 56 | if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then 57 | echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 58 | echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 59 | return 1 60 | fi 61 | fi 62 | else 63 | JAVACMD="$( 64 | 'set' +e 65 | 'unset' -f command 2>/dev/null 66 | 'command' -v java 67 | )" || : 68 | JAVACCMD="$( 69 | 'set' +e 70 | 'unset' -f command 2>/dev/null 71 | 'command' -v javac 72 | )" || : 73 | 74 | if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then 75 | echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 76 | return 1 77 | fi 78 | fi 79 | } 80 | 81 | # hash string like Java String::hashCode 82 | hash_string() { 83 | str="${1:-}" h=0 84 | while [ -n "$str" ]; do 85 | char="${str%"${str#?}"}" 86 | h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) 87 | str="${str#?}" 88 | done 89 | printf %x\\n $h 90 | } 91 | 92 | verbose() { :; } 93 | [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } 94 | 95 | die() { 96 | printf %s\\n "$1" >&2 97 | exit 1 98 | } 99 | 100 | trim() { 101 | # MWRAPPER-139: 102 | # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. 103 | # Needed for removing poorly interpreted newline sequences when running in more 104 | # exotic environments such as mingw bash on Windows. 105 | printf "%s" "${1}" | tr -d '[:space:]' 106 | } 107 | 108 | # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties 109 | while IFS="=" read -r key value; do 110 | case "${key-}" in 111 | distributionUrl) distributionUrl=$(trim "${value-}") ;; 112 | distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; 113 | esac 114 | done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" 115 | [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" 116 | 117 | case "${distributionUrl##*/}" in 118 | maven-mvnd-*bin.*) 119 | MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ 120 | case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in 121 | *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; 122 | :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; 123 | :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; 124 | :Linux*x86_64*) distributionPlatform=linux-amd64 ;; 125 | *) 126 | echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 127 | distributionPlatform=linux-amd64 128 | ;; 129 | esac 130 | distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" 131 | ;; 132 | maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; 133 | *) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; 134 | esac 135 | 136 | # apply MVNW_REPOURL and calculate MAVEN_HOME 137 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 138 | [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" 139 | distributionUrlName="${distributionUrl##*/}" 140 | distributionUrlNameMain="${distributionUrlName%.*}" 141 | distributionUrlNameMain="${distributionUrlNameMain%-bin}" 142 | MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" 143 | MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" 144 | 145 | exec_maven() { 146 | unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : 147 | exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" 148 | } 149 | 150 | if [ -d "$MAVEN_HOME" ]; then 151 | verbose "found existing MAVEN_HOME at $MAVEN_HOME" 152 | exec_maven "$@" 153 | fi 154 | 155 | case "${distributionUrl-}" in 156 | *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; 157 | *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; 158 | esac 159 | 160 | # prepare tmp dir 161 | if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then 162 | clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } 163 | trap clean HUP INT TERM EXIT 164 | else 165 | die "cannot create temp dir" 166 | fi 167 | 168 | mkdir -p -- "${MAVEN_HOME%/*}" 169 | 170 | # Download and Install Apache Maven 171 | verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 172 | verbose "Downloading from: $distributionUrl" 173 | verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 174 | 175 | # select .zip or .tar.gz 176 | if ! command -v unzip >/dev/null; then 177 | distributionUrl="${distributionUrl%.zip}.tar.gz" 178 | distributionUrlName="${distributionUrl##*/}" 179 | fi 180 | 181 | # verbose opt 182 | __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' 183 | [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v 184 | 185 | # normalize http auth 186 | case "${MVNW_PASSWORD:+has-password}" in 187 | '') MVNW_USERNAME='' MVNW_PASSWORD='' ;; 188 | has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; 189 | esac 190 | 191 | if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then 192 | verbose "Found wget ... using wget" 193 | wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" 194 | elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then 195 | verbose "Found curl ... using curl" 196 | curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" 197 | elif set_java_home; then 198 | verbose "Falling back to use Java to download" 199 | javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" 200 | targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" 201 | cat >"$javaSource" <<-END 202 | public class Downloader extends java.net.Authenticator 203 | { 204 | protected java.net.PasswordAuthentication getPasswordAuthentication() 205 | { 206 | return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); 207 | } 208 | public static void main( String[] args ) throws Exception 209 | { 210 | setDefault( new Downloader() ); 211 | java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); 212 | } 213 | } 214 | END 215 | # For Cygwin/MinGW, switch paths to Windows format before running javac and java 216 | verbose " - Compiling Downloader.java ..." 217 | "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" 218 | verbose " - Running Downloader.java ..." 219 | "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" 220 | fi 221 | 222 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 223 | if [ -n "${distributionSha256Sum-}" ]; then 224 | distributionSha256Result=false 225 | if [ "$MVN_CMD" = mvnd.sh ]; then 226 | echo "Checksum validation is not supported for maven-mvnd." >&2 227 | echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 228 | exit 1 229 | elif command -v sha256sum >/dev/null; then 230 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then 231 | distributionSha256Result=true 232 | fi 233 | elif command -v shasum >/dev/null; then 234 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then 235 | distributionSha256Result=true 236 | fi 237 | else 238 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 239 | echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 240 | exit 1 241 | fi 242 | if [ $distributionSha256Result = false ]; then 243 | echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 244 | echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 245 | exit 1 246 | fi 247 | fi 248 | 249 | # unzip and move 250 | if command -v unzip >/dev/null; then 251 | unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" 252 | else 253 | tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" 254 | fi 255 | printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" 256 | mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" 257 | 258 | clean || : 259 | exec_maven "$@" 260 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM http://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.2 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | if ($env:MAVEN_USER_HOME) { 83 | $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" 84 | } 85 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 86 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 87 | 88 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 89 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 90 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 91 | exit $? 92 | } 93 | 94 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 95 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 96 | } 97 | 98 | # prepare tmp dir 99 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 100 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 101 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 102 | trap { 103 | if ($TMP_DOWNLOAD_DIR.Exists) { 104 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 105 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 106 | } 107 | } 108 | 109 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 110 | 111 | # Download and Install Apache Maven 112 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 113 | Write-Verbose "Downloading from: $distributionUrl" 114 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 115 | 116 | $webclient = New-Object System.Net.WebClient 117 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 118 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 119 | } 120 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 121 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 122 | 123 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 124 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 125 | if ($distributionSha256Sum) { 126 | if ($USE_MVND) { 127 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 128 | } 129 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 130 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 131 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 132 | } 133 | } 134 | 135 | # unzip and move 136 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 137 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 138 | try { 139 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 140 | } catch { 141 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 142 | Write-Error "fail to move MAVEN_HOME" 143 | } 144 | } finally { 145 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 146 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 147 | } 148 | 149 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 150 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | io.github.surpsg 6 | diff-coverage-maven-plugin 7 | ${project.groupId}:${project.artifactId} 8 | maven-plugin 9 | 1.0.0 10 | 11 | Diff coverage maven plugin builds code coverage report of new and modified code based on a provided diff 12 | 13 | https://github.com/SurpSG/diff-coverage-maven-plugin 14 | 15 | 16 | MIT License 17 | http://www.opensource.org/licenses/mit-license.php 18 | 19 | 20 | 21 | 22 | 23 | Sergii Gnatiuk 24 | surpsg2012@gmail.com 25 | 26 | 27 | 28 | 29 | https://github.com/SurpSG/diff-coverage-maven-plugin 30 | scm:git:git://github.com/SurpSG/diff-coverage-maven-plugin.git 31 | scm:git:ssh://github.com/SurpSG/diff-coverage-maven-plugin.git 32 | 33 | 34 | Github 35 | https://github.com/SurpSG/diff-coverage-maven-plugin/issues 36 | 37 | 38 | 39 | 40 | ossrh 41 | https://oss.sonatype.org/content/repositories/snapshots 42 | 43 | 44 | ossrh 45 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 46 | 47 | 48 | 49 | 50 | UTF-8 51 | official 52 | HEAD 53 | 54 | 3.9.9 55 | 3.15.1 56 | 57 | 2.1.10 58 | 17 59 | true 60 | 4.13.2 61 | 62 | 0.8.12 63 | 3.2.0 64 | 1.0.0 65 | 66 | 67 | 68 | 69 | org.apache.maven 70 | maven-plugin-api 71 | ${maven.version} 72 | provided 73 | 74 | 75 | org.apache.maven.plugin-tools 76 | maven-plugin-annotations 77 | ${maven.plugin.tools.version} 78 | provided 79 | 80 | 81 | org.apache.maven 82 | maven-core 83 | ${maven.version} 84 | provided 85 | 86 | 87 | 88 | org.jetbrains.kotlin 89 | kotlin-stdlib-jdk8 90 | ${kotlin.version} 91 | 92 | 93 | org.jetbrains.kotlin 94 | kotlin-test-junit 95 | ${kotlin.version} 96 | test 97 | 98 | 99 | 100 | io.github.gw-kit 101 | delta-coverage-core 102 | ${delta.coverage.core.version} 103 | 104 | 105 | org.jacoco 106 | org.jacoco.core 107 | ${jacoco.version} 108 | 109 | 110 | org.jacoco 111 | org.jacoco.report 112 | ${jacoco.version} 113 | 114 | 115 | org.eclipse.jgit 116 | org.eclipse.jgit 117 | 7.1.0.202411261347-r 118 | 119 | 120 | 121 | org.codehaus.plexus 122 | plexus-utils 123 | 4.0.2 124 | 125 | 126 | 127 | junit 128 | junit 129 | ${junit.version} 130 | test 131 | 132 | 133 | 134 | 135 | ${project.basedir}/src/main/kotlin 136 | 137 | 138 | org.jetbrains.kotlin 139 | kotlin-maven-plugin 140 | ${kotlin.version} 141 | 142 | 143 | compile 144 | 145 | compile 146 | 147 | 148 | 149 | test-compile 150 | 151 | test-compile 152 | 153 | 154 | 155 | 156 | 157 | 158 | org.apache.maven.plugins 159 | maven-plugin-plugin 160 | ${maven.plugin.tools.version} 161 | 162 | 163 | 164 | org.jacoco 165 | jacoco-maven-plugin 166 | ${jacoco.version} 167 | 168 | 169 | pre-unit-test 170 | 171 | prepare-agent 172 | 173 | 174 | 175 | 176 | pre-integration-test 177 | pre-integration-test 178 | 179 | prepare-agent 180 | 181 | 182 | ${project.build.directory}/jacoco-it.exec 183 | invoker.mavenOpts 184 | 185 | 186 | 187 | 188 | post-integration-test 189 | post-integration-test 190 | 191 | merge 192 | 193 | 194 | 195 | 196 | ${project.build.directory} 197 | 198 | *.exec 199 | 200 | 201 | 202 | ${project.build.directory}/fullCoverage.exec 203 | 204 | 205 | 206 | 207 | post-integration-test 208 | 209 | report 210 | 211 | 212 | ${project.build.directory}/fullCoverage.exec 213 | ${project.reporting.outputDirectory}/jacoco-fullCoverage 214 | 215 | 216 | 217 | 218 | 219 | 220 | org.apache.maven.plugins 221 | maven-invoker-plugin 222 | 3.9.0 223 | 224 | ${project.build.directory}/it 225 | verify 226 | setup 227 | true 228 | true 229 | true 230 | ${project.build.directory}/local-repo 231 | 232 | 234 | git-diff-support/pom.xml 235 | url-source-check/pom.xml 236 | 237 | 238 | */pom.xml 239 | 240 | 241 | clean 242 | install 243 | 244 | src/it/settings.xml 245 | 246 | 247 | 248 | 249 | install 250 | run 251 | 252 | 253 | 254 | 255 | 256 | io.github.surpsg 257 | diff-coverage-maven-plugin 258 | ${diff.coverage.plugin.version} 259 | 260 | ${project.build.directory}/fullCoverage.exec 261 | 262 | ${diff.source} 263 | 264 | 265 | true 266 | 0.9 267 | 268 | 269 | 270 | 271 | 272 | diffCoverage 273 | 274 | 275 | 276 | 277 | 278 | 279 | org.apache.maven.plugins 280 | maven-source-plugin 281 | 3.3.1 282 | 283 | 284 | attach-sources 285 | package 286 | 287 | jar 288 | 289 | 290 | true 291 | true 292 | 293 | 294 | 295 | 296 | 297 | org.jetbrains.dokka 298 | dokka-maven-plugin 299 | 2.0.0 300 | 301 | 302 | pre-site 303 | 304 | dokka 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | release 315 | 316 | 317 | 318 | org.apache.maven.plugins 319 | maven-gpg-plugin 320 | 3.2.7 321 | 322 | 323 | sign-artifacts 324 | verify 325 | 326 | sign 327 | 328 | 329 | 330 | 331 | 332 | org.sonatype.central 333 | central-publishing-maven-plugin 334 | 0.7.0 335 | true 336 | 337 | central 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "automerge": true, 7 | "baseBranches": ["develop"] 8 | } 9 | -------------------------------------------------------------------------------- /settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | ossrh 9 | 10 | gpg 11 | ${env.GPG_PASSPHRASE} 12 | 13 | 9DBA3212DC5C0322927BE20010206DD4CF5F9FF3 14 | ${gpg.keyname} 15 | false 16 | 17 | 18 | 19 | 20 | ossrh 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/it/exclude-classes/diffFile.patch: -------------------------------------------------------------------------------- 1 | =================================================================== 2 | --- a/src/it/exclude-classes/src/main/java/com/include/Example.java 3 | +++ b/src/it/exclude-classes/src/main/java/com/include/Example.java 4 | @@ -3,7 +3,7 @@ 5 | public class Example { 6 | 7 | public void sayHello() { 8 | - System.out.println(""); 9 | + System.out.println("hello"); 10 | } 11 | 12 | } 13 | =================================================================== 14 | --- a/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe2.java 15 | +++ b/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe2.java 16 | @@ -3,7 +3,7 @@ 17 | public class ExcludeMe2 { 18 | 19 | public void excluded() { 20 | - System.out.println(""); 21 | + System.out.println("this method must not be invoked from tests"); 22 | } 23 | 24 | } 25 | =================================================================== 26 | --- a/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe.java 27 | +++ b/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe.java 28 | @@ -3,7 +3,7 @@ 29 | public class ExcludeMe { 30 | 31 | public void excluded() { 32 | - System.out.println(""); 33 | + System.out.println("this method must not be invoked from tests"); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/it/exclude-classes/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | diffFile.patch 44 | 45 | 46 | **/exclude/** 47 | 48 | 49 | true 50 | 1.0 51 | 52 | 53 | 54 | 55 | 56 | diffCoverage 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe.java: -------------------------------------------------------------------------------- 1 | package com.exclude; 2 | 3 | public class ExcludeMe { 4 | 5 | public void excluded() { 6 | System.out.println("this method must not be invoked from tests"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe2.java: -------------------------------------------------------------------------------- 1 | package com.exclude; 2 | 3 | public class ExcludeMe2 { 4 | 5 | public void excluded() { 6 | System.out.println("this method must not be invoked from tests"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/exclude-classes/src/main/java/com/include/Example.java: -------------------------------------------------------------------------------- 1 | package com.include; 2 | 3 | public class Example { 4 | 5 | public void sayHello() { 6 | System.out.println("hello"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/exclude-classes/src/test/java/com/include/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.include; 2 | import org.junit.Test; 3 | 4 | public class ExampleTest { 5 | 6 | @Test 7 | public void test() { 8 | new Example().sayHello(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/exclude-classes/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String unexpectedOutputMsg = "[ERROR] Rule violated for bundle exclude-classes"; 5 | 6 | String buildLog = FileUtils.fileRead(new File(basedir, "build.log")); 7 | if (buildLog.contains(unexpectedOutputMsg)) { 8 | throw new RuntimeException("Unexpected message: " + unexpectedOutputMsg); 9 | } 10 | -------------------------------------------------------------------------------- /src/it/excluded-all-classes/diffFile.patch: -------------------------------------------------------------------------------- 1 | any 2 | -------------------------------------------------------------------------------- /src/it/excluded-all-classes/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.buildResult=failure 2 | -------------------------------------------------------------------------------- /src/it/excluded-all-classes/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | diffFile.patch 44 | 45 | 46 | ** 47 | 48 | 49 | true 50 | 1.0 51 | 52 | 53 | 54 | 55 | 56 | diffCoverage 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/it/excluded-all-classes/src/main/java/com/include/Example.java: -------------------------------------------------------------------------------- 1 | package com.include; 2 | 3 | public class Example { 4 | 5 | public void sayHello() { 6 | System.out.println("hello"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/excluded-all-classes/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String expectedErrorMsg = "Classes collection is empty"; 5 | 6 | String buildLog = FileUtils.fileRead(new File(basedir, "build.log")); 7 | if (!buildLog.contains(expectedErrorMsg)) { 8 | throw new RuntimeException("Expected error message: " + expectedErrorMsg); 9 | } 10 | -------------------------------------------------------------------------------- /src/it/fail-on-duplicated-coverage-config-check/diffFile.patch: -------------------------------------------------------------------------------- 1 | empty diff 2 | -------------------------------------------------------------------------------- /src/it/fail-on-duplicated-coverage-config-check/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.buildResult=failure 2 | -------------------------------------------------------------------------------- /src/it/fail-on-duplicated-coverage-config-check/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | diffFile.patch 44 | 45 | 46 | 0.7 47 | 0.9 48 | 49 | 50 | 51 | 52 | 53 | diffCoverage 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/it/fail-on-duplicated-coverage-config-check/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String expectedErrMsgHead = "Simultaneous configuration of 'minCoverage' and any of [minCoverage, minBranches, minInstructions] is not allowed."; 5 | String expectedErrorMsgPart1 = "violations.minCoverage = 0.7"; 6 | String expectedErrorMsgPart2 = "violations.minLines = 0.9"; 7 | 8 | String buildLog = FileUtils.fileRead( new File( basedir, "build.log" ) ); 9 | if ( !buildLog.contains( expectedErrMsgHead ) ) { 10 | throw new RuntimeException( "Expected message: " + expectedErrMsgHead ); 11 | } 12 | if ( !buildLog.contains( expectedErrorMsgPart1 ) ) { 13 | throw new RuntimeException( "Expected message: " + expectedErrorMsgPart1 ); 14 | } 15 | if ( !buildLog.contains( expectedErrorMsgPart2 ) ) { 16 | throw new RuntimeException( "Unexpected message: " + expectedErrorMsgPart2 ); 17 | } 18 | -------------------------------------------------------------------------------- /src/it/git-diff-support/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !*.java 4 | !.gitignore 5 | !*/ 6 | -------------------------------------------------------------------------------- /src/it/git-diff-support/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | HEAD 44 | 45 | 46 | false 47 | 0.7 48 | 49 | 50 | 51 | 52 | 53 | diffCoverage 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/it/git-diff-support/setup.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | import org.eclipse.jgit.api.Git; 4 | import org.eclipse.jgit.api.errors.GitAPIException; 5 | import org.eclipse.jgit.lib.ConfigConstants; 6 | import org.eclipse.jgit.lib.CoreConfig; 7 | import org.eclipse.jgit.lib.Repository; 8 | import org.eclipse.jgit.storage.file.FileRepositoryBuilder; 9 | 10 | File rootProject = new File("target/it/git-diff-support"); 11 | System.out.println(rootProject.getAbsolutePath()); 12 | 13 | // init git repository 14 | Repository repository = FileRepositoryBuilder.create(new File(rootProject, ".git")); 15 | repository.getConfig().setEnum( 16 | ConfigConstants.CONFIG_CORE_SECTION, 17 | null, 18 | ConfigConstants.CONFIG_KEY_AUTOCRLF, 19 | File.separator.equals("\r\n") ? CoreConfig.AutoCRLF.TRUE : CoreConfig.AutoCRLF.INPUT 20 | ); 21 | repository.create(); 22 | 23 | // commit all files 24 | Git git; 25 | try { 26 | git = new Git(repository); 27 | git.add().addFilepattern(".").call(); 28 | git.commit().setMessage("Add all").call(); 29 | } finally { 30 | git.close(); 31 | } 32 | 33 | // modify java class 34 | File srcDir = new File(rootProject, "src/main/java/com/test/"); 35 | File scrFile = new File(srcDir, "Example.java"); 36 | scrFile.delete(); 37 | new File(srcDir, "Example.new").renameTo(scrFile); 38 | -------------------------------------------------------------------------------- /src/it/git-diff-support/src/main/java/com/test/Example.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | 3 | public class Example { 4 | 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | } 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/git-diff-support/src/main/java/com/test/Example.new: -------------------------------------------------------------------------------- 1 | package com.test; 2 | 3 | public class Example { 4 | 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | } else { 9 | System.out.println("else"); 10 | } 11 | System.out.println("return"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/it/git-diff-support/src/test/java/com/test/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | import org.junit.Test; 3 | 4 | public class ExampleTest { 5 | 6 | @Test 7 | public void test() { 8 | new Example().sayHello(true); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/git-diff-support/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String expectedLinesErrMsg = "lines covered ratio is 0.5, but expected minimum is 0.7"; 5 | String unexpectedInstructionsErrMsg = "instructions covered ratio is"; 6 | String unexpectedBranchesErrMsg = "branches covered ratio is "; 7 | 8 | String buildLog = FileUtils.fileRead( new File( basedir, "build.log" ) ); 9 | if ( !buildLog.contains( expectedLinesErrMsg ) ) { 10 | throw new RuntimeException( "Expected message: " + expectedLinesErrMsg ); 11 | } 12 | if ( buildLog.contains( unexpectedInstructionsErrMsg ) ) { 13 | throw new RuntimeException( "Unexpected message: " + unexpectedInstructionsErrMsg ); 14 | } 15 | if ( buildLog.contains( unexpectedBranchesErrMsg ) ) { 16 | throw new RuntimeException( "Unexpected message: " + unexpectedBranchesErrMsg ); 17 | } 18 | -------------------------------------------------------------------------------- /src/it/include-classes/diffFile.patch: -------------------------------------------------------------------------------- 1 | =================================================================== 2 | --- a/src/it/exclude-classes/src/main/java/com/include/Example.java 3 | +++ b/src/it/exclude-classes/src/main/java/com/include/Example.java 4 | @@ -3,7 +3,7 @@ 5 | public class Example { 6 | 7 | public void sayHello() { 8 | - System.out.println(""); 9 | + System.out.println("hello"); 10 | } 11 | 12 | } 13 | =================================================================== 14 | --- a/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe.java 15 | +++ b/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe.java 16 | @@ -3,7 +3,7 @@ 17 | public class ExcludeMe { 18 | 19 | public void excluded() { 20 | - System.out.println(""); 21 | + System.out.println("this method must not be invoked from tests"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/it/include-classes/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | diffFile.patch 44 | 45 | 46 | **/include/**/Example.class 47 | 48 | 49 | true 50 | 1.0 51 | 52 | 53 | 54 | 55 | 56 | diffCoverage 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/it/include-classes/src/main/java/com/exclude/ExcludeMe.java: -------------------------------------------------------------------------------- 1 | package com.exclude; 2 | 3 | public class ExcludeMe { 4 | 5 | public void excluded() { 6 | System.out.println("this method must not be invoked from tests");// 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/include-classes/src/main/java/com/include/Example.java: -------------------------------------------------------------------------------- 1 | package com.include; 2 | 3 | public class Example { 4 | 5 | public void sayHello() { 6 | System.out.println("hello"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/include-classes/src/test/java/com/include/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.include; 2 | import org.junit.Test; 3 | 4 | public class ExampleTest { 5 | 6 | @Test 7 | public void test() { 8 | new Example().sayHello(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/include-classes/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String unexpectedOutputMsg = "[ERROR] Rule violated for bundle exclude-classes"; 5 | 6 | String buildLog = FileUtils.fileRead(new File(basedir, "build.log")); 7 | if (buildLog.contains(unexpectedOutputMsg)) { 8 | throw new RuntimeException("Unexpected message: " + unexpectedOutputMsg); 9 | } 10 | -------------------------------------------------------------------------------- /src/it/include-exclude-classes/diffFile.patch: -------------------------------------------------------------------------------- 1 | =================================================================== 2 | --- a/src/it/exclude-classes/src/main/java/com/include/Example.java 3 | +++ b/src/it/exclude-classes/src/main/java/com/include/Example.java 4 | @@ -3,7 +3,7 @@ 5 | public class Example { 6 | 7 | public void sayHello() { 8 | - System.out.println(""); 9 | + System.out.println("hello"); 10 | } 11 | 12 | } 13 | =================================================================== 14 | --- a/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe2.java 15 | +++ b/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe2.java 16 | @@ -3,7 +3,7 @@ 17 | public class ExcludeMe2 { 18 | 19 | public void excluded() { 20 | - System.out.println(""); 21 | + System.out.println("this method must not be invoked from tests"); 22 | } 23 | 24 | } 25 | =================================================================== 26 | --- a/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe.java 27 | +++ b/src/it/exclude-classes/src/main/java/com/exclude/ExcludeMe.java 28 | @@ -3,7 +3,7 @@ 29 | public class ExcludeMe { 30 | 31 | public void excluded() { 32 | - System.out.println(""); 33 | + System.out.println("this method must not be invoked from tests"); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/it/include-exclude-classes/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | diffFile.patch 44 | 45 | 46 | **/include/**/Example.class 47 | 48 | 49 | **/exclude/**/ExcludeMe.class 50 | **/exclude/**/ExcludeMe2.class 51 | 52 | 53 | true 54 | 1.0 55 | 56 | 57 | 58 | 59 | 60 | diffCoverage 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/it/include-exclude-classes/src/main/java/com/exclude/ExcludeMe.java: -------------------------------------------------------------------------------- 1 | package com.exclude; 2 | 3 | public class ExcludeMe { 4 | 5 | public void excluded() { 6 | System.out.println("this method must not be invoked from tests"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/include-exclude-classes/src/main/java/com/exclude/ExcludeMe2.java: -------------------------------------------------------------------------------- 1 | package com.exclude; 2 | 3 | public class ExcludeMe2 { 4 | 5 | public void excluded() { 6 | System.out.println("this method must not be invoked from tests"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/include-exclude-classes/src/main/java/com/include/Example.java: -------------------------------------------------------------------------------- 1 | package com.include; 2 | 3 | public class Example { 4 | 5 | public void sayHello() { 6 | System.out.println("hello"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/it/include-exclude-classes/src/test/java/com/include/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.include; 2 | import org.junit.Test; 3 | 4 | public class ExampleTest { 5 | 6 | @Test 7 | public void test() { 8 | new Example().sayHello(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/include-exclude-classes/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String unexpectedOutputMsg = "[ERROR] Rule violated for bundle exclude-classes"; 5 | 6 | String buildLog = FileUtils.fileRead(new File(basedir, "build.log")); 7 | if (buildLog.contains(unexpectedOutputMsg)) { 8 | throw new RuntimeException("Unexpected message: " + unexpectedOutputMsg); 9 | } 10 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/moduleA/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | it-check-passes-moduleA 7 | 1.0-SNAPSHOT 8 | 9 | 10 | jacoco 11 | it-check-passes 12 | 1.0-SNAPSHOT 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/ClassA.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleA; 2 | 3 | public class ClassA { 4 | public int sayHello() { 5 | return 1; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/moduleA/src/test/java/com/test/moduleA/ClassATest.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleA; 2 | import org.junit.Test; 3 | 4 | public class ClassATest { 5 | @Test 6 | public void test() { 7 | new ClassA().sayHello(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/moduleB/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | it-check-passes-moduleB 7 | 1.0-SNAPSHOT 8 | 9 | 10 | jacoco 11 | it-check-passes 12 | 1.0-SNAPSHOT 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/ClassB.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleB; 2 | 3 | public class ClassB { 4 | public int sayHello() { 5 | return 2; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/moduleB/src/test/java/com/test/moduleB/ClassBTest.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleB; 2 | import org.junit.Test; 3 | 4 | public class ClassBTest { 5 | @Test 6 | public void test() { 7 | new ClassB().sayHello(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | 1.8 13 | 1.8 14 | 15 | 16 | 17 | 18 | junit 19 | junit 20 | 4.13.2 21 | test 22 | 23 | 24 | 25 | 26 | moduleA 27 | moduleB 28 | report 29 | 30 | 31 | 32 | 33 | 34 | org.jacoco 35 | jacoco-maven-plugin 36 | 0.8.12 37 | 38 | 39 | 40 | prepare-agent 41 | 42 | 43 | 44 | ${project.build.directory}/coverage-reports/custom-jacoco-name.exec 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/report/diffFile.patch: -------------------------------------------------------------------------------- 1 | Index: src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/Example.java 2 | IDEA additional info: 3 | Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP 4 | <+>UTF-8 5 | =================================================================== 6 | diff --git a/src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/Example.java b/src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/ClassB.java 7 | rename from src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/Example.java 8 | rename to src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/ClassB.java 9 | --- a/src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/Example.java (revision 72796eb0c10e73bb0883db1a420cc8ab20cfc2d6) 10 | +++ b/src/it/multi-module-reports-exclusions-check/moduleB/src/main/java/com/test/moduleB/ClassB.java (date 1628722971598) 11 | @@ -1,14 +1,7 @@ 12 | package com.test.moduleB; 13 | 14 | -public class Example { 15 | - 16 | - public void sayHello(boolean a) { 17 | - if (a) { 18 | - System.out.println("if"); 19 | - } else { 20 | - System.out.println("else"); 21 | - } 22 | - System.out.println("return"); 23 | +public class ClassB { 24 | + public int sayHello() { 25 | + return 2; 26 | } 27 | - 28 | } 29 | Index: src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/Example.java 30 | IDEA additional info: 31 | Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP 32 | <+>UTF-8 33 | =================================================================== 34 | diff --git a/src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/Example.java b/src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/ClassA.java 35 | rename from src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/Example.java 36 | rename to src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/ClassA.java 37 | --- a/src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/Example.java (revision 72796eb0c10e73bb0883db1a420cc8ab20cfc2d6) 38 | +++ b/src/it/multi-module-reports-exclusions-check/moduleA/src/main/java/com/test/moduleA/ClassA.java (date 1628722971618) 39 | @@ -1,14 +1,7 @@ 40 | package com.test.moduleA; 41 | 42 | -public class Example { 43 | - 44 | - public void sayHello(boolean a) { 45 | - if (a) { 46 | - System.out.println("if"); 47 | - } else { 48 | - System.out.println("else"); 49 | - } 50 | - System.out.println("return"); 51 | - } 52 | - 53 | +public class ClassA { 54 | + public int sayHello() { 55 | + return 1; 56 | + } 57 | } 58 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/report/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | it-check-passes-report 8 | 1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | jacoco 13 | it-check-passes 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | 19 | jacoco 20 | it-check-passes-moduleA 21 | 1.0-SNAPSHOT 22 | 23 | 24 | jacoco 25 | it-check-passes-moduleB 26 | 1.0-SNAPSHOT 27 | 28 | 29 | 30 | 31 | 32 | 33 | io.github.surpsg 34 | diff-coverage-maven-plugin 35 | 36 | 37 | diffFile.patch 38 | 39 | **/coverage-reports/custom-jacoco-name.exec 40 | **/moduleA/**/*.exec 41 | 42 | false 43 | 0.6 44 | 0.7 45 | 1.0 46 | 47 | 48 | 49 | 50 | console 51 | false 52 | 53 | 54 | 55 | 56 | 57 | 58 | diffCoverage 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-exclusions-check/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | File reportsDir = new File(basedir, "/report/target/site/delta-coverage/aggregated"); 5 | File htmlReportDir = new File( reportsDir, "/html" ); 6 | if ( !htmlReportDir.exists() || !htmlReportDir.isDirectory() ) { 7 | throw new RuntimeException( "Html report dir wasn't found: " + htmlReportDir.getAbsolutePath() ); 8 | } 9 | 10 | File xmlReportFile = new File( reportsDir, "report.xml" ); 11 | if ( !xmlReportFile.exists() || !xmlReportFile.isFile() ) { 12 | throw new RuntimeException( "Xml report file wasn't found: " + xmlReportFile.getAbsolutePath() ); 13 | } 14 | 15 | File mdReportFile = new File( reportsDir, "report.md" ); 16 | if ( !mdReportFile.exists() || !mdReportFile.isFile() ) { 17 | throw new RuntimeException( "Markdown report file wasn't found: " + mdReportFile.getAbsolutePath() ); 18 | } 19 | 20 | String expectedInstructionsErrMsg = "[aggregated] Rule violated for bundle aggregated: instructions covered ratio is 0.5, but expected minimum is 0.6"; 21 | String expectedLinesErrMsg = "[aggregated] Rule violated for bundle aggregated: lines covered ratio is 0.5, but expected minimum is 0.7"; 22 | String unexpectedBranchesErrMsg = "[aggregated] Rule violated for bundle aggregated: branches covered ratio"; 23 | 24 | String buildLog = FileUtils.fileRead( new File( basedir, "build.log" ) ); 25 | if ( !buildLog.contains( expectedInstructionsErrMsg ) ) { 26 | throw new RuntimeException( "Expected message: " + expectedInstructionsErrMsg ); 27 | } 28 | if ( !buildLog.contains( expectedLinesErrMsg ) ) { 29 | throw new RuntimeException( "Expected message: " + expectedLinesErrMsg ); 30 | } 31 | if ( buildLog.contains( unexpectedBranchesErrMsg ) ) { 32 | throw new RuntimeException( "Unexpected message: " + unexpectedBranchesErrMsg ); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/moduleA/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | it-check-passes-moduleA 7 | 1.0-SNAPSHOT 8 | 9 | 10 | jacoco 11 | it-check-passes 12 | 1.0-SNAPSHOT 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/moduleA/src/main/java/com/test/moduleA/ClassModuleA.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleA; 2 | 3 | public class ClassModuleA { 4 | public void sayHello(boolean a) { 5 | if (a) { 6 | System.out.println("if"); 7 | } else { 8 | System.out.println("else"); 9 | } 10 | System.out.println("return"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/moduleA/src/test/java/com/test/moduleA/ClassModuleATest.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleA; 2 | 3 | import org.junit.Test; 4 | 5 | public class ClassModuleATest { 6 | @Test public void test() { 7 | new ClassModuleA().sayHello(true); 8 | new ClassModuleA().sayHello(false); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/moduleB/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | it-check-passes-moduleB 7 | 1.0-SNAPSHOT 8 | 9 | 10 | jacoco 11 | it-check-passes 12 | 1.0-SNAPSHOT 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/moduleB/src/main/java/com/test/moduleB/ClassModuleB.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleB; 2 | 3 | public class ClassModuleB { 4 | public void sayHello(boolean a) { 5 | if (a) { 6 | System.out.println("if"); 7 | } else { 8 | System.out.println("else"); 9 | } 10 | System.out.println("return"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/moduleB/src/test/java/com/test/moduleB/ClassModuleBTest.java: -------------------------------------------------------------------------------- 1 | package com.test.moduleB; 2 | 3 | import org.junit.Test; 4 | 5 | public class ClassModuleBTest { 6 | @Test 7 | public void test() { 8 | new ClassModuleB().sayHello(true); 9 | new ClassModuleB().sayHello(false); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | 1.8 13 | 1.8 14 | 15 | 16 | 17 | 18 | junit 19 | junit 20 | 4.13.2 21 | test 22 | 23 | 24 | 25 | 26 | moduleA 27 | moduleB 28 | report 29 | 30 | 31 | 32 | 33 | 34 | org.jacoco 35 | jacoco-maven-plugin 36 | 0.8.12 37 | 38 | 39 | 40 | prepare-agent 41 | 42 | 43 | 44 | ${project.build.directory}/coverage-reports/custom-jacoco-name.exec 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/report/diffFile.patch: -------------------------------------------------------------------------------- 1 | Index: src/it/multi-module-reports-generation-check/moduleB/src/main/java/com/test/moduleB/ClassModuleB.java 2 | IDEA additional info: 3 | Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP 4 | <+>UTF-8 5 | =================================================================== 6 | diff --git a/src/it/multi-module-reports-generation-check/moduleB/src/main/java/com/test/moduleB/ClassModuleB.java b/src/it/multi-module-reports-generation-check/moduleB/src/main/java/com/test/moduleB/ClassModuleB.java 7 | new file mode 100644 8 | --- /dev/null (date 1628714536415) 9 | +++ b/src/it/multi-module-reports-generation-check/moduleB/src/main/java/com/test/moduleB/ClassModuleB.java (date 1628714536415) 10 | @@ -0,0 +1,12 @@ 11 | +package com.test.moduleB; 12 | + 13 | +public class ClassModuleB { 14 | + public void sayHello(boolean a) { 15 | + if (a) { 16 | + System.out.println("if"); 17 | + } else { 18 | + System.out.println("else"); 19 | + } 20 | + System.out.println("return"); 21 | + } 22 | +} 23 | Index: src/it/multi-module-reports-generation-check/moduleA/src/main/java/com/test/moduleA/ClassModuleA.java 24 | IDEA additional info: 25 | Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP 26 | <+>UTF-8 27 | =================================================================== 28 | diff --git a/src/it/multi-module-reports-generation-check/moduleA/src/main/java/com/test/moduleA/ClassModuleA.java b/src/it/multi-module-reports-generation-check/moduleA/src/main/java/com/test/moduleA/ClassModuleA.java 29 | new file mode 100644 30 | --- /dev/null (date 1628714375075) 31 | +++ b/src/it/multi-module-reports-generation-check/moduleA/src/main/java/com/test/moduleA/ClassModuleA.java (date 1628714375075) 32 | @@ -0,0 +1,12 @@ 33 | +package com.test.moduleA; 34 | + 35 | +public class ClassModuleA { 36 | + public void sayHello(boolean a) { 37 | + if (a) { 38 | + System.out.println("if"); 39 | + } else { 40 | + System.out.println("else"); 41 | + } 42 | + System.out.println("return"); 43 | + } 44 | +} 45 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/report/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | it-check-passes-report 8 | 1.0-SNAPSHOT 9 | pom 10 | 11 | 12 | jacoco 13 | it-check-passes 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | 19 | jacoco 20 | it-check-passes-moduleA 21 | 1.0-SNAPSHOT 22 | 23 | 24 | jacoco 25 | it-check-passes-moduleB 26 | 1.0-SNAPSHOT 27 | 28 | 29 | 30 | 31 | 32 | 33 | io.github.surpsg 34 | diff-coverage-maven-plugin 35 | 36 | 37 | diffFile.patch 38 | 39 | **/custom-jacoco-name.exec 40 | 41 | **/exclude/**/ExcludeMe.class 42 | 43 | 44 | 45 | 46 | 47 | diffCoverage 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/it/multi-module-reports-generation-check/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | File reportsDir = new File(basedir, "/report/target/site/delta-coverage/aggregated"); 5 | File htmlReportDir = new File( reportsDir, "/html" ); 6 | if ( !htmlReportDir.exists() || !htmlReportDir.isDirectory() ) { 7 | throw new RuntimeException( "Html report dir wasn't found: " + htmlReportDir.getAbsolutePath() ); 8 | } 9 | 10 | File xmlReportFile = new File( reportsDir, "report.xml" ); 11 | if ( !xmlReportFile.exists() || !xmlReportFile.isFile() ) { 12 | throw new RuntimeException( "Xml report file wasn't found: " + xmlReportFile.getAbsolutePath() ); 13 | } 14 | 15 | File mdReportFile = new File( reportsDir, "report.md" ); 16 | if ( !mdReportFile.exists() || !mdReportFile.isFile() ) { 17 | throw new RuntimeException( "Markdown report file wasn't found: " + mdReportFile.getAbsolutePath() ); 18 | } 19 | -------------------------------------------------------------------------------- /src/it/reports-generation-check/diffFile.patch: -------------------------------------------------------------------------------- 1 | =================================================================== 2 | --- a/src/main/java/com/test/Example.java (revision 9e78667391946d3461759f5589b67d3a676d8ce7) 3 | +++ b/src/main/java/com/test/Example.java (date 1593433398791) 4 | @@ -5,7 +5,10 @@ 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | + } else { 9 | + System.out.println("else"); 10 | } 11 | + System.out.println("return"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/it/reports-generation-check/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | diffFile.patch 44 | 45 | 46 | 47 | 48 | 49 | diffCoverage 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/it/reports-generation-check/src/main/java/com/test/Example.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | 3 | public class Example { 4 | 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | } else { 9 | System.out.println("else"); 10 | } 11 | System.out.println("return"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/it/reports-generation-check/src/test/java/com/test/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | import org.junit.Test; 3 | 4 | public class ExampleTest { 5 | 6 | @Test 7 | public void test() { 8 | new Example().sayHello(true); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/reports-generation-check/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | File reportsDir = new File(basedir, "target/site/delta-coverage/aggregated"); 5 | File htmlReportDir = new File( reportsDir, "/html" ); 6 | if ( !htmlReportDir.exists() || !htmlReportDir.isDirectory() ) { 7 | throw new RuntimeException( "Html report dir wasn't found: " + htmlReportDir.getAbsolutePath() ); 8 | } 9 | 10 | File xmlReportFile = new File( reportsDir, "report.xml" ); 11 | if ( !xmlReportFile.exists() || !xmlReportFile.isFile() ) { 12 | throw new RuntimeException( "Xml report file wasn't found: " + xmlReportFile.getAbsolutePath() ); 13 | } 14 | 15 | File mdReportFile = new File( reportsDir, "report.md" ); 16 | if ( !mdReportFile.exists() || !mdReportFile.isFile() ) { 17 | throw new RuntimeException( "Markdown report file wasn't found: " + mdReportFile.getAbsolutePath() ); 18 | } 19 | -------------------------------------------------------------------------------- /src/it/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | it-repo 7 | 8 | true 9 | 10 | 11 | 12 | local.central 13 | @localRepositoryUrl@ 14 | 15 | true 16 | 17 | 18 | true 19 | 20 | 21 | 22 | 23 | 24 | local.central 25 | @localRepositoryUrl@ 26 | 27 | true 28 | 29 | 30 | true 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/it/url-source-check/diffFile.patch: -------------------------------------------------------------------------------- 1 | =================================================================== 2 | --- a/src/main/java/com/test/Example.java (revision 9e78667391946d3461759f5589b67d3a676d8ce7) 3 | +++ b/src/main/java/com/test/Example.java (date 1593433398791) 4 | @@ -5,7 +5,10 @@ 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | + } else { 9 | + System.out.println("else"); 10 | } 11 | + System.out.println("return"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/it/url-source-check/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | ${project.baseUri}diffFile.patch 44 | 45 | 46 | false 47 | 0.7 48 | 49 | 50 | 51 | 52 | 53 | diffCoverage 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/it/url-source-check/src/main/java/com/test/Example.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | 3 | public class Example { 4 | 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | } else { 9 | System.out.println("else"); 10 | } 11 | System.out.println("return"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/it/url-source-check/src/test/java/com/test/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | import org.junit.Test; 3 | 4 | public class ExampleTest { 5 | 6 | @Test 7 | public void test() { 8 | new Example().sayHello(true); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/url-source-check/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String expectedInstructionsErrMsg = "instructions covered ratio is 0.5, but expected minimum is 0.7"; 5 | String unexpectedLinesErrMsg = "lines covered ratio is"; 6 | String unexpectedBranchesErrMsg = "branches covered ratio is "; 7 | 8 | String buildLog = FileUtils.fileRead( new File( basedir, "build.log" ) ); 9 | if ( !buildLog.contains( expectedInstructionsErrMsg ) ) { 10 | throw new RuntimeException( "Expected message: " + expectedInstructionsErrMsg ); 11 | } 12 | if ( buildLog.contains( unexpectedLinesErrMsg ) ) { 13 | throw new RuntimeException( "Unexpected message: " + unexpectedLinesErrMsg ); 14 | } 15 | if ( buildLog.contains( unexpectedBranchesErrMsg ) ) { 16 | throw new RuntimeException( "Unexpected message: " + unexpectedBranchesErrMsg ); 17 | } 18 | -------------------------------------------------------------------------------- /src/it/violation-rules-check/diffFile.patch: -------------------------------------------------------------------------------- 1 | =================================================================== 2 | --- a/src/main/java/com/test/Example.java (revision 9e78667391946d3461759f5589b67d3a676d8ce7) 3 | +++ b/src/main/java/com/test/Example.java (date 1593433398791) 4 | @@ -5,7 +5,10 @@ 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | + } else { 9 | + System.out.println("else"); 10 | } 11 | + System.out.println("return"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/it/violation-rules-check/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.buildResult=failure 2 | -------------------------------------------------------------------------------- /src/it/violation-rules-check/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jacoco 7 | it-check-passes 8 | 1.0-SNAPSHOT 9 | 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.13.2 20 | test 21 | 22 | 23 | 24 | 25 | 26 | 27 | org.jacoco 28 | jacoco-maven-plugin 29 | 0.8.12 30 | 31 | 32 | 33 | prepare-agent 34 | 35 | 36 | 37 | 38 | 39 | io.github.surpsg 40 | diff-coverage-maven-plugin 41 | 42 | 43 | 44 | diffFile.patch 45 | 46 | 47 | 48 | true 49 | 0.7 50 | 51 | 52 | 53 | 54 | console 55 | false 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | diffCoverage 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/it/violation-rules-check/src/main/java/com/test/Example.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | 3 | public class Example { 4 | 5 | public void sayHello(boolean a) { 6 | if (a) { 7 | System.out.println("if"); 8 | } else { 9 | System.out.println("else"); 10 | } 11 | System.out.println("return"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/it/violation-rules-check/src/test/java/com/test/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | import org.junit.Test; 3 | 4 | public class ExampleTest { 5 | 6 | @Test 7 | public void test() { 8 | new Example().sayHello(true); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/it/violation-rules-check/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import org.codehaus.plexus.util.*; 3 | 4 | String expectedInstructionsErrMsg = "[aggregated] Rule violated for bundle aggregated: instructions covered ratio is 0.5, but expected minimum is 0.7"; 5 | String expectedLinesErrMsg = "[aggregated] Rule violated for bundle aggregated: lines covered ratio is 0.5, but expected minimum is 0.7"; 6 | String unexpectedBranchesErrMsg = "[aggregated] Rule violated for bundle aggregated: branches"; 7 | 8 | String buildLog = FileUtils.fileRead( new File( basedir, "build.log" ) ); 9 | if ( !buildLog.contains( expectedInstructionsErrMsg ) ) { 10 | throw new RuntimeException( "Expected message: " + expectedInstructionsErrMsg ); 11 | } 12 | if ( !buildLog.contains( expectedLinesErrMsg ) ) { 13 | throw new RuntimeException( "Expected message: " + expectedLinesErrMsg ); 14 | } 15 | if ( buildLog.contains( unexpectedBranchesErrMsg ) ) { 16 | throw new RuntimeException( "Unexpected message: " + unexpectedBranchesErrMsg ); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/surpsg/DiffCoverageConfiguration.kt: -------------------------------------------------------------------------------- 1 | package io.github.surpsg 2 | 3 | import java.io.File 4 | import java.net.URL 5 | 6 | class DiffSourceConfiguration( 7 | var url: URL? = null, 8 | var git: String? = null, 9 | var file: File? = null 10 | ) { 11 | override fun toString(): String { 12 | return "DiffSourceConfiguration(url=$url, git=$git, file=$file)" 13 | } 14 | } 15 | 16 | class ViolationsConfiguration( 17 | var failOnViolation: Boolean = false, 18 | var minLines: Double = 0.0, 19 | var minBranches: Double = 0.0, 20 | var minInstructions: Double = 0.0, 21 | 22 | var minCoverage: Double = MIN_COVERAGE_PROPERTY_DEFAULT 23 | ) 24 | 25 | class Report( 26 | var type: String? = null, 27 | var enabled: Boolean = true, 28 | ) 29 | 30 | internal const val MIN_COVERAGE_PROPERTY_DEFAULT: Double = -1.0; 31 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/surpsg/DiffCoverageMojo.kt: -------------------------------------------------------------------------------- 1 | package io.github.surpsg 2 | 3 | import io.github.surpsg.deltacoverage.CoverageEngine 4 | import io.github.surpsg.deltacoverage.config.CoverageEntity 5 | import io.github.surpsg.deltacoverage.config.CoverageRulesConfig 6 | import io.github.surpsg.deltacoverage.config.DeltaCoverageConfig 7 | import io.github.surpsg.deltacoverage.config.DiffSourceConfig 8 | import io.github.surpsg.deltacoverage.config.ViolationRule 9 | import io.github.surpsg.deltacoverage.diff.DiffSource 10 | import io.github.surpsg.deltacoverage.report.DeltaReportFacadeFactory 11 | import org.apache.maven.plugin.AbstractMojo 12 | import org.apache.maven.plugins.annotations.LifecyclePhase 13 | import org.apache.maven.plugins.annotations.Mojo 14 | import org.apache.maven.plugins.annotations.Parameter 15 | import org.apache.maven.project.MavenProject 16 | import org.codehaus.plexus.util.FileUtils 17 | import java.io.File 18 | 19 | @Mojo(name = "diffCoverage", defaultPhase = LifecyclePhase.VERIFY) 20 | class DiffCoverageMojo : AbstractMojo() { 21 | 22 | @Parameter(property = "reactorProjects", required = true, readonly = true) 23 | private lateinit var reactorProjects: MutableList 24 | 25 | @Parameter(property = "jacoco.dataFile", defaultValue = "\${project.build.directory}/jacoco.exec") 26 | private lateinit var dataFile: File 27 | 28 | @Parameter(property = "jacoco.dataFileIncludes", required = false) 29 | private var dataFileIncludes: String? = null 30 | 31 | @Parameter(property = "jacoco.dataFileExcludes", required = false) 32 | private var dataFileExcludes: String? = null 33 | 34 | @Parameter(defaultValue = ALL_FILES_PATTERN, required = false) 35 | private lateinit var includes: List 36 | 37 | @Parameter(required = false) 38 | private var excludes: List = emptyList() 39 | 40 | @Parameter(defaultValue = "\${project.reporting.outputDirectory}") 41 | private lateinit var outputDirectory: File 42 | 43 | @Parameter(name = "diffSource", required = true) 44 | private lateinit var diffSource: DiffSourceConfiguration 45 | 46 | @Parameter(name = "violations") 47 | private var violations = ViolationsConfiguration() 48 | 49 | @Parameter(name = "reports") 50 | private var reports: List = emptyList() 51 | 52 | private val rootProjectDir: File 53 | get() = reactorProjects[0].basedir 54 | 55 | override fun execute() { 56 | val diffCoverageConfig: DeltaCoverageConfig = buildDeltaCoverageConfig("aggregated").apply { 57 | logPluginProperties(this) 58 | } 59 | 60 | DeltaReportFacadeFactory 61 | .buildFacade(diffCoverageConfig.coverageEngine) 62 | .generateReports( 63 | outputDirectory.absoluteFile.resolve("delta-coverage-summary.json").toPath(), 64 | diffCoverageConfig, 65 | ) 66 | } 67 | 68 | private fun logPluginProperties(diffCoverageConfig: DeltaCoverageConfig) { 69 | log.apply { 70 | debug("Root dir: $rootProjectDir") 71 | debug("Classes dirs: ${diffCoverageConfig.classFiles}") 72 | debug("Sources: ${diffCoverageConfig.sourceFiles}") 73 | debug("Exec files: ${diffCoverageConfig.binaryCoverageFiles}") 74 | } 75 | } 76 | 77 | private fun buildDeltaCoverageConfig(view: String) = DeltaCoverageConfig { 78 | coverageEngine = CoverageEngine.JACOCO 79 | viewName = view 80 | 81 | diffSource = DiffSource.buildDiffSource( 82 | rootProjectDir, 83 | DiffSourceConfig { 84 | file = this@DiffCoverageMojo.diffSource.file.asStringOrEmpty { absolutePath } 85 | url = this@DiffCoverageMojo.diffSource.url.asStringOrEmpty { toString() } 86 | diffBase = this@DiffCoverageMojo.diffSource.git ?: "" 87 | } 88 | ) 89 | 90 | binaryCoverageFiles += collectExecFiles() 91 | sourceFiles += reactorProjects.map { it.compileSourceRoots }.flatten().map { File(it) }.toSet() 92 | classFiles += collectClassesFiles().throwIfEmpty("Classes collection") 93 | 94 | coverageRulesConfig = buildCoverageRulesConfig() 95 | reportsConfig = buildDeltaCoverageReportConfig(outputDirectory.absolutePath, reports) 96 | } 97 | 98 | private fun buildCoverageRulesConfig(): CoverageRulesConfig { 99 | val isMinCoverageSet: Boolean = violations.minCoverage != MIN_COVERAGE_PROPERTY_DEFAULT 100 | val configuredProperties: Set> = collectConfiguredCoveragePropertiesNames() 101 | 102 | if (isMinCoverageSet && configuredProperties.isNotEmpty()) { 103 | val conflictingProperties = configuredProperties.joinToString(separator = "\n") { 104 | "violations.${it.first} = ${it.second}" 105 | } 106 | throw IllegalArgumentException( 107 | """ 108 | 109 | Simultaneous configuration of 'minCoverage' and any of [minCoverage, minBranches, minInstructions] is not allowed. 110 | violations.minCoverage = ${violations.minCoverage} 111 | $conflictingProperties 112 | """.trimIndent() 113 | ) 114 | } 115 | 116 | return CoverageRulesConfig { 117 | failOnViolation = violations.failOnViolation 118 | violationRules += if (isMinCoverageSet) { 119 | CoverageEntity.values().map { entity -> 120 | ViolationRule { coverageEntity = entity; minCoverageRatio = violations.minCoverage } 121 | } 122 | } else { 123 | buildCoverageRules() 124 | } 125 | } 126 | } 127 | 128 | private fun collectConfiguredCoveragePropertiesNames(): Set> { 129 | return sequenceOf( 130 | "minLines" to violations.minLines, 131 | "minBranches" to violations.minBranches, 132 | "minInstructions" to violations.minInstructions 133 | ).filter { 134 | it.second > 0.0 135 | }.toSet() 136 | } 137 | 138 | private fun buildCoverageRules(): Set = sequenceOf( 139 | CoverageEntity.LINE to violations.minLines, 140 | CoverageEntity.BRANCH to violations.minBranches, 141 | CoverageEntity.INSTRUCTION to violations.minInstructions 142 | ) 143 | .filter { it.second > 0.0 } 144 | .map { (entity, value) -> 145 | ViolationRule { coverageEntity = entity; minCoverageRatio = value } 146 | } 147 | .toSet() 148 | 149 | private fun collectExecFiles(): Set { 150 | return if (dataFileIncludes == null) { 151 | setOf(dataFile) 152 | } else { 153 | FileUtils.getFiles(rootProjectDir, dataFileIncludes, dataFileExcludes).toSet() 154 | } 155 | } 156 | 157 | private fun collectClassesFiles(): Set { 158 | val includePattern: String = includes.joinToString(",") 159 | val excludePattern: String = excludes.joinToString(",") 160 | return if (excludePattern.isEmpty() && includePattern == ALL_FILES_PATTERN) { 161 | reactorProjects.map { File(it.build.outputDirectory) }.toSet() 162 | } else { 163 | collectFilteredFiles(includePattern, excludePattern) 164 | } 165 | } 166 | 167 | private fun collectFilteredFiles(includePattern: String, excludePattern: String?): Set { 168 | return reactorProjects.asSequence() 169 | .map { project -> File(project.build.outputDirectory) } 170 | .filter { outputDirectory -> outputDirectory.exists() } 171 | .flatMap { outputDirectory -> 172 | FileUtils.getFiles( 173 | outputDirectory, 174 | includePattern, 175 | excludePattern 176 | ) 177 | }.toSet() 178 | } 179 | 180 | private fun T?.asStringOrEmpty(toString: T.() -> String): String = if (this != null) { 181 | toString(this) 182 | } else { 183 | "" 184 | } 185 | 186 | private fun Set.throwIfEmpty(collectionDescription: String): Set { 187 | if (isEmpty()) { 188 | throw RuntimeException("$collectionDescription is empty") 189 | } 190 | return this 191 | } 192 | 193 | private companion object { 194 | const val ALL_FILES_PATTERN = "**" 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/surpsg/ReportsMapper.kt: -------------------------------------------------------------------------------- 1 | package io.github.surpsg 2 | 3 | import io.github.surpsg.deltacoverage.config.ReportConfig 4 | import io.github.surpsg.deltacoverage.config.ReportsConfig 5 | 6 | internal fun buildDeltaCoverageReportConfig( 7 | reportDir: String, 8 | reports: List, 9 | ) = ReportsConfig { 10 | val enabledReports: Map = buildEnableReportMap(reports) 11 | baseReportDir = reportDir 12 | html = ReportConfig { 13 | outputFileName = "html" 14 | enabled = enabledReports.getOrDefault("html", true) 15 | } 16 | xml = ReportConfig { 17 | outputFileName = "report.xml" 18 | enabled = enabledReports.getOrDefault("xml", true) 19 | } 20 | console = ReportConfig { 21 | outputFileName = "console.txt" 22 | enabled = enabledReports.getOrDefault("console", true) 23 | } 24 | markdown = ReportConfig { 25 | outputFileName = "report.md" 26 | enabled = enabledReports.getOrDefault("markdown", true) 27 | } 28 | fullCoverageReport = false 29 | } 30 | 31 | private fun buildEnableReportMap(reports: List): Map = reports.associate { 32 | requireNotNull(it.type) to it.enabled 33 | } 34 | --------------------------------------------------------------------------------