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

Commit 84aee1d

Browse files
authored
Merge pull request #26 from mathworks/CI_78_matrix_build_support
Added support for Jenkins environment variables.
2 parents b0dd8ff + 31d3b20 commit 84aee1d

File tree

5 files changed

+159
-66
lines changed

5 files changed

+159
-66
lines changed

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

Lines changed: 70 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ public class MatlabBuilder extends Builder implements SimpleBuildStep {
5353
private static final double BASE_MATLAB_VERSION_COBERTURA_SUPPORT = 9.3;
5454
private int buildResult;
5555
private TestRunTypeList testRunTypeList;
56-
private String localMatlab;
56+
private String matlabRoot;
57+
private EnvVars env;
5758
private static final String MATLAB_RUNNER_TARGET_FILE =
5859
"Builder.matlab.runner.target.file.name";
5960
private static final String MATLAB_RUNNER_RESOURCE =
@@ -70,35 +71,47 @@ public MatlabBuilder() {
7071
// Getter and Setters to access local members
7172

7273
@DataBoundSetter
73-
public void setLocalMatlab(String localMatlab) {
74-
this.localMatlab = localMatlab;
74+
public void setMatlabRoot(String matlabRoot) {
75+
this.matlabRoot = matlabRoot;
7576
}
7677

7778
@DataBoundSetter
7879
public void setTestRunTypeList(TestRunTypeList testRunTypeList) {
7980
this.testRunTypeList = testRunTypeList;
8081
}
8182

82-
public String getLocalMatlab() {
83+
public String getMatlabRoot() {
8384

84-
return this.localMatlab;
85+
return this.matlabRoot;
8586
}
8687

8788
public TestRunTypeList getTestRunTypeList() {
8889
return this.testRunTypeList;
8990
}
91+
92+
private String getLocalMatlab() {
93+
return this.env == null ? getLocalMatlab(): this.env.expand(getMatlabRoot());
94+
}
95+
96+
private String getCustomMatlabCommand() {
97+
return this.env == null ? this.getTestRunTypeList().getStringByName("customMatlabCommand")
98+
: this.env.expand(this.getTestRunTypeList().getStringByName("customMatlabCommand"));
99+
}
100+
private void setEnv(EnvVars env) {
101+
this.env = env;
102+
}
90103

91104
@Extension
92105
public static class MatlabDescriptor extends BuildStepDescriptor<Builder> {
93106
MatlabReleaseInfo rel;
94-
String localMatlab;
107+
String matlabRoot;
95108

96-
public String getLocalMatlab() {
97-
return localMatlab;
109+
public String getMatlabRoot() {
110+
return matlabRoot;
98111
}
99112

100-
public void setLocalMatlab(String localMatlab) {
101-
this.localMatlab = localMatlab;
113+
public void setMatlabRoot(String matlabRoot) {
114+
this.matlabRoot = matlabRoot;
102115
}
103116

104117
// Overridden Method used to show the text under build dropdown
@@ -141,22 +154,22 @@ public DescriptorExtensionList<TestRunTypeList, Descriptor<TestRunTypeList>> get
141154
*/
142155

143156

144-
public FormValidation doCheckLocalMatlab(@QueryParameter String localMatlab) {
145-
setLocalMatlab(localMatlab);
157+
public FormValidation doCheckMatlabRoot(@QueryParameter String matlabRoot) {
158+
setMatlabRoot(matlabRoot);
146159
List<Function<String, FormValidation>> listOfCheckMethods =
147160
new ArrayList<Function<String, FormValidation>>();
148161
listOfCheckMethods.add(chkMatlabEmpty);
149162
listOfCheckMethods.add(chkMatlabSupportsRunTests);
150163

151-
return getFirstErrorOrWarning(listOfCheckMethods, localMatlab);
164+
return getFirstErrorOrWarning(listOfCheckMethods, matlabRoot);
152165
}
153166

154167
public FormValidation getFirstErrorOrWarning(
155-
List<Function<String, FormValidation>> validations, String localMatalb) {
168+
List<Function<String, FormValidation>> validations, String matlabRoot) {
156169
if (validations == null || validations.isEmpty())
157170
return FormValidation.ok();
158171
for (Function<String, FormValidation> val : validations) {
159-
FormValidation validationResult = val.apply(localMatalb);
172+
FormValidation validationResult = val.apply(matlabRoot);
160173
if (validationResult.kind.compareTo(Kind.ERROR) == 0
161174
|| validationResult.kind.compareTo(Kind.WARNING) == 0) {
162175
return validationResult;
@@ -165,22 +178,26 @@ public FormValidation getFirstErrorOrWarning(
165178
return FormValidation.ok();
166179
}
167180

168-
Function<String, FormValidation> chkMatlabEmpty = (String localMatlab) -> {
169-
if (localMatlab.isEmpty()) {
181+
Function<String, FormValidation> chkMatlabEmpty = (String matlabRoot) -> {
182+
if (matlabRoot.isEmpty()) {
170183
return FormValidation.error(Message.getValue("Builder.matlab.root.empty.error"));
171184
}
172185
return FormValidation.ok();
173186
};
174-
175-
Function<String, FormValidation> chkMatlabSupportsRunTests = (String localMatlab) -> {
176-
try {
177-
rel = new MatlabReleaseInfo(localMatlab);
178-
if (rel.verLessThan(BASE_MATLAB_VERSION_RUNTESTS_SUPPORT)) {
187+
188+
Function<String, FormValidation> chkMatlabSupportsRunTests = (String matlabRoot) -> {
189+
final MatrixPatternResolver resolver = new MatrixPatternResolver(matlabRoot);
190+
if (!resolver.hasVariablePattern()) {
191+
try {
192+
rel = new MatlabReleaseInfo(matlabRoot);
193+
if (rel.verLessThan(BASE_MATLAB_VERSION_RUNTESTS_SUPPORT)) {
194+
return FormValidation
195+
.error(Message.getValue("Builder.matlab.test.support.error"));
196+
}
197+
} catch (MatlabVersionNotFoundException e) {
179198
return FormValidation
180-
.error(Message.getValue("Builder.matlab.test.support.error"));
199+
.error(Message.getValue("Builder.invalid.matlab.root.error"));
181200
}
182-
} catch (MatlabVersionNotFoundException e) {
183-
return FormValidation.error(Message.getValue("Builder.invalid.matlab.root.error"));
184201
}
185202
return FormValidation.ok();
186203
};
@@ -229,25 +246,29 @@ public static abstract class TestRunTypeDescriptor extends Descriptor<TestRunTyp
229246
public FormValidation doCheckTaCoberturaChkBx(@QueryParameter boolean taCoberturaChkBx) {
230247
List<Function<String, FormValidation>> listOfCheckMethods =
231248
new ArrayList<Function<String, FormValidation>>();
232-
final String localMatlab = Jenkins.getInstance()
233-
.getDescriptorByType(MatlabDescriptor.class).getLocalMatlab();
249+
final String matlabRoot = Jenkins.getInstance()
250+
.getDescriptorByType(MatlabDescriptor.class).getMatlabRoot();
234251
if (taCoberturaChkBx) {
235252
listOfCheckMethods.add(chkCoberturaSupport);
236253
}
237254
return Jenkins.getInstance().getDescriptorByType(MatlabDescriptor.class)
238-
.getFirstErrorOrWarning(listOfCheckMethods, localMatlab);
239-
}
240-
241-
Function<String, FormValidation> chkCoberturaSupport = (String localMatlab) -> {
242-
rel = new MatlabReleaseInfo(localMatlab);
243-
try {
244-
if (rel.verLessThan(BASE_MATLAB_VERSION_COBERTURA_SUPPORT)) {
245-
return FormValidation
246-
.warning(Message.getValue("Builder.matlab.cobertura.support.warning"));
255+
.getFirstErrorOrWarning(listOfCheckMethods, matlabRoot);
256+
}
257+
258+
Function<String, FormValidation> chkCoberturaSupport = (String matlabRoot) -> {
259+
rel = new MatlabReleaseInfo(matlabRoot);
260+
final MatrixPatternResolver resolver = new MatrixPatternResolver(matlabRoot);
261+
if(!resolver.hasVariablePattern()) {
262+
try {
263+
if (rel.verLessThan(BASE_MATLAB_VERSION_COBERTURA_SUPPORT)) {
264+
return FormValidation
265+
.warning(Message.getValue("Builder.matlab.cobertura.support.warning"));
266+
}
267+
} catch (MatlabVersionNotFoundException e) {
268+
return FormValidation.error(Message.getValue("Builder.invalid.matlab.root.error"));
247269
}
248-
} catch (MatlabVersionNotFoundException e) {
249-
return FormValidation.error(Message.getValue("Builder.invalid.matlab.root.error"));
250270
}
271+
251272

252273
return FormValidation.ok();
253274
};
@@ -370,30 +391,30 @@ public String getStringByName(String memberName) {
370391
@Override
371392
public void perform(@Nonnull Run<?, ?> build, @Nonnull FilePath workspace,
372393
@Nonnull Launcher launcher, @Nonnull TaskListener listener)
373-
throws InterruptedException, IOException {
374-
final EnvVars env = build.getEnvironment(listener);
394+
throws InterruptedException, IOException {
375395
final boolean isLinuxLauncher = launcher.isUnix();
376396

377397
// Invoke MATLAB command and transfer output to standard
378398
// Output Console
379399

380-
buildResult = execMatlabCommand(build, workspace, launcher, listener, env, isLinuxLauncher);
400+
buildResult = execMatlabCommand(build, workspace, launcher, listener, isLinuxLauncher);
381401

382402
if (buildResult != 0) {
383403
build.setResult(Result.FAILURE);
384404
}
385405
}
386406

387-
private int execMatlabCommand(Run<?, ?> build, FilePath workspace, Launcher launcher,
388-
TaskListener listener, EnvVars env, boolean isLinuxLauncher)
407+
private synchronized int execMatlabCommand(Run<?, ?> build, FilePath workspace, Launcher launcher,
408+
TaskListener listener, boolean isLinuxLauncher)
389409
throws IOException, InterruptedException {
410+
setEnv(build.getEnvironment(listener));
390411
//Copy MATLAB scratch file into the workspace
391412
copyMatlabScratchFileInWorkspace(MATLAB_RUNNER_RESOURCE, MATLAB_RUNNER_TARGET_FILE,
392413
workspace, getClass().getClassLoader());
393414
ProcStarter matlabLauncher;
394415
try {
395416
MatlabReleaseInfo rel = new MatlabReleaseInfo(getLocalMatlab());
396-
matlabLauncher = launcher.launch().pwd(workspace).envs(env);
417+
matlabLauncher = launcher.launch().pwd(workspace).envs(this.env);
397418
if (rel.verLessThan(BASE_MATLAB_VERSION_BATCH_SUPPORT)) {
398419
ListenerLogDecorator outStream = new ListenerLogDecorator(listener);
399420
matlabLauncher = matlabLauncher.cmds(constructDefaultMatlabCommand(isLinuxLauncher)).stderr(outStream);
@@ -421,13 +442,13 @@ public List<String> constructMatlabCommandWithBatch() {
421442
+ getTestRunTypeList().getBooleanByName("taCoberturaChkBx") + "))";
422443
} else {
423444

424-
runCommand = this.getTestRunTypeList().getStringByName("customMatlabCommand");
445+
runCommand = getCustomMatlabCommand();
425446
}
426447

427448
matlabDefaultArgs =
428-
Arrays.asList(this.localMatlab + File.separator + "bin" + File.separator + "matlab",
449+
Arrays.asList(getLocalMatlab() + File.separator + "bin" + File.separator + "matlab",
429450
"-batch", runCommand);
430-
451+
431452
return matlabDefaultArgs;
432453
}
433454

@@ -448,7 +469,7 @@ public List<String> constructDefaultMatlabCommand(boolean isLinuxLauncher) {
448469

449470
private String[] getPreRunnerSwitches() {
450471
String[] preRunnerSwitches =
451-
{this.localMatlab + File.separator + "bin" + File.separator + "matlab", "-nosplash",
472+
{getLocalMatlab() + File.separator + "bin" + File.separator + "matlab", "-nosplash",
452473
"-nodesktop", "-noAppIcon"};
453474
return preRunnerSwitches;
454475
}
@@ -471,7 +492,7 @@ private String[] getRunnerSwitch() {
471492
+ getTestRunTypeList().getBooleanByName("taCoberturaChkBx")
472493
+ ")),catch e,disp(getReport(e,'extended')),exit(1),end";
473494
} else {
474-
runCommand = "try,eval(\"" + this.getTestRunTypeList().getStringByName("customMatlabCommand").replaceAll("\"","\"\"")
495+
runCommand = "try,eval(\"" + getCustomMatlabCommand().replaceAll("\"","\"\"")
475496
+ "\"),catch e,disp(getReport(e,'extended')),exit(1),end,exit";
476497
}
477498

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.mathworks.ci;
2+
/*
3+
* Copyright 2019 The MathWorks, Inc.
4+
*
5+
* This is Matrix pattern resolver class which is a utility for identifying variables. Either $xyz, ${xyz} or ${a.b} but not $a.b, while ignoring "$$"
6+
*/
7+
8+
import java.util.regex.Matcher;
9+
import java.util.regex.Pattern;
10+
11+
public class MatrixPatternResolver {
12+
private String inputString;
13+
private static Pattern VARIBLE = Pattern.compile("\\$([A-Za-z0-9_]+|\\{[A-Za-z0-9_.]+\\}|\\$)");
14+
15+
public MatrixPatternResolver(String inputString) {
16+
this.inputString = inputString;
17+
}
18+
19+
public String getInputString() {
20+
return this.inputString;
21+
}
22+
23+
public boolean hasVariablePattern() {
24+
Matcher m = VARIBLE.matcher(getInputString());
25+
return m.find(0);
26+
}
27+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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

44
<f:section>
5-
<f:entry title="MATLAB root " field="localMatlab">
5+
<f:entry title="MATLAB root " field="matlabRoot">
66
<f:textbox/>
77
</f:entry>
88
</f:section>

0 commit comments

Comments
 (0)