Skip to content
This repository was archived by the owner on Mar 27, 2025. It is now read-only.

Commit 92ec27f

Browse files
authored
Merge pull request #148 from mathworks/source_folder_pp_fs
Add Source Folder option
2 parents d4a8214 + 8286c04 commit 92ec27f

File tree

13 files changed

+358
-34
lines changed

13 files changed

+358
-34
lines changed

src/main/java/com/mathworks/ci/MatlabBuild.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import java.io.IOException;
1010
import java.io.InputStream;
11+
import java.util.List;
1112
import java.util.UUID;
1213
import hudson.EnvVars;
1314
import hudson.FilePath;

src/main/java/com/mathworks/ci/RunMatlabTestsBuilder.java

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,26 @@
99
*/
1010

1111
import java.io.IOException;
12-
import java.util.*;
12+
import java.util.Map;
13+
import java.util.HashMap;
14+
import java.util.List;
15+
import java.util.ArrayList;
16+
import java.util.Optional;
17+
import java.util.Arrays;
18+
import java.util.stream.Collectors;
1319
import javax.annotation.Nonnull;
14-
import org.kohsuke.stapler.DataBoundConstructor;
15-
import org.kohsuke.stapler.DataBoundSetter;
16-
import org.kohsuke.stapler.StaplerRequest;
1720
import hudson.EnvVars;
1821
import hudson.Extension;
1922
import hudson.FilePath;
2023
import hudson.Launcher;
21-
import hudson.Launcher.ProcStarter;
2224
import hudson.model.AbstractProject;
2325
import hudson.model.Result;
2426
import hudson.model.Run;
2527
import hudson.model.TaskListener;
28+
import org.kohsuke.stapler.DataBoundConstructor;
29+
import org.kohsuke.stapler.DataBoundSetter;
30+
import org.kohsuke.stapler.StaplerRequest;
31+
import hudson.Launcher.ProcStarter;
2632
import hudson.tasks.BuildStepDescriptor;
2733
import hudson.tasks.Builder;
2834
import jenkins.tasks.SimpleBuildStep;
@@ -32,7 +38,7 @@ public class RunMatlabTestsBuilder extends Builder implements SimpleBuildStep, M
3238

3339
private int buildResult;
3440
private EnvVars env;
35-
41+
3642
// Make all old values transient which protects them writing back on disk.
3743
private transient boolean tapChkBx;
3844
private transient boolean junitChkBx;
@@ -47,16 +53,15 @@ public class RunMatlabTestsBuilder extends Builder implements SimpleBuildStep, M
4753
private Artifact stmResultsArtifact = new NullArtifact();
4854
private Artifact modelCoverageArtifact = new NullArtifact();
4955
private Artifact pdfReportArtifact = new NullArtifact();
50-
56+
private SourceFolder sourceFolder;
57+
5158
@DataBoundConstructor
5259
public RunMatlabTestsBuilder() {
5360

5461
}
5562

56-
5763
// Getter and Setters to access local members
5864

59-
6065
@DataBoundSetter
6166
public void setTapArtifact(TapArtifact tapArtifact) {
6267
this.tapArtifact = tapArtifact;
@@ -86,7 +91,13 @@ public void setModelCoverageArtifact(ModelCovArtifact modelCoverageArtifact) {
8691
public void setPdfReportArtifact(PdfArtifact pdfReportArtifact) {
8792
this.pdfReportArtifact = pdfReportArtifact;
8893
}
89-
94+
95+
@DataBoundSetter
96+
public void setSourceFolder(SourceFolder sourceFolder) {
97+
this.sourceFolder = sourceFolder;
98+
}
99+
100+
90101
public String getTapReportFilePath() {
91102
return this.getTapArtifact().getFilePath();
92103
}
@@ -135,6 +146,10 @@ public String getPdfReportFilePath() {
135146
return this.getPdfReportArtifact().getFilePath();
136147
}
137148

149+
public SourceFolder getSourceFolder() {
150+
return this.sourceFolder;
151+
}
152+
138153
private Artifact getArtifactObject(boolean isChecked, Artifact returnVal) {
139154
// If previously checked assign valid artifact object else NullArtifact.
140155
return (isChecked) ? returnVal : new NullArtifact();
@@ -286,6 +301,17 @@ private String getInputArguments() {
286301

287302
args.forEach((key, val) -> inputArgsList.add("'" + key + "'" + "," + "'" + val + "'"));
288303

304+
/*
305+
* Add source folder options to argument.
306+
* For source folder we create a MATLAB cell array and add it to input argument list.
307+
* */
308+
SourceFolder sf = getSourceFolder();
309+
if(sf != null && !sf.getSourceFolderPaths().isEmpty()){
310+
sf.addSourceToInputArgs(inputArgsList, Utilities.getCellArrayFrmList(sf.getSourceFolderPaths().stream()
311+
.map(SourceFolderPaths::getSrcFolderPath)
312+
.collect(Collectors.toList())));
313+
}
314+
289315
return String.join(",", inputArgsList);
290316
}
291317

@@ -300,6 +326,7 @@ private String getInputArguments() {
300326
* 7Csort:date/jenkinsci-dev/AFYHSG3NUEI/UsVJIKoE4B8J
301327
*
302328
*/
329+
303330
public static class PdfArtifact extends AbstractArtifactImpl {
304331

305332
private static final String PDF_TEST_REPORT = "PDFTestReport";

src/main/java/com/mathworks/ci/RunMatlabTestsStep.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import hudson.Launcher;
2323
import hudson.model.Run;
2424
import hudson.model.TaskListener;
25+
import hudson.Util;
2526

2627
public class RunMatlabTestsStep extends Step {
2728

@@ -31,7 +32,7 @@ public class RunMatlabTestsStep extends Step {
3132
private String codeCoverageCobertura;
3233
private String testResultsSimulinkTest;
3334
private String modelCoverageCobertura;
34-
35+
private List<String> sourceFolder = new ArrayList<>();
3536

3637
@DataBoundConstructor
3738
public RunMatlabTestsStep() {
@@ -93,6 +94,14 @@ public void setModelCoverageCobertura(String modelCoverageCobertura) {
9394
this.modelCoverageCobertura = modelCoverageCobertura;
9495
}
9596

97+
public List<String> getSourceFolder() {
98+
return sourceFolder;
99+
}
100+
101+
@DataBoundSetter
102+
public void setSourceFolder(List<String> sourceFolder) {
103+
this.sourceFolder = Util.fixNull(sourceFolder);
104+
}
96105

97106
@Override
98107
public StepExecution start(StepContext context) throws Exception {
@@ -126,7 +135,9 @@ private String getInputArgs() {
126135
inputArgs.add("'Test'");
127136

128137
args.forEach((key, val) -> {
129-
if (val != null) {
138+
if(key.equals("SourceFolder") && val != null){
139+
inputArgs.add("'" + key + "'" + "," + val);
140+
}else if(val != null){
130141
inputArgs.add("'" + key + "'" + "," + "'" + val.replaceAll("'", "''") + "'");
131142
}
132143
});
@@ -142,6 +153,9 @@ private Map<String, String> getGenscriptArgs() {
142153
args.put("SimulinkTestResults", getTestResultsSimulinkTest());
143154
args.put("CoberturaCodeCoverage", getCodeCoverageCobertura());
144155
args.put("CoberturaModelCoverage", getModelCoverageCobertura());
156+
if(!getSourceFolder().isEmpty()){
157+
args.put("SourceFolder", Utilities.getCellArrayFrmList(getSourceFolder()));
158+
}
145159
return args;
146160
}
147161
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.mathworks.ci;
2+
3+
/**
4+
* Copyright 2020 The MathWorks, Inc.
5+
*
6+
* Describable class for Source Folder Option in RunMATLABTest Build step.
7+
*
8+
*/
9+
10+
import hudson.Extension;
11+
import hudson.Util;
12+
import hudson.model.AbstractDescribableImpl;
13+
import hudson.model.Descriptor;
14+
import org.kohsuke.stapler.DataBoundConstructor;
15+
import java.util.List;
16+
import java.util.Map;
17+
import java.util.stream.Collectors;
18+
19+
public class SourceFolder extends AbstractDescribableImpl<SourceFolder> {
20+
21+
private List<SourceFolderPaths> sourceFolderPaths;
22+
private static final String SOURCE_FOLDER = "SourceFolder";
23+
24+
@DataBoundConstructor
25+
public SourceFolder(List<SourceFolderPaths> sourceFolderPaths) {
26+
this.sourceFolderPaths = Util.fixNull(sourceFolderPaths);
27+
}
28+
29+
public List<SourceFolderPaths> getSourceFolderPaths() {
30+
return this.sourceFolderPaths;
31+
}
32+
33+
public void addSourceToInputArgs(List<String> inputArgsList, String cellArraySourceVal) {
34+
// Concatenate all source folders to MATLAB cell array string.
35+
inputArgsList.add("'" + SOURCE_FOLDER + "'" + "," + cellArraySourceVal);
36+
}
37+
38+
@Extension public static class DescriptorImpl extends Descriptor<SourceFolder> {
39+
@Override
40+
public String getDisplayName() {
41+
return "";
42+
}
43+
}
44+
45+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.mathworks.ci;
2+
3+
/**
4+
* Copyright 2020 The MathWorks, Inc.
5+
*
6+
* Describable class for Repeatable Source Folder text boxes in Source Folder option
7+
* in RunMATLABTest Build step.
8+
*
9+
*/
10+
11+
import hudson.Extension;
12+
import hudson.model.AbstractDescribableImpl;
13+
import hudson.model.Descriptor;
14+
import org.kohsuke.stapler.DataBoundConstructor;
15+
16+
public class SourceFolderPaths extends AbstractDescribableImpl<SourceFolderPaths> {
17+
18+
private String srcFolderPath;
19+
20+
@DataBoundConstructor
21+
public SourceFolderPaths(String srcFolderPath){
22+
this.srcFolderPath = srcFolderPath;
23+
}
24+
25+
public String getSrcFolderPath() {
26+
return this.srcFolderPath;
27+
}
28+
29+
@Extension
30+
public static final class DescriptorImpl extends Descriptor<SourceFolderPaths> {
31+
32+
@Override
33+
public String getDisplayName() {
34+
return "";
35+
}
36+
}
37+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.mathworks.ci;
2+
3+
/**
4+
* Copyright 2020 The MathWorks, Inc.
5+
*
6+
* Utility class for common methods.
7+
*
8+
*/
9+
10+
import java.util.List;
11+
import java.util.function.Predicate;
12+
import java.util.stream.Collectors;
13+
14+
public class Utilities {
15+
16+
public static String getCellArrayFrmList(List<String> listOfStr){
17+
// Ignore empty string values in the list
18+
Predicate<String> isEmpty = String::isEmpty;
19+
Predicate<String> isNotEmpty = isEmpty.negate();
20+
List<String> filteredListOfStr = listOfStr.stream().filter(isNotEmpty).collect(Collectors.toList());
21+
22+
// Escape apostrophe for MATLAB
23+
filteredListOfStr.replaceAll(val -> "'" + val.replaceAll("'", "''") + "'");
24+
return "{" + String.join(",", filteredListOfStr) + "}";
25+
}
26+
}

src/main/resources/com/mathworks/ci/RunMatlabTestsBuilder/config.jelly

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
<?jelly escape-by-default='true'?>
22
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
3-
4-
<f:section title="Generate Test Artifacts">
3+
4+
<f:block>
5+
<br></br>
6+
<f:optionalProperty field="sourceFolder" title="Source Folder" />
7+
</f:block>
8+
9+
<f:block>
10+
<br></br>
11+
<b>Generate Test Artifacts</b>
512
<f:optionalBlock name="pdfReportArtifact" field="pdfReportArtifact" title="PDF test report" checked="${instance.pdfReportArtifact.selected}">
613
<f:entry field="pdfReportFilePath" title="File path: ">
714
<f:textbox default="matlabTestArtifacts/testreport.pdf"/>
@@ -26,9 +33,11 @@
2633
</f:entry>
2734
</f:optionalBlock>
2835

29-
</f:section>
36+
</f:block>
3037

31-
<f:section title="Generate Coverage Artifacts">
38+
<f:block>
39+
<br></br>
40+
<b>Generate Coverage Artifacts</b>
3241
<f:optionalBlock name="coberturaArtifact" field="coberturaArtifact" title="Cobertura code coverage" checked="${instance.coberturaArtifact.selected}">
3342
<f:entry field="coberturaReportFilePath" title="File path: ">
3443
<f:textbox default="matlabTestArtifacts/cobertura.xml"/>
@@ -40,5 +49,5 @@
4049
<f:textbox default="matlabTestArtifacts/coberturamodelcoverage.xml"/>
4150
</f:entry>
4251
</f:optionalBlock>
43-
</f:section>
44-
</j:jelly>
52+
</f:block>
53+
</j:jelly>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div>
2+
<p>Specify the location of folders containing source code, relative to the project root folder. The specified folders and their subfolders are added to the top of the MATLAB search path. To generate a coverage report, MATLAB uses only the source code in the specified folders and their subfolders.</p>
3+
<p>Paste the source folder path in the <b>File path</b> box. To add more folders, click <b>Add folder</b>.</p>
4+
</div>
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
11
<?jelly escape-by-default='true'?>
22
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
33

4-
<f:entry field="testResultsPDF">
4+
<f:entry field="testResultsPDF" title="testResultsPDF: ">
55
<f:textbox/>
66
</f:entry>
77

8-
<f:entry field="testResultsTAP">
8+
<f:entry field="testResultsTAP" title="testResultsTAP: ">
99
<f:textbox/>
1010
</f:entry>
1111

12-
<f:entry field="testResultsJUnit">
12+
<f:entry field="testResultsJUnit" title="testResultsJUnit: ">
1313
<f:textbox/>
1414
</f:entry>
1515

16-
<f:entry field="codeCoverageCobertura">
16+
<f:entry field="codeCoverageCobertura" title="codeCoverageCobertura: ">
1717
<f:textbox/>
1818
</f:entry>
1919

20-
<f:entry field="testResultsSimulinkTest">
20+
<f:entry field="testResultsSimulinkTest" title="testResultsSimulinkTest: ">
2121
<f:textbox/>
2222
</f:entry>
2323

24-
<f:entry field="modelCoverageCobertura">
24+
<f:entry field="modelCoverageCobertura" title="modelCoverageCobertura: ">
2525
<f:textbox/>
26-
</f:entry>
26+
</f:entry>
27+
28+
<f:entry field="sourceFolder" title="sourceFolder: ">
29+
<f:textbox/>
30+
</f:entry>
2731

28-
</j:jelly>
32+
</j:jelly>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div>
2+
<p>Specify the location of folders containing source code, relative to the project root folder, as a string array. The specified folders and their subfolders are added to the top of the MATLAB search path. To generate a coverage report, MATLAB uses only the source code in the specified folders and their subfolders.</p>
3+
<p><b>Example:</b> ["src/folderA", "src/folderB"]</p>
4+
</div>

0 commit comments

Comments
 (0)