Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/assign-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ jobs:
add-reviews:
runs-on: ubuntu-latest
steps:
- uses: kentaro-m/[email protected].4
- uses: kentaro-m/[email protected].5
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ jobs:
platform: [ubuntu-latest, macos-latest, windows-latest]
jdk: [17]
include:
- os: ubuntu-latest
- platform: ubuntu-latest
jdk: 11
- os: macos-latest
- platform: macos-latest
jdk: 11

runs-on: ${{ matrix.platform }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,20 @@ class CoverageChecksPublisher {
private static final ElementFormatter FORMATTER = new ElementFormatter();

private final CoverageBuildAction action;
private final Node rootNode;
private final JenkinsFacade jenkinsFacade;
private final String checksName;
private final ChecksAnnotationScope annotationScope;

CoverageChecksPublisher(final CoverageBuildAction action, final String checksName,
CoverageChecksPublisher(final CoverageBuildAction action, final Node rootNode, final String checksName,
final ChecksAnnotationScope annotationScope) {
this(action, checksName, annotationScope, new JenkinsFacade());
this(action, rootNode, checksName, annotationScope, new JenkinsFacade());
}

@VisibleForTesting
CoverageChecksPublisher(final CoverageBuildAction action,
final String checksName, final ChecksAnnotationScope annotationScope, final JenkinsFacade jenkinsFacade) {
CoverageChecksPublisher(final CoverageBuildAction action, final Node rootNode, final String checksName,
final ChecksAnnotationScope annotationScope, final JenkinsFacade jenkinsFacade) {
this.rootNode = rootNode;
this.jenkinsFacade = jenkinsFacade;
this.action = action;
this.checksName = checksName;
Expand Down Expand Up @@ -97,7 +99,7 @@ private String getChecksTitle() {
}

private String getSummary() {
var root = action.getResult();
var root = rootNode;
return getOverallCoverageSummary(root) + "\n\n"
+ getQualityGatesSummary() + "\n\n"
+ getProjectMetricsSummary(root);
Expand All @@ -108,7 +110,7 @@ private List<ChecksAnnotation> getAnnotations() {
return List.of();
}

var tree = action.getResult();
var tree = rootNode;
Node filtered;
if (annotationScope == ChecksAnnotationScope.ALL_LINES) {
filtered = tree;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,13 +391,12 @@ private void perform(final Run<?, ?> run, final FilePath workspace, final TaskLi

if (!results.isEmpty()) {
CoverageReporter reporter = new CoverageReporter();
var action = reporter.publishAction(getActualId(), getName(), getIcon(),
Node.merge(results), run, workspace, taskListener,
getQualityGates(),
getScm(), getSourceDirectoriesPaths(),
var rootNode = Node.merge(results);
var action = reporter.publishAction(getActualId(), getName(), getIcon(), rootNode, run,
workspace, taskListener, getQualityGates(), getScm(), getSourceDirectoriesPaths(),
getSourceCodeEncoding(), getSourceCodeRetention(), resultHandler);
if (!skipPublishingChecks) {
var checksPublisher = new CoverageChecksPublisher(action, getChecksName(), getChecksAnnotationScope());
var checksPublisher = new CoverageChecksPublisher(action, rootNode, getChecksName(), getChecksAnnotationScope());
checksPublisher.publishCoverageReport(taskListener);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,9 @@ public String getDisplayName() {

/** Descriptor for {@link CoverageTool}. **/
@Extension
public static class CoverageToolDescriptor extends Descriptor<io.jenkins.plugins.coverage.metrics.steps.CoverageTool> {
public static class CoverageToolDescriptor extends Descriptor<CoverageTool> {
private static final JenkinsFacade JENKINS = new JenkinsFacade();

/**
* Creates a new instance of {@link CoverageToolDescriptor}.
*/
public CoverageToolDescriptor() {
super();

// empty constructor required for stapler
}

/**
* Returns a model with all {@link SourceCodeRetention} strategies.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
/**
* Configures the XML stream for the coverage tree, which consists of {@link Node}s.
*/
@SuppressWarnings("CouplingBetweenObjects")
@SuppressWarnings("PMD.CouplingBetweenObjects")
class CoverageXmlStream extends AbstractXmlStream<Node> {
private static final Collector<CharSequence, ?, String> ARRAY_JOINER = Collectors.joining(", ", "[", "]");

Expand Down
61 changes: 61 additions & 0 deletions plugin/src/main/resources/coverage/deprecated-coverage-table.jelly
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:bs="/bootstrap5" xmlns:dt="/data-tables" xmlns:st="jelly:stapler" xmlns:fa="/font-awesome" >

<st:documentation>
Provides a table to render the file coverage nodes without the source code.
<st:attribute name="tableId" type="String">
The ID of the table.
</st:attribute>
</st:documentation>

<div class="row">
<j:choose>
<j:when test="${it.hasSourceCode()}">
<div class="col-12 d-xxl-none">
<bs:card title="${%Coverage of all files}" fontAwesomeIcon="file-lines" fontAwesomeStyle="regular" class="flex-fill h-100" >
<dt:table model="${it.getTableModel(tableId + '-table')}"/>
</bs:card>
</div>
<div class="col-xxl-6 d-none d-xxl-block">
<bs:card title="${%Coverage of all files}" fontAwesomeIcon="file-lines" fontAwesomeStyle="regular" class="flex-fill h-100">
<dt:table model="${it.getTableModel(tableId + '-table-inline')}"/>
</bs:card>
</div>
<div class="col-xxl-6 d-none d-xxl-block">
<bs:card title="${%Source code view}" fontAwesomeIcon="file-code" fontAwesomeStyle="regular"
class="flex-fill h-100">
<div id="${tableId}-source-file-content">
<table id="${tableId}-source-file" class="source">
</table>
</div>
<div id="${tableId}-no-selection">
<div class="text-center">
<fa:svg-icon name="hand-point-left" class="no-selection-banner"/>
</div>
<div class="text-center">
<h5 class="card-title">${%Please select a file in the table to open the source code}</h5>
</div>
</div>
<div id="${tableId}-no-source">
<div class="text-center">
<fa:svg-icon name="ban" class="no-selection-banner"/>
</div>
<div class="text-center">
<h5 class="card-title">${%No source code available for this file}</h5>
</div>
</div>
</bs:card>
</div>
</j:when>
<j:otherwise>
<div class="col-12">
<bs:card title="${%Coverage of all files}" fontAwesomeIcon="file-lines" fontAwesomeStyle="regular" class="flex-fill h-100">
<dt:table model="${it.getTableModel(tableId + '-table')}"/>
</bs:card>
</div>

</j:otherwise>
</j:choose>
</div>

</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@
</div>

<div role="tabpanel" id="fileCoverage" class="tab-pane fade" aria-labelledby="fileCoverage-tab">
<cov:coverage-table tableId="absolute-coverage"/>
<cov:deprecated-coverage-table tableId="absolute-coverage"/>
</div>

<j:if test="${hasChangeCoverage}">
<div role="tabpanel" id="changeCoverage" class="tab-pane fade" aria-labelledby="changeCoverage-tab">
<cov:coverage-table tableId="change-coverage"/>
<cov:deprecated-coverage-table tableId="change-coverage"/>
</div>
</j:if>

<j:if test="${hasIndirectCoverageChanges}">
<div role="tabpanel" id="indirectCoverage" class="tab-pane fade" aria-labelledby="indirectCoverage-tab">
<cov:coverage-table tableId="indirect-coverage"/>
<cov:deprecated-coverage-table tableId="indirect-coverage"/>
</div>
</j:if>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,6 @@ private CpsFlowDefinition createPipelineWithSourceCode(final SourceCodeRetention

private void verifySourceCodeInBuild(final Run<?, ?> build, final String acuCobolParserSourceCodeSnippet,
final String pathUtilSourceCodeSnippet) {
System.out.println(getConsoleLog(build));

List<CoverageBuildAction> actions = build.getActions(CoverageBuildAction.class);
var builder = new CoverageBuilder().setMetric(Metric.LINE).setMissed(0);
assertThat(actions).hasSize(2).satisfiesExactly(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import edu.hm.hafner.coverage.Coverage.CoverageBuilder;
import edu.hm.hafner.coverage.Metric;
import edu.hm.hafner.coverage.Node;

import hudson.model.Run;

Expand All @@ -36,11 +37,14 @@ class CoverageChecksPublisherTest extends AbstractCoverageTest {
private static final String BUILD_LINK = "job/pipeline-coding-style/job/5";
private static final String COVERAGE_ID = "coverage";
private static final String REPORT_NAME = "Name";
private static final int ANNOTATIONS_COUNT_FOR_MODIFIED = 3;

@ParameterizedTest(name = "should create checks (scope = {0}, expected annotations = {1})")
@CsvSource({"SKIP, 0", "ALL_LINES, 36", "MODIFIED_LINES, 3"})
void shouldCreateChecksReport(final ChecksAnnotationScope scope, final int expectedAnnotations) {
var publisher = new CoverageChecksPublisher(createCoverageBuildAction(), REPORT_NAME, scope, createJenkins());
var result = readJacocoResult("jacoco-codingstyle.xml");

var publisher = new CoverageChecksPublisher(createCoverageBuildAction(result), result, REPORT_NAME, scope, createJenkins());

var checkDetails = publisher.extractChecksDetails();

Expand All @@ -65,14 +69,14 @@ private void assertThatDetailsAreCorrect(final ChecksDetails checkDetails, final
}

private void assertSummary(final ChecksOutput checksOutput) throws IOException {
var expectedContent = Files.readString(getResourceAsFile("coverage-publisher-summary.md"));
var expectedContent = Files.readString(getResourceAsFile("coverage-publisher-summary.checks-expected-result"));
assertThat(checksOutput.getSummary()).isPresent()
.get()
.isEqualTo(expectedContent);
}

private void assertChecksAnnotations(final ChecksOutput checksOutput, final int expectedAnnotations) {
if (expectedAnnotations == 3) {
if (expectedAnnotations == ANNOTATIONS_COUNT_FOR_MODIFIED) {
assertThat(checksOutput.getChecksAnnotations()).hasSize(expectedAnnotations).satisfiesExactly(
annotation -> {
assertThat(annotation.getTitle()).contains("Not covered line");
Expand Down Expand Up @@ -108,15 +112,15 @@ private JenkinsFacade createJenkins() {
return jenkinsFacade;
}

private CoverageBuildAction createCoverageBuildAction() {
private CoverageBuildAction createCoverageBuildAction(final Node result) {
var testCoverage = new CoverageBuilder().setMetric(Metric.LINE)
.setCovered(1)
.setMissed(1)
.build();

var run = mock(Run.class);
when(run.getUrl()).thenReturn(BUILD_LINK);
var result = readJacocoResult("jacoco-codingstyle.xml");

result.findFile("TreeStringBuilder.java")
.ifPresent(file -> {
assertThat(file.getMissedLines()).contains(61, 62);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import io.jenkins.plugins.coverage.metrics.model.Baseline;
import io.jenkins.plugins.coverage.metrics.steps.CoverageTool.Parser;

import static edu.hm.hafner.coverage.Metric.*;
import static io.jenkins.plugins.coverage.metrics.AbstractCoverageTest.*;
import static org.assertj.core.api.Assertions.*;

Expand Down Expand Up @@ -143,19 +142,19 @@ private void verifyOneJacocoResult(final ParameterizedJob<?, ?> project) {

private static void verifyJaCoCoAction(final CoverageBuildAction coverageResult) {
assertThat(coverageResult.getAllValues(Baseline.PROJECT)).extracting(Value::getMetric)
.containsExactly(MODULE,
PACKAGE,
.containsExactly(Metric.MODULE,
Metric.PACKAGE,
Metric.FILE,
Metric.CLASS,
METHOD,
LINE,
BRANCH,
INSTRUCTION,
COMPLEXITY,
COMPLEXITY_DENSITY,
LOC);
Metric.METHOD,
Metric.LINE,
Metric.BRANCH,
Metric.INSTRUCTION,
Metric.COMPLEXITY,
Metric.COMPLEXITY_DENSITY,
Metric.LOC);
assertThat(coverageResult.getMetricsForSummary())
.containsExactly(Metric.LINE, Metric.BRANCH, Metric.MUTATION, COMPLEXITY_DENSITY, Metric.LOC);
.containsExactly(Metric.LINE, Metric.BRANCH, Metric.MUTATION, Metric.COMPLEXITY_DENSITY, Metric.LOC);
assertThat(coverageResult.getAllValues(Baseline.PROJECT))
.contains(createLineCoverageBuilder()
.setCovered(JACOCO_ANALYSIS_MODEL_COVERED)
Expand Down Expand Up @@ -238,11 +237,11 @@ void shouldRecordCoberturaAndJacocoResultsInFreestyleJob() {

CoverageRecorder recorder = new CoverageRecorder();

var cobertura = new io.jenkins.plugins.coverage.metrics.steps.CoverageTool();
var cobertura = new CoverageTool();
cobertura.setParser(Parser.COBERTURA);
cobertura.setPattern(COBERTURA_HIGHER_COVERAGE_FILE);

var jacoco = new io.jenkins.plugins.coverage.metrics.steps.CoverageTool();
var jacoco = new CoverageTool();
jacoco.setParser(Parser.JACOCO);
jacoco.setPattern(JACOCO_ANALYSIS_MODEL_FILE);

Expand Down Expand Up @@ -309,7 +308,7 @@ private void verifyOnePitResult(final ParameterizedJob<?, ?> project) {

CoverageBuildAction coverageResult = build.getAction(CoverageBuildAction.class);
assertThat(coverageResult.getAllValues(Baseline.PROJECT))
.filteredOn(Value::getMetric, MUTATION)
.filteredOn(Value::getMetric, Metric.MUTATION)
.first()
.isInstanceOfSatisfying(Coverage.class, m -> {
assertThat(m.getCovered()).isEqualTo(222);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ void shouldComputeDeltaInPipelineOnDockerAgent(final SourceCodeRetention sourceC
Run<?, ?> build = buildSuccessfully(project);
verifyGitRepositoryForCommit(build, COMMIT);

System.out.println(getConsoleLog(build));
verifyGitIntegration(build, referenceBuild);

assertThat(getConsoleLog(build)).contains(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ void shouldCreateFreestyleJobFromYamlConfiguration() {
private void assertRecorderProperties(final CoverageRecorder recorder) {
assertThat(recorder.getTools()).hasSize(2).usingRecursiveFieldByFieldElementComparator()
.containsExactly(
new io.jenkins.plugins.coverage.metrics.steps.CoverageTool(Parser.JACOCO, "jacoco-pattern.*"),
new io.jenkins.plugins.coverage.metrics.steps.CoverageTool(Parser.COBERTURA, "cobertura-pattern.*"));
new CoverageTool(Parser.JACOCO, "jacoco-pattern.*"),
new CoverageTool(Parser.COBERTURA, "cobertura-pattern.*"));
assertThat(recorder.getQualityGates()).hasSize(2).usingRecursiveFieldByFieldElementComparator()
.containsExactly(
new CoverageQualityGate(70.0, Metric.LINE, Baseline.PROJECT, QualityGateCriticality.UNSTABLE),
Expand Down