diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 339ec48ff..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,37 +0,0 @@ -version: 2 -updates: - - package-ecosystem: maven - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 - commit-message: - prefix: "" - ignore: - - dependency-name: org.eclipse.collections:eclipse-collections - versions: - - ">= 10.a" - - dependency-name: org.eclipse.collections:eclipse-collections-api - versions: - - ">= 10.a" - - - package-ecosystem: "github-actions" - directory: "/" - commit-message: - prefix: "" - schedule: - interval: "daily" - - - package-ecosystem: "npm" - directory: "/" - commit-message: - prefix: "" - schedule: - interval: "daily" - ignore: - - dependency-name: datatables.net-responsive - versions: - - "> 3.0.2" - - dependency-name: datatables.net-responsive-bs5 - versions: - - "> 3.0.2" diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 000000000..4d2c3749f --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["github>jenkinsci/renovate-config"], + "commitMessageAction": "Bump", + "ignorePaths": ["src/**"] +} diff --git a/.github/scripts/fetch-artifacts.sh b/.github/scripts/fetch-artifacts.sh index 3ed934cb4..379355426 100644 --- a/.github/scripts/fetch-artifacts.sh +++ b/.github/scripts/fetch-artifacts.sh @@ -9,7 +9,7 @@ set -euo pipefail # ARTIFACT_NAMES: comma-separated list of artifact names (in the same order as WORKFLOWS) # Optional: # RETRIES: number of polling attempts per workflow (default: 30) -# SLEEP_SEC: seconds to wait between attempts (default: 10) +# SLEEP_SEC: seconds to wait between attempts (default: 30) # ALLOWED_EVENTS: comma-separated list of workflow run events to consider (default: pull_request,pull_request_target) IFS=',' read -r -a WORKFLOWS_ARR <<< "${OTHER_WORKFLOWS}" @@ -19,7 +19,7 @@ SHA="${HEAD_SHA}" TOKEN="${TOKEN}" API_BASE="https://api.github.com/repos/${REPO}" RETRIES=${RETRIES:-30} -SLEEP_SEC=${SLEEP_SEC:-10} +SLEEP_SEC=${SLEEP_SEC:-60} ALLOWED_EVENTS=${ALLOWED_EVENTS:-pull_request,pull_request_target} mkdir -p artifacts diff --git a/.github/workflows/check-md-links.yml b/.github/workflows/check-md-links.yml index a0f09dc03..834e7f411 100644 --- a/.github/workflows/check-md-links.yml +++ b/.github/workflows/check-md-links.yml @@ -5,7 +5,7 @@ on: push jobs: check-markdown-links: name: 'Check Markdown links' - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: umbrelladocs/action-linkspector@v1.4.1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdaf28958..21dcd51c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Maven uses: stCarolas/setup-maven@v5 with: - maven-version: 3.9.11 + maven-version: 3.9.14 - name: Build with Maven env: BROWSER: chrome-container diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ede17e8d8..6fa51e1f9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,7 +35,7 @@ jobs: - name: Set up Maven uses: stCarolas/setup-maven@v5 with: - maven-version: 3.9.11 + maven-version: 3.9.14 - name: Initialize CodeQL uses: github/codeql-action/init@v4 diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml index beef84eaf..d10e43418 100644 --- a/.github/workflows/dependency-check.yml +++ b/.github/workflows/dependency-check.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Maven uses: stCarolas/setup-maven@v5 with: - maven-version: 3.9.12 + maven-version: 3.9.14 - name: Cache the NVD database uses: actions/cache@v5 with: @@ -40,7 +40,7 @@ jobs: exit 1; fi - name: Upload Dependency Report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: dependency-report path: | diff --git a/.github/workflows/quality-monitor-build.yml b/.github/workflows/quality-monitor-build.yml index 69e41aea0..81cd6d82b 100644 --- a/.github/workflows/quality-monitor-build.yml +++ b/.github/workflows/quality-monitor-build.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Maven uses: stCarolas/setup-maven@v5 with: - maven-version: 3.9.12 + maven-version: 3.9.14 - name: Check if quality monitor reports mutation coverage run: | FILE='.github/quality-monitor.json' @@ -44,11 +44,15 @@ jobs: exit 1; fi mv -fv maven.log target/maven.log + rm -rf target/tmp + - name: Write PR number + run: echo '${{ github.event.pull_request.number }}' > pr-number.txt - name: Upload Quality Reports - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: quality-reports path: | + pr-number.txt **/target/**/*.json **/target/**/*.xml **/target/**/*.log diff --git a/.github/workflows/quality-monitor-comment-pr.yml b/.github/workflows/quality-monitor-comment-pr.yml index 648630030..a405b6f4d 100644 --- a/.github/workflows/quality-monitor-comment-pr.yml +++ b/.github/workflows/quality-monitor-comment-pr.yml @@ -13,32 +13,13 @@ permissions: jobs: comment: - if: ${{ github.event.workflow_run.event == 'pull_request' }} + if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest name: Comment on PR steps: - - name: Extract PR number and SHA - id: pr - run: | - pr_number='${{ github.event.workflow_run.pull_requests[0].number }}' - echo "number=$pr_number" >> "$GITHUB_OUTPUT" - sha='${{ github.event.workflow_run.head_sha }}' - echo "sha=$sha" >> "$GITHUB_OUTPUT" - name: Checkout PR uses: actions/checkout@v6 - with: - ref: ${{ steps.pr.outputs.sha }} - - name: Install jq and unzip - run: sudo apt-get update && sudo apt-get install -y jq unzip - - name: Prepare environment - env: - HEAD_SHA: ${{ github.event.workflow_run.head_sha }} - REPO: ${{ github.repository }} - TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo "HEAD_SHA=$HEAD_SHA" - echo "REPO=$REPO" - name: Fetch reports from dependency check and quality monitor workflows env: REPO: ${{ github.repository }} @@ -46,8 +27,6 @@ jobs: TOKEN: ${{ secrets.GITHUB_TOKEN }} OTHER_WORKFLOWS: "quality-monitor-build.yml,dependency-check.yml" ARTIFACT_NAMES: "quality-reports,dependency-report" - RETRIES: 30 - SLEEP_SEC: 10 run: | chmod +x ./.github/scripts/fetch-artifacts.sh ./.github/scripts/fetch-artifacts.sh @@ -56,6 +35,27 @@ jobs: mkdir -p reports/target mv artifacts/*/target/* reports/target ls -la reports/target/* || true + mv artifacts/*/pr-number.txt reports/ + - name: Extract PR number and SHA + id: pr + run: | + pr_number="$(cat reports/pr-number.txt | tr -d '\r\n' | xargs)" + if [ -z "$pr_number" ] || [ "$pr_number" = "null" ]; then + echo "No PR associated with this workflow run" >&2 + exit 1 + fi + echo "PR number from reports/pr-number.txt: $pr_number" + echo "number=$pr_number" >> "$GITHUB_OUTPUT" + - name: Install jq and unzip + run: sudo apt-get update && sudo apt-get install -y jq unzip + - name: Prepare environment + env: + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + REPO: ${{ github.repository }} + TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "HEAD_SHA=$HEAD_SHA" + echo "REPO=$REPO" - name: Read Quality Monitor Configuration id: quality-monitor run: echo "json=$(jq -c . .github/quality-monitor-pr.json)" >> "$GITHUB_OUTPUT" @@ -65,7 +65,7 @@ jobs: - name: Run Quality Monitor and Comment on PR uses: uhafner/quality-monitor@v4 with: - sha: ${{ steps.pr.outputs.sha }} + sha: ${{ github.event.workflow_run.head_sha }} config: ${{ steps.quality-monitor.outputs.json }} quality-gates: ${{ steps.quality-gates.outputs.json }} pr-number: ${{ steps.pr.outputs.number }} diff --git a/.github/workflows/quality-monitor-comment.yml b/.github/workflows/quality-monitor-comment.yml index 968716974..cf23705f4 100644 --- a/.github/workflows/quality-monitor-comment.yml +++ b/.github/workflows/quality-monitor-comment.yml @@ -37,8 +37,6 @@ jobs: TOKEN: ${{ secrets.GITHUB_TOKEN }} OTHER_WORKFLOWS: "quality-monitor-build.yml,dependency-check.yml" ARTIFACT_NAMES: "quality-reports,dependency-report" - RETRIES: 30 - SLEEP_SEC: 10 run: | chmod +x ./.github/scripts/fetch-artifacts.sh ./.github/scripts/fetch-artifacts.sh diff --git a/README.md b/README.md index b308a21ed..df93fca58 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,9 @@ It has support for the following report formats: - [JaCoCo](https://www.jacoco.org/) code coverage results - [OpenCover](https://github.com/OpenCover/opencover) code coverage results - [VectorCAST](https://www.vector.com/int/en/products/products-a-z/software/vectorcast) code coverage results including MC/DC, Function, Function Call coverages +- [TRACE32](https://www.lauterbach.com) code coverage results - [PIT](https://pitest.org/) mutation coverage results -- [JUnit](https://junit.org/junit5/) test results +- [JUnit](https://junit.org) test results - [NUnit](https://nunit.org) test results - [XUnit](https://xunit.net) test results - [PMD software metrics](https://github.com/uhafner/codingstyle-pom/blob/main/pom.xml#L945-L960) via a patched version of [PMD](https://pmd.github.io/) @@ -113,6 +114,7 @@ The Coverage Plug-in supports the following report formats: - [Cobertura](https://cobertura.github.io/cobertura/): Code Coverage - [OpenCover](https://github.com/OpenCover/opencover): Code Coverage - [VectorCAST](https://www.vector.com/int/en/products/products-a-z/software/vectorcast) Code Coverage including MC/DC, Function, Function Call coverages +- [TRACE32](https://www.lauterbach.com) Code Coverage - [PIT](https://pitest.org/): Mutation Coverage - [JUnit](https://ant.apache.org/manual/Tasks/junitreport.html): Test Results - [NUnit](https://nunit.org/): Test Results diff --git a/plugin/pom.xml b/plugin/pom.xml index 24cb798a3..da2c918bd 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -13,7 +13,7 @@ Coverage Plugin Collects reports of code coverage or mutation coverage tools and visualizes the results. It has support - for the following report formats: JaCoCo, Cobertura, and PIT. + for the following report formats: JaCoCo, Cobertura, PIT and TRACE32. https://github.com/jenkinsci/coverage-plugin @@ -35,14 +35,15 @@ false - 0.66.0 + 0.67.0 2.11.0 - 1.21.4 + 2.0.4 + edu.hm.hafner coverage-model @@ -87,6 +88,7 @@ jsoup + io.jenkins.plugins ionicons-api @@ -96,8 +98,6 @@ token-macro true - - org.jenkins-ci.plugins.workflow workflow-multibranch @@ -111,8 +111,8 @@ workflow-step-api - org.jenkins-ci.plugins - jackson2-api + io.jenkins.plugins + jackson3-api io.jenkins.plugins @@ -121,6 +121,7 @@ io.jenkins.plugins echarts-api + 6.0.0-1279.v4e95ca_f54783 io.jenkins.plugins @@ -133,6 +134,7 @@ io.jenkins.plugins data-tables-api + 2.3.7-1556.vb_8e745408397 io.jenkins.plugins @@ -141,6 +143,7 @@ io.jenkins.plugins plugin-util-api + 7.1330.v47b_46ee2047a_ io.jenkins.plugins @@ -149,16 +152,13 @@ io.jenkins.plugins prism-api - 1.30.0-703.v116fb_3b_5b_b_a_a_ - - - io.jenkins.plugins - plugin-util-api - tests - test + org.jenkins-ci.plugins + variant + + org.xmlunit xmlunit-core @@ -191,6 +191,21 @@ + + org.testcontainers + testcontainers + ${testcontainers.version} + test + + + + + io.jenkins.plugins + plugin-util-api + 7.1320.v684dd26fca_19 + tests + test + org.jenkins-ci.plugins.workflow workflow-cps @@ -252,7 +267,6 @@ timestamper test - org.jenkins-ci.plugins ssh-credentials @@ -263,24 +277,6 @@ ssh-slaves test - - org.testcontainers - testcontainers - ${testcontainers.version} - test - - - org.apache.commons - commons-compress - - - - - org.testcontainers - junit-jupiter - ${testcontainers.version} - test - io.jenkins configuration-as-code diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java index 795d63a70..335db6689 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java @@ -63,6 +63,11 @@ public LinesChartModel create(final Iterable> re addSeriesIfAvailable(dataSet, model, Metric.MCDC_PAIR, JenkinsPalette.RED.light()); addSeriesIfAvailable(dataSet, model, Metric.FUNCTION_CALL, JenkinsPalette.RED.dark()); + /* TRACE32 metrics */ + addSeriesIfAvailable(dataSet, model, Metric.STMT_DC, JenkinsPalette.RED.light()); + addSeriesIfAvailable(dataSet, model, Metric.STMT_CC, JenkinsPalette.RED.light()); + addSeriesIfAvailable(dataSet, model, Metric.CONDITION, JenkinsPalette.RED.normal()); + model.useContinuousRangeAxis(); model.computeVisibleRange(); model.setRangeMax(100); // Restrict the range to 100% diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/FileWithModifiedLines.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/FileWithModifiedLines.java index d33463e33..838104df2 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/FileWithModifiedLines.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/FileWithModifiedLines.java @@ -22,12 +22,12 @@ class FileWithModifiedLines { } @Exported(inline = true) - public String getFullyQualifiedFileName() { + String getFullyQualifiedFileName() { return fullyQualifiedFileName; } @Exported(inline = true) - public SortedSet getModifiedLinesBlocks() { + SortedSet getModifiedLinesBlocks() { return modifiedLinesBlocks; } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesBlock.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesBlock.java index 86f250e64..a7b9539bf 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesBlock.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesBlock.java @@ -24,17 +24,17 @@ class ModifiedLinesBlock implements Comparable { } @Exported - public int getStartLine() { + int getStartLine() { return startLine; } @Exported - public int getEndLine() { + int getEndLine() { return endLine; } @Exported - public LineCoverageType getType() { + LineCoverageType getType() { return type; } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesCoverageApi.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesCoverageApi.java index 06087e17e..314f8d785 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesCoverageApi.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesCoverageApi.java @@ -25,7 +25,7 @@ class ModifiedLinesCoverageApi { } @Exported(inline = true, name = "files") - public List getFilesWithModifiedLines() { + List getFilesWithModifiedLines() { return filesWithModifiedLines; } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/CoverageSourcePrinter.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/CoverageSourcePrinter.java index 3ecce4785..aa9a95d5d 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/CoverageSourcePrinter.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/CoverageSourcePrinter.java @@ -8,6 +8,7 @@ import java.io.Serial; import java.io.Serializable; import java.util.Arrays; +import java.util.NavigableSet; import java.util.TreeSet; import io.jenkins.plugins.prism.Sanitizer; @@ -36,8 +37,8 @@ class CoverageSourcePrinter implements Serializable { private final int[] missedPerLine; - @SuppressWarnings("PMD.LooseCoupling") - private final TreeSet modifiedLines; + @SuppressWarnings("serial") + private final NavigableSet modifiedLines; CoverageSourcePrinter(final FileNode file) { path = file.getRelativePath(); @@ -48,7 +49,7 @@ class CoverageSourcePrinter implements Serializable { modifiedLines = new TreeSet<>(file.getModifiedLines()); } - public String renderLine(final int line, final String sourceCode) { + String renderLine(final int line, final String sourceCode) { var isPainted = isPainted(line); return tr() .withClasses(isPainted ? getColorClass(line) : UNDEFINED, getModifiedClass(line)) @@ -79,7 +80,7 @@ String getModifiedClass(final int line) { return isModified(line) ? MODIFIED : StringUtils.EMPTY; } - public String getColorClass(final int line) { + String getColorClass(final int line) { if (getCovered(line) == 0) { return NO_COVERAGE; } @@ -91,7 +92,7 @@ else if (getMissed(line) == 0) { } } - public String getTooltip(final int line) { + String getTooltip(final int line) { var covered = getCovered(line); var missed = getMissed(line); if (covered + missed > 1) { @@ -111,7 +112,7 @@ else if (covered == 1) { } } - public String getSummaryColumn(final int line) { + String getSummaryColumn(final int line) { var covered = getCovered(line); var missed = getMissed(line); if (covered + missed > 1) { @@ -120,11 +121,11 @@ public String getSummaryColumn(final int line) { return String.valueOf(covered); } - public final String getPath() { + final String getPath() { return path; } - public boolean isPainted(final int line) { + boolean isPainted(final int line) { return findIndexOfLine(line) >= 0; } @@ -136,11 +137,11 @@ int findIndexOfLine(final int line) { return Arrays.binarySearch(linesToPaint, line); } - public int getCovered(final int line) { + int getCovered(final int line) { return getCounter(line, coveredPerLine); } - public int getMissed(final int line) { + int getMissed(final int line) { return getCounter(line, missedPerLine); } @@ -152,7 +153,7 @@ int getCounter(final int line, final int... counters) { return 0; } - public String getColumnHeader() { + String getColumnHeader() { return StringUtils.EMPTY; } } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/MutationSourcePrinter.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/MutationSourcePrinter.java index ea1b6f846..f6293b71e 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/MutationSourcePrinter.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/MutationSourcePrinter.java @@ -84,11 +84,11 @@ private List asBulletPoints(final List mutations, final .collect(Collectors.toList()); } - public int getSurvived(final int line) { + int getSurvived(final int line) { return getCounter(line, survivedPerLine); } - public int getKilled(final int line) { + int getKilled(final int line) { return getCounter(line, killedPerLine); } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/SourceCodePainter.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/SourceCodePainter.java index eac033377..5d721b5b8 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/SourceCodePainter.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/source/SourceCodePainter.java @@ -123,8 +123,8 @@ static class AgentCoveragePainter extends MasterToSlaveFileCallable @Serial private static final long serialVersionUID = 3966282357309568323L; - @SuppressWarnings("PMD.LooseCoupling") - private final ArrayList paintedFiles; + @SuppressWarnings("serial") + private final List paintedFiles; private final String sourceCodeEncoding; private final String directory; diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CodeDeltaCalculator.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CodeDeltaCalculator.java index 43f59c635..e24d341b7 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CodeDeltaCalculator.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CodeDeltaCalculator.java @@ -79,7 +79,7 @@ class CodeDeltaCalculator { * * @return the {@link Delta code delta} as Optional if existent, else an empty Optional */ - public Optional calculateCodeDeltaToReference(final Run referenceBuild, final FilteredLog log) { + Optional calculateCodeDeltaToReference(final Run referenceBuild, final FilteredLog log) { return DeltaCalculatorFactory .findDeltaCalculator(scm, build, workspace, listener, log) .calculateDelta(build, referenceBuild, log); @@ -93,7 +93,7 @@ public Optional calculateCodeDeltaToReference(final Run referenceBu * * @return the relevant code changes */ - public Set getCoverageRelevantChanges(final Delta delta) { + Set getCoverageRelevantChanges(final Delta delta) { return delta.getFileChangesMap().values().stream() .filter(fileChange -> fileChange.getFileEditType() == FileEditType.MODIFY || fileChange.getFileEditType() == FileEditType.ADD @@ -116,7 +116,7 @@ public Set getCoverageRelevantChanges(final Delta delta) { * @throws IllegalStateException * when creating the mapping failed due to ambiguous paths */ - public Map mapScmChangesToReportPaths( + Map mapScmChangesToReportPaths( final Set changes, final Node root, final FilteredLog log) throws IllegalStateException { Set reportPaths = new HashSet<>(root.getFiles()); Set scmPaths = changes.stream().map(FileChanges::getFileName).collect(Collectors.toSet()); @@ -150,7 +150,7 @@ public Map mapScmChangesToReportPaths( * @throws IllegalStateException * if the SCM path mapping is ambiguous */ - public Map createOldPathMapping(final Node root, final Node referenceRoot, + Map createOldPathMapping(final Node root, final Node referenceRoot, final Map changes, final FilteredLog log) throws IllegalStateException { Set oldReportPaths = new HashSet<>(referenceRoot.getFiles()); diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageBuildAction.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageBuildAction.java index 6692cd4ec..8c85f7b63 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageBuildAction.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageBuildAction.java @@ -6,7 +6,6 @@ import edu.hm.hafner.coverage.Metric; import edu.hm.hafner.coverage.Node; import edu.hm.hafner.coverage.Value; -import edu.hm.hafner.echarts.JacksonFacade; import edu.hm.hafner.util.FilteredLog; import edu.hm.hafner.util.VisibleForTesting; import edu.umd.cs.findbugs.annotations.NonNull; @@ -24,6 +23,7 @@ import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.Stream; +import tools.jackson.databind.ObjectMapper; import org.kohsuke.stapler.StaplerProxy; import hudson.Functions; @@ -73,41 +73,41 @@ public final class CoverageBuildAction extends BuildAction implements Stap private final FilteredLog log; /** The aggregated values of the result for the root of the tree. */ - @SuppressWarnings("PMD.LooseCoupling") - private final ArrayList projectValues; + @SuppressWarnings("serial") + private final List projectValues; /** The delta of this build's coverages with respect to the reference build. */ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @SuppressFBWarnings(value = "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", justification = "Not used anymore") private transient NavigableMap difference; - @SuppressWarnings("PMD.LooseCoupling") - private /* almost final */ ArrayList differences; // since 2.0.0 + @SuppressWarnings("serial") + private /* almost final */ List differences; // since 2.0.0 /** The coverages filtered by modified lines of the associated change request. */ - @SuppressWarnings("PMD.LooseCoupling") - private final ArrayList modifiedLinesCoverage; + @SuppressWarnings("serial") + private final List modifiedLinesCoverage; /** The coverage delta of the associated change request with respect to the reference build. */ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @SuppressFBWarnings(value = "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", justification = "Not used anymore") private transient NavigableMap modifiedLinesCoverageDifference; - @SuppressWarnings("PMD.LooseCoupling") - private /* almost final */ ArrayList modifiedLinesDifferences; // since 2.0.0 + @SuppressWarnings("serial") + private /* almost final */ List modifiedLinesDifferences; // since 2.0.0 /** The coverage of the modified lines. */ - @SuppressWarnings("PMD.LooseCoupling") - private final ArrayList modifiedFilesCoverage; + @SuppressWarnings("serial") + private final List modifiedFilesCoverage; /** The coverage delta of the modified lines. */ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @SuppressFBWarnings(value = "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", justification = "Not used anymore") private transient NavigableMap modifiedFilesCoverageDifference; - @SuppressWarnings("PMD.LooseCoupling") - private /* almost final */ ArrayList modifiedFilesDifferences; // since 2.0.0 + @SuppressWarnings("serial") + private /* almost final */ List modifiedFilesDifferences; // since 2.0.0 /** The indirect coverage changes of the associated change request with respect to the reference build. */ - @SuppressWarnings("PMD.LooseCoupling") - private final ArrayList indirectCoverageChanges; + @SuppressWarnings("serial") + private final List indirectCoverageChanges; static { CoverageXmlStream.registerConverters(XSTREAM2); @@ -235,8 +235,7 @@ public CoverageBuildAction(final Run owner, final String id, final String } } - @SuppressWarnings("PMD.LooseCoupling") - private ArrayList copy(final List list) { + private List copy(final List list) { return new ArrayList<>(list); // do not use immutable collections to simplify serialization } @@ -649,7 +648,8 @@ NavigableSet getMetricsForSummary() { // software metrics Metric.LOC, Metric.NCSS, Metric.TESTS, Metric.CYCLOMATIC_COMPLEXITY, Metric.COGNITIVE_COMPLEXITY, Metric.NPATH_COMPLEXITY, - Metric.MCDC_PAIR, Metric.FUNCTION_CALL)); + Metric.MCDC_PAIR, Metric.FUNCTION_CALL + )); } /** @@ -698,11 +698,11 @@ public CoverageViewModel getTarget() { } private String createCoverageModel(final String configuration) { - return new JacksonFacade().toJson(new TrendChartFactory().createChartModel(configuration, this)); + return new ObjectMapper().writeValueAsString(new TrendChartFactory().createChartModel(configuration, this)); } private String createMetricsModel(final String configuration) { - return new JacksonFacade().toJson(new TrendChartFactory().createMetricsModel(configuration, this)); + return new ObjectMapper().writeValueAsString(new TrendChartFactory().createMetricsModel(configuration, this)); } @NonNull diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumn.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumn.java index fa839370a..2441ef3c1 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumn.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumn.java @@ -249,8 +249,7 @@ private static CoverageAppearanceConfiguration getConfiguration(final JenkinsFac /** * Descriptor of the column. */ - @Extension(optional = true) - @Symbol("coverageTotalsColumn") + @Extension @Symbol("coverageTotalsColumn") public static class CoverageMetricColumnDescriptor extends ListViewColumnDescriptor { private final JenkinsFacade jenkins; diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageStep.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageStep.java index 7d16fab3c..f11eda494 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageStep.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageStep.java @@ -57,10 +57,10 @@ public class CoverageStep extends Step implements Serializable { private static final long serialVersionUID = 34386077204781270L; private static final ValidationUtilities VALIDATION_UTILITIES = new ValidationUtilities(); - @SuppressWarnings("PMD.LooseCoupling") - private ArrayList tools = new ArrayList<>(); - @SuppressWarnings("PMD.LooseCoupling") - private ArrayList qualityGates = new ArrayList<>(); + @SuppressWarnings("serial") + private List tools = new ArrayList<>(); + @SuppressWarnings("serial") + private List qualityGates = new ArrayList<>(); private String id = StringUtils.EMPTY; private String name = StringUtils.EMPTY; private boolean skipPublishingChecks = false; @@ -72,8 +72,8 @@ public class CoverageStep extends Step implements Serializable { private boolean skipSymbolicLinks = false; private String scm = StringUtils.EMPTY; private String sourceCodeEncoding = StringUtils.EMPTY; - @SuppressWarnings("PMD.LooseCoupling") - private HashSet sourceDirectories = new HashSet<>(); + @SuppressWarnings("serial") + private Set sourceDirectories = new HashSet<>(); private SourceCodeRetention sourceCodeRetention = SourceCodeRetention.LAST_BUILD; /** diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTableModel.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTableModel.java index b5de91577..9267e2dec 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTableModel.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTableModel.java @@ -129,6 +129,12 @@ public List getColumns() { configureValueColumn("testStrength", Metric.TEST_STRENGTH, Messages.Column_TestStrength(), Messages.Column_DeltaTestStrength("Δ"), columns); + /* TRACE32 metrics */ + configureValueColumn("stmtDcCoverage", Metric.STMT_DC, Metric.STMT_DC.getDisplayName(), SKIP_DELTA, columns); + configureValueColumn("stmtCcCoverage", Metric.STMT_CC, Metric.STMT_CC.getDisplayName(), SKIP_DELTA, columns); + configureValueColumn("conditionCoverage", Metric.CONDITION, Metric.CONDITION.getDisplayName(), SKIP_DELTA, columns); + configureValueColumn("bytesCoverage", Metric.BYTES, Metric.BYTES.getDisplayName(), SKIP_DELTA, columns); + var entries = new EnumMap<>(Map.of( Metric.LOC, 200, Metric.TESTS, 500, @@ -197,6 +203,7 @@ protected ColorProvider getColorProvider() { /** * UI row model for the coverage details table. */ + @SuppressWarnings("PMD.PublicMemberInNonPublicType") static class CoverageRow { private static final String COVERAGE_COLUMN_OUTER = "coverage-cell-outer float-end"; private static final String COVERAGE_COLUMN_INNER = "coverage-jenkins-cell-inner"; @@ -247,6 +254,10 @@ public DetailedCell getBranchCoverage() { return createColoredCoverageColumn(getCoverageOfNode(Metric.BRANCH)); } + public DetailedCell getInstructionCoverage() { + return createColoredCoverageColumn(getCoverageOfNode(Metric.INSTRUCTION)); + } + public DetailedCell getMethodCoverage() { return createColoredCoverageColumn(getCoverageOfNode(Metric.METHOD)); } @@ -267,7 +278,23 @@ public DetailedCell getTestStrength() { return createColoredCoverageColumn(getCoverageOfNode(Metric.TEST_STRENGTH)); } - Coverage getCoverageOfNode(final Metric metric) { + public DetailedCell getStmtDcCoverage() { + return createColoredCoverageColumn(getCoverageOfNode(Metric.STMT_DC)); + } + + public DetailedCell getStmtCcCoverage() { + return createColoredCoverageColumn(getCoverageOfNode(Metric.STMT_CC)); + } + + public DetailedCell getConditionCoverage() { + return createColoredCoverageColumn(getCoverageOfNode(Metric.CONDITION)); + } + + public DetailedCell getBytesCoverage() { + return createColoredCoverageColumn(getCoverageOfNode(Metric.BYTES)); + } + + public Coverage getCoverageOfNode(final Metric metric) { return file.getTypedValue(metric, Coverage.nullObject(metric)); } @@ -279,6 +306,10 @@ public DetailedCell getBranchCoverageDelta() { return createColoredFileCoverageDeltaColumn(Metric.BRANCH); } + public DetailedCell getInstructionCoverageDelta() { + return createColoredFileCoverageDeltaColumn(Metric.INSTRUCTION); + } + public DetailedCell getMutationCoverageDelta() { return createColoredFileCoverageDeltaColumn(Metric.MUTATION); } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTokenMacro.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTokenMacro.java index 5cb8f50ba..662d25ffd 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTokenMacro.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTokenMacro.java @@ -7,7 +7,7 @@ import java.util.function.Predicate; import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro; -import hudson.Extension; +import org.jenkinsci.plugins.variant.OptionalExtension; import hudson.FilePath; import hudson.model.AbstractBuild; import hudson.model.Run; @@ -17,11 +17,11 @@ import io.jenkins.plugins.coverage.metrics.model.ElementFormatter; /** - * Provides a token that evaluates to the number of issues. + * Provides a token that evaluates the number of issues. * * @author Ullrich Hafner */ -@Extension(optional = true) +@OptionalExtension(requireClasses = DataBoundTokenMacro.class) public class CoverageTokenMacro extends DataBoundTokenMacro { private static final ElementFormatter FORMATTER = new ElementFormatter(); static final String COVERAGE = "COVERAGE"; diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTool.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTool.java index 72385d598..47d01dc88 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTool.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageTool.java @@ -250,7 +250,10 @@ public enum Parser { "symbol-footsteps-outline plugin-ionicons-api"), XUNIT(Messages._Parser_Xunit(), ParserType.TEST, "**/xunit.xml,**/TestResult.xml", - "symbol-solid/list-check plugin-font-awesome-api"); + "symbol-solid/list-check plugin-font-awesome-api"), + TRACE32(Messages._Parser_TRACE32(), ParserType.COVERAGE, + "**/index.xml", + "symbol-footsteps-outline plugin-ionicons-api"); private final Localizable displayName; private final ParserType parserType; diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java index 03f55c5ba..c63527e01 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel.java @@ -4,9 +4,8 @@ import org.apache.commons.lang3.Strings; import org.apache.commons.lang3.exception.ExceptionUtils; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import edu.hm.hafner.coverage.Coverage; import edu.hm.hafner.coverage.FileNode; @@ -35,6 +34,7 @@ import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.bind.JavaScriptMethod; +import tools.jackson.core.JacksonException; import hudson.model.Api; import hudson.model.ModelObject; import hudson.model.Run; @@ -81,8 +81,9 @@ public class CoverageViewModel extends DefaultAsyncTableContentProvider implemen private static final ElementFormatter FORMATTER = new ElementFormatter(); private static final Set TREE_METRICS = Set.of( - Metric.LINE, Metric.BRANCH, Metric.MUTATION, Metric.TEST_STRENGTH, Metric.CYCLOMATIC_COMPLEXITY, Metric.TESTS, - Metric.MCDC_PAIR, Metric.FUNCTION_CALL, Metric.COGNITIVE_COMPLEXITY, Metric.NCSS, Metric.NPATH_COMPLEXITY); + Metric.LINE, Metric.BRANCH, Metric.INSTRUCTION, Metric.MUTATION, Metric.TEST_STRENGTH, Metric.CYCLOMATIC_COMPLEXITY, + Metric.TESTS, Metric.MCDC_PAIR, Metric.FUNCTION_CALL, Metric.COGNITIVE_COMPLEXITY, Metric.NCSS, Metric.NPATH_COMPLEXITY, + Metric.STMT_DC, Metric.STMT_CC, Metric.CONDITION, Metric.BYTES); private final Run owner; private final String displayName; private final CoverageStatistics statistics; @@ -240,7 +241,7 @@ private ColorProvider createColorProvider(final String json) { Map colorMapping = mapper.readValue(json, new ColorMappingType()); return ColorProviderFactory.createColorProvider(colorMapping); } - catch (JsonProcessingException e) { + catch (JacksonException e) { return ColorProviderFactory.createDefaultColorProvider(); } } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageXmlStream.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageXmlStream.java index 2b85ca7ea..98363efca 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageXmlStream.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageXmlStream.java @@ -66,7 +66,7 @@ private static String[] toArray(final String value) { } @VisibleForTesting - public XStream2 getStream() { + XStream2 getStream() { return createStream(); } @@ -169,7 +169,7 @@ protected Entry createMapping(final String key, final String valu * @param * type of the objects that will be marshalled and unmarshalled */ - public static class SimpleConverter implements Converter { + static class SimpleConverter implements Converter { private final Class type; private final Function marshaller; private final Function unmarshaller; diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/PathResolver.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/PathResolver.java index 8e15e498c..4975c440d 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/PathResolver.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/PathResolver.java @@ -81,12 +81,12 @@ static class AgentPathResolver extends MasterToSlaveFileCallable relativePaths; - @SuppressWarnings("PMD.LooseCoupling") - private final HashSet permittedSourceDirectories; - @SuppressWarnings("PMD.LooseCoupling") - private final HashSet requestedSourceDirectories; + @SuppressWarnings("serial") + private final Set relativePaths; + @SuppressWarnings("serial") + private final Set permittedSourceDirectories; + @SuppressWarnings("serial") + private final Set requestedSourceDirectories; /** * Creates a new instance of {@link AgentPathResolver}. diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/TrendChartFactory.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/TrendChartFactory.java index 3796bb220..e338320b1 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/TrendChartFactory.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/TrendChartFactory.java @@ -1,19 +1,17 @@ package io.jenkins.plugins.coverage.metrics.steps; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - import edu.hm.hafner.coverage.Metric; import edu.hm.hafner.coverage.Value; import edu.hm.hafner.echarts.ChartModelConfiguration; -import edu.hm.hafner.echarts.JacksonFacade; import edu.hm.hafner.echarts.line.LinesChartModel; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ObjectNode; import io.jenkins.plugins.coverage.metrics.charts.CoverageTrendChart; import io.jenkins.plugins.coverage.metrics.charts.MetricsTrendChart; @@ -27,7 +25,6 @@ * @author Ullrich Hafner */ class TrendChartFactory { - private static final JacksonFacade JACKSON = new JacksonFacade(); static final Set DEFAULT_TREND_METRICS = Set.of( Metric.LINE, Metric.BRANCH, Metric.MUTATION, Metric.TEST_STRENGTH, @@ -62,7 +59,22 @@ private LinesChartModel getLinesChartModel(final String configuration, final Cov } private boolean useLines(final String configuration) { - return JACKSON.getBoolean(configuration, "useLines", false); + return getBoolean(configuration, "useLines", false); + } + + private boolean getBoolean(final String json, final String property, final boolean defaultValue) { + try { + var node = new ObjectMapper().readValue(json, ObjectNode.class); + var typeNode = node.get(property); + if (typeNode != null) { + return typeNode.asBoolean(defaultValue); + } + } + catch (JacksonException exception) { + // ignore + } + + return defaultValue; } Set getVisibleMetrics(final String configuration) { @@ -80,7 +92,7 @@ Set getVisibleMetrics(final String configuration) { .collect(Collectors.toSet()); } } - catch (JsonProcessingException | ClassCastException | IllegalArgumentException ignored) { + catch (JacksonException | ClassCastException | IllegalArgumentException ignored) { // ignore and return default values } diff --git a/plugin/src/main/resources/META-INF/hudson.remoting.ClassFilter b/plugin/src/main/resources/META-INF/hudson.remoting.ClassFilter index 210eb9d5f..0b37d197f 100644 --- a/plugin/src/main/resources/META-INF/hudson.remoting.ClassFilter +++ b/plugin/src/main/resources/META-INF/hudson.remoting.ClassFilter @@ -21,6 +21,7 @@ edu.hm.hafner.coverage.Percentage edu.hm.hafner.coverage.SafeFraction edu.hm.hafner.coverage.TestCase edu.hm.hafner.coverage.Value +edu.hm.hafner.coverage.Rate java.util.ImmutableCollections$ListN java.util.ImmutableCollections$SetN diff --git a/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/model/Messages.properties b/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/model/Messages.properties index b718e51e0..9792468b8 100644 --- a/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/model/Messages.properties +++ b/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/model/Messages.properties @@ -19,6 +19,10 @@ Metric.FUNCTION_CALL=Function Call Coverage Metric.NCSS=NCSS Metric.COGNITIVE_COMPLEXITY=Cognitive Complexity Metric.NPATH=NPath Complexity +Metric.STMT_DC=Statement + Decision Coverage +Metric.STMT_CC=Statement + Condition Coverage +Metric.CONDITION=Condition Coverage +Metric.BYTES=Bytes Coverage Metric.Short.CONTAINER=Container Metric.Short.MODULE=Module @@ -41,6 +45,10 @@ Metric.Short.FUNCTION_CALL=Function Call Metric.Short.NCSS=NCSS Metric.Short.COGNITIVE_COMPLEXITY=Cognitive Complexity Metric.Short.NPATH=NPath Complexity +Metric.Short.STMT_DC=Statement + DC +Metric.Short.STMT_CC=Statement + CC +Metric.Short.CONDITION=Condition +Metric.Short.BYTES=Bytes Metric.MUTATION.Killed=Killed Metric.MUTATION.Survived=Survived diff --git a/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel/view-model.js b/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel/view-model.js index aa85e1120..cb7323684 100644 --- a/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel/view-model.js +++ b/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModel/view-model.js @@ -1,4 +1,4 @@ -/* global $, proxy, echartsJenkinsApi, bootstrap5 */ +/* global $, proxy, echartsJenkinsApi, bootstrap5, culori */ (function ($) { function fillDialog(trendConfiguration, jsonConfiguration) { @@ -34,7 +34,7 @@ if (colorHex.match(/^#[a-fA-F0-9]{6}$/) !== null) { colorHexMapping.set(jenkinsId, colorHex); } - }) + }); return colorHexMapping; } @@ -42,8 +42,12 @@ return echartsJenkinsApi.resolveJenkinsColor(colorName); } - function printPercentage(value, minimumFractionDigits = 2) { - return Number(value / 100.0).toLocaleString(undefined, {style: 'percent', minimumFractionDigits: minimumFractionDigits}); + function printPercentage(value, minimumFractionDigits) { + const options = { + style: 'percent', + minimumFractionDigits: minimumFractionDigits ? minimumFractionDigits : 2 + }; + return Number(value / 100.0).toLocaleString(undefined, options); } const openBuild = function (build) { // NOPMD @@ -439,7 +443,7 @@ return true; } - return false + return false; } const selectedTabID = 'jenkins-coverage-activeTab'; @@ -595,7 +599,7 @@ else { showNoSelection(); } - }) + }); datatable.on('deselect', function () { showNoSelection(); }); diff --git a/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/Messages.properties b/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/Messages.properties index 081179106..aeb43e711 100644 --- a/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/Messages.properties +++ b/plugin/src/main/resources/io/jenkins/plugins/coverage/metrics/steps/Messages.properties @@ -12,6 +12,7 @@ Parser.OpenCover=OpenCover Coverage Reports Parser.PIT=PIT Mutation Testing Reports Parser.VectorCAST=VectorCAST Coverage Results Parser.Xunit=XUnit Test Results +Parser.TRACE32=TRACE32 Coverage Reports Coverage.Not.Available=N/A Coverage.Permission.Denied=You do not have Jenkins' WORKSPACE permission to view the source code @@ -32,6 +33,8 @@ Column.LineCoverage=Line Column.DeltaLineCoverage=Line {0} Column.BranchCoverage=Branch Column.DeltaBranchCoverage=Branch {0} +Column.InstructionCoverage=Instruction +Column.DeltaInstructionCoverage=Instruction {0} Column.MutationCoverage=Mutation Column.TestStrength=Test Strength Column.DeltaMutationCoverage=Mutation {0} diff --git a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/source/DockerAgentSourceCodeITest.java b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/source/DockerAgentSourceCodeITest.java index 5da9deb53..cbd2ca67f 100644 --- a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/source/DockerAgentSourceCodeITest.java +++ b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/source/DockerAgentSourceCodeITest.java @@ -1,8 +1,6 @@ package io.jenkins.plugins.coverage.metrics.source; import org.junit.jupiter.api.Disabled; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.MountableFile; import java.io.IOException; @@ -11,11 +9,10 @@ import hudson.model.Node; /** - * Verifies if source code copying and rendering works on Docker agents. + * Verifies if source code copying and rendering work on Docker agents. * * @author Ullrich Hafner */ -@Testcontainers(disabledWithoutDocker = true) @Disabled("Docker tests are failing with Java 17 Jenkins") class DockerAgentSourceCodeITest extends SourceCodeITest { private static final String SOURCES_IN_DOCKER_PATH = "/tmp/coverage"; @@ -23,7 +20,6 @@ class DockerAgentSourceCodeITest extends SourceCodeITest { private static final String PATH_UTIL_CONTAINER_PATH = SOURCES_IN_DOCKER_PATH + "/" + PATH_UTIL_PACKAGE_PATH + PATH_UTIL_FILE_NAME; private static final String RESOURCES = "io/jenkins/plugins/coverage/metrics/source/"; - @Container private static final AgentContainer AGENT_CONTAINER = new AgentContainer() .withCopyFileToContainer( MountableFile.forClasspathResource(RESOURCES + ACU_COBOL_PARSER_SOURCE_FILE), diff --git a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumnTest.java b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumnTest.java index 9d6e2e545..1872aab65 100644 --- a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumnTest.java +++ b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageMetricColumnTest.java @@ -70,7 +70,7 @@ void shouldAllowEnums() { * @return the created stub */ @VisibleForTesting - public static Job createJobWithActions(final CoverageBuildAction... actions) { + static Job createJobWithActions(final CoverageBuildAction... actions) { Job job = mock(Job.class); Run build = createBuildWithActions(actions); when(job.getLastCompletedBuild()).thenAnswer(a -> build); @@ -86,7 +86,7 @@ void shouldAllowEnums() { * @return the created stub */ @VisibleForTesting - public static Run createBuildWithActions(final CoverageBuildAction... actions) { + static Run createBuildWithActions(final CoverageBuildAction... actions) { Run build = mock(Run.class); when(build.getActions(CoverageBuildAction.class)).thenReturn(Arrays.asList(actions)); if (actions.length > 0) { diff --git a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoveragePluginITest.java b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoveragePluginITest.java index b1140e75e..4461a2186 100644 --- a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoveragePluginITest.java +++ b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoveragePluginITest.java @@ -181,6 +181,7 @@ private void verifyJaCoCoAction(final CoverageBuildAction coverageResult) { "Package", "Line", "Branch", + "Instruction", "LOC", "Complexity"); assertThat(tableModel.getRows()) diff --git a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModelTest.java b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModelTest.java index a10e2ad2e..b14814d2e 100644 --- a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModelTest.java +++ b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/CoverageViewModelTest.java @@ -57,6 +57,8 @@ void shouldReportOverview() { .contains("title=\"edu/hm/hafner/util/", "data-bs-toggle=\"tooltip\" data-bs-placement=\"top\"")) ); + + assertThat(model.getTableRows(ABSOLUTE_COVERAGE_TABLE_ID)).startsWith("[{\"branchCoverage\":{\"display\":\"
percentages) { diff --git a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/GitForensicsITest.java b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/GitForensicsITest.java index 6e07f442c..b9cba9d7d 100644 --- a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/GitForensicsITest.java +++ b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/steps/GitForensicsITest.java @@ -6,8 +6,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; import edu.hm.hafner.coverage.Coverage; import edu.hm.hafner.coverage.Difference; @@ -44,7 +42,6 @@ * @author Florian Orendi */ @Disabled("Docker tests are failing with Java 17 Jenkins") -@Testcontainers(disabledWithoutDocker = true) class GitForensicsITest extends AbstractCoverageITest { /** The JaCoCo coverage report, generated for the commit {@link #COMMIT}. */ private static final String JACOCO_FILE = "forensics_integration.xml"; @@ -56,7 +53,6 @@ class GitForensicsITest extends AbstractCoverageITest { private static final String REPOSITORY = "https://github.com/jenkinsci/forensics-api-plugin.git"; - @Container private static final AgentContainer AGENT_CONTAINER = new AgentContainer(); @ParameterizedTest(name = "Source code retention {0} should store {1} files") @@ -116,8 +112,10 @@ void shouldVerifyQualityGate(final Baseline baseline, final double threshold, fi verifyGitRepositoryForCommit(referenceBuild, COMMIT_REFERENCE); String qualityGate = String.format(", qualityGates: [" - + " [threshold: %f, metric: 'LINE', baseline: '%s', criticality: 'UNSTABLE']]", threshold, baseline.name()); - project.setDefinition(createPipelineForCommit(node, COMMIT, JACOCO_FILE, SourceCodeRetention.EVERY_BUILD, qualityGate)); + + " [threshold: %f, metric: 'LINE', baseline: '%s', criticality: 'UNSTABLE']]", threshold, + baseline.name()); + project.setDefinition( + createPipelineForCommit(node, COMMIT, JACOCO_FILE, SourceCodeRetention.EVERY_BUILD, qualityGate)); Run build = buildWithResult(project, Result.UNSTABLE); verifyCoverage(build.getAction(CoverageBuildAction.class), referenceBuild.getAction(CoverageBuildAction.class)); @@ -127,10 +125,12 @@ void shouldVerifyQualityGate(final Baseline baseline, final double threshold, fi if (baseline == Baseline.PROJECT_DELTA || baseline == Baseline.MODIFIED_FILES_DELTA || baseline == Baseline.MODIFIED_LINES_DELTA) { - assertThat(getConsoleLog(build)).contains("≪Unstable≫ - (Actual value: %+.2f%%, Quality gate: %.2f)".formatted(value, threshold)); + assertThat(getConsoleLog(build)).contains( + "≪Unstable≫ - (Actual value: %+.2f%%, Quality gate: %.2f)".formatted(value, threshold)); } else { - assertThat(getConsoleLog(build)).contains("≪Unstable≫ - (Actual value: %.2f%%, Quality gate: %.2f)".formatted(value, threshold)); + assertThat(getConsoleLog(build)).contains( + "≪Unstable≫ - (Actual value: %.2f%%, Quality gate: %.2f)".formatted(value, threshold)); } } diff --git a/pom.xml b/pom.xml index 796c00c68..70e96fcb1 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.jvnet.hudson.plugins analysis-pom - 11.2958.v63511c4c1160 + 12.3159.v1734d34dfb_fc @@ -21,7 +21,7 @@ - 2 + 3 999999-SNAPSHOT jenkinsci/coverage-plugin diff --git a/ui-tests/pom.xml b/ui-tests/pom.xml index 4430dc07c..de1d06181 100644 --- a/ui-tests/pom.xml +++ b/ui-tests/pom.xml @@ -5,7 +5,7 @@ edu.hm.hafner codingstyle-pom - 5.42.0 + 6.8.0 @@ -16,8 +16,8 @@ UI Tests of Code Coverage Plugin - 2.556 - 3.1795.v6fb_496fc129b_ + 2.558 + 3.1820.ve687007a_69e5 2.3 5.1.1 ${project.groupId}.code.coverage.api.ui.tests @@ -48,12 +48,12 @@ org.jenkins-ci acceptance-test-harness - 6509.v07d7a_3818f74 + 6623.v46eb_51303186 com.fasterxml.jackson.core jackson-databind - 2.21.0 + 2.21.2 test @@ -171,7 +171,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.4 + 3.5.5 true false @@ -259,7 +259,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.4 + 3.5.5 false false diff --git a/ui-tests/src/main/java/io/jenkins/plugins/coverage/publisher/threshold/AbstractThreshold.java b/ui-tests/src/main/java/io/jenkins/plugins/coverage/publisher/threshold/AbstractThreshold.java index 42407e1e0..fb3851129 100644 --- a/ui-tests/src/main/java/io/jenkins/plugins/coverage/publisher/threshold/AbstractThreshold.java +++ b/ui-tests/src/main/java/io/jenkins/plugins/coverage/publisher/threshold/AbstractThreshold.java @@ -7,7 +7,7 @@ /** * Used for thresholds and global thresholds. */ -abstract class AbstractThreshold extends PageAreaImpl { +public abstract class AbstractThreshold extends PageAreaImpl { private final Control thresholdTarget = control("thresholdTarget"); private final Control unhealthyThreshold = control("unhealthyThreshold"); private final Control unstableThreshold = control("unstableThreshold"); @@ -22,6 +22,7 @@ abstract class AbstractThreshold extends PageAreaImpl { * @param path * to threshold */ + @SuppressWarnings("this-escape") protected AbstractThreshold(final PageArea parent, final String path) { super(parent, path); } @@ -70,7 +71,7 @@ public void delete() { /** * Ensures advanced options are activated so that Thresholds can be set. */ - public abstract void ensureAdvancedOptionsIsActivated(); + abstract void ensureAdvancedOptionsIsActivated(); Control getThresholdTarget() { return thresholdTarget;