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

Commit e894502

Browse files
committed
Initial commit
1 parent 9f6db19 commit e894502

File tree

7 files changed

+147
-20
lines changed

7 files changed

+147
-20
lines changed

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.Arrays;
1616
import java.util.List;
1717
import javax.annotation.CheckForNull;
18+
import jenkins.model.Jenkins;
1819
import net.sf.json.JSONObject;
1920
import org.jenkinsci.Symbol;
2021
import org.kohsuke.stapler.DataBoundConstructor;
@@ -28,6 +29,14 @@ public MatlabInstallation(String name, @CheckForNull String home, List<? extends
2829
super(Util.fixEmptyAndTrim(name), Util.fixEmptyAndTrim(home), properties);
2930
}
3031

32+
/*
33+
* Constructor for Custom object
34+
* */
35+
36+
public MatlabInstallation(String name){
37+
super(name, null, null);
38+
}
39+
3140
@Override public MatlabInstallation forEnvironment(EnvVars envVars) {
3241
return new MatlabInstallation(getName(), envVars.expand(getHome()), getProperties().toList());
3342
}
@@ -43,6 +52,23 @@ public void buildEnvVars(EnvVars env) {
4352
env.put("PATH+matlabroot", pathToExecutable);
4453
}
4554

55+
public static MatlabInstallation[] getAll () {
56+
return Jenkins.get().getDescriptorByType(DescriptorImpl.class).getInstallations();
57+
}
58+
59+
public static boolean isEmpty() {
60+
return getAll().length == 0;
61+
}
62+
63+
public static MatlabInstallation getInstallation(String name) {
64+
for (MatlabInstallation _inst : getAll()) {
65+
if (!name.isEmpty() && name.equals(_inst.getName())) {
66+
return _inst;
67+
}
68+
}
69+
return null;
70+
}
71+
4672
@Extension @Symbol("matlab")
4773
public static class DescriptorImpl extends ToolDescriptor<MatlabInstallation> {
4874
@CopyOnWrite
@@ -71,7 +97,5 @@ public void setInstallations(MatlabInstallation... matlabInstallations) {
7197
this.installations = matlabInstallations;
7298
save();
7399
}
74-
75100
}
76-
77101
}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import java.io.IOException;
1010
import javax.annotation.Nonnull;
11-
import org.jenkinsci.Symbol;
1211
import org.kohsuke.stapler.DataBoundConstructor;
1312
import org.kohsuke.stapler.DataBoundSetter;
1413
import org.kohsuke.stapler.StaplerRequest;
@@ -21,6 +20,7 @@
2120
import hudson.model.Result;
2221
import hudson.model.Run;
2322
import hudson.model.TaskListener;
23+
import hudson.model.Computer;
2424
import hudson.tasks.BuildStepDescriptor;
2525
import hudson.tasks.Builder;
2626
import jenkins.tasks.SimpleBuildStep;
@@ -101,7 +101,7 @@ public void perform(@Nonnull Run<?, ?> build, @Nonnull FilePath workspace,
101101

102102
// Invoke MATLAB command and transfer output to standard
103103
// Output Console
104-
104+
105105

106106
buildResult = execMatlabCommand(workspace, launcher, listener, getEnv());
107107

@@ -112,6 +112,13 @@ public void perform(@Nonnull Run<?, ?> build, @Nonnull FilePath workspace,
112112

113113
private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher,
114114
TaskListener listener, EnvVars envVars) throws IOException, InterruptedException {
115+
116+
/*
117+
* Handle the case for using MATLAB Axis for multi conf projects by adding appropriate
118+
* matlabroot to env PATH
119+
* */
120+
Utilities.addMatlabToEnvPathFrmAxis(Computer.currentComputer(), listener, getEnv());
121+
115122
final String uniqueTmpFldrName = getUniqueNameForRunnerFile();
116123
final String uniqueCommandFile =
117124
"command_" + getUniqueNameForRunnerFile().replaceAll("-", "_");

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import hudson.model.Result;
2626
import hudson.model.Run;
2727
import hudson.model.TaskListener;
28+
import hudson.model.Computer;
2829
import org.kohsuke.stapler.DataBoundConstructor;
2930
import org.kohsuke.stapler.DataBoundSetter;
3031
import org.kohsuke.stapler.StaplerRequest;
@@ -248,6 +249,13 @@ public void perform(@Nonnull Run<?, ?> build, @Nonnull FilePath workspace,
248249

249250
private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher,
250251
TaskListener listener, EnvVars envVars) throws IOException, InterruptedException {
252+
253+
/*
254+
* Handle the case for using MATLAB Axis for multi conf projects by adding appropriate
255+
* matlabroot to env PATH
256+
* */
257+
Utilities.addMatlabToEnvPathFrmAxis(Computer.currentComputer(), listener, getEnv());
258+
251259
final String uniqueTmpFldrName = getUniqueNameForRunnerFile();
252260
ProcStarter matlabLauncher;
253261
try {

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

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
*/
1010

1111
import java.io.File;
12-
import java.io.FileNotFoundException;
1312
import java.io.IOException;
1413
import java.util.ArrayList;
14+
import java.util.Arrays;
1515
import java.util.List;
1616
import java.util.function.Function;
1717

18-
import org.jenkinsci.Symbol;
18+
import hudson.matrix.MatrixProject;
19+
import hudson.model.Computer;
1920
import org.kohsuke.stapler.DataBoundConstructor;
2021
import org.kohsuke.stapler.DataBoundSetter;
2122
import org.kohsuke.stapler.QueryParameter;
@@ -33,9 +34,9 @@
3334

3435
public class UseMatlabVersionBuildWrapper extends SimpleBuildWrapper {
3536

36-
3737
private String matlabRootFolder;
3838
private EnvVars env;
39+
private String matlabInstName;
3940

4041
@DataBoundConstructor
4142
public UseMatlabVersionBuildWrapper() {}
@@ -44,13 +45,41 @@ public String getMatlabRootFolder() {
4445
return this.matlabRootFolder;
4546
}
4647

47-
@DataBoundSetter
48+
public String getMatlabInstHome(Computer cmp, TaskListener listener)
49+
throws IOException, InterruptedException {
50+
return Utilities.getNodeSpecificHome(this.matlabInstName, cmp.getNode(), listener);
51+
}
52+
53+
public String getMatlabInstName() {
54+
/* For backward compatibility assign installation name to custom
55+
* if matlabRootFolder is not null.
56+
* */
57+
if(this.matlabInstName!=null && !this.matlabInstName.isEmpty() && this.matlabRootFolder!=null && !this.matlabRootFolder.isEmpty()){
58+
this.matlabInstName = Message.getValue("matlab.custom.location");
59+
}
60+
return matlabInstName;
61+
}
62+
4863
public void setMatlabRootFolder(String matlabRootFolder) {
4964
this.matlabRootFolder = matlabRootFolder;
5065
}
5166

52-
private String getLocalMatlab() {
53-
return this.env == null ? getMatlabRootFolder() : this.env.expand(getMatlabRootFolder());
67+
@DataBoundSetter
68+
public void setMatlabBuildWrapperContent(MatlabBuildWrapperContent matlabBuildWrapperContent){
69+
if (matlabBuildWrapperContent != null){
70+
this.matlabInstName = matlabBuildWrapperContent.getMatlabInstName();
71+
this.matlabRootFolder = matlabBuildWrapperContent.getMatlabRootFolder();
72+
}
73+
}
74+
75+
private String getLocalMatlab(Computer cmp, TaskListener listener)
76+
throws IOException, InterruptedException {
77+
String matlabroot = getMatlabRootFolder();
78+
if (matlabroot == null || matlabroot.isEmpty()){
79+
matlabroot = getMatlabInstHome(cmp, listener);
80+
}
81+
82+
return this.env == null ? matlabroot : this.env.expand(matlabroot);
5483
}
5584

5685
private void setEnv(EnvVars env) {
@@ -63,6 +92,8 @@ public static final class UseMatlabVersionDescriptor extends BuildWrapperDescrip
6392

6493
MatlabReleaseInfo rel;
6594
String matlabRootFolder;
95+
private boolean isMatrix;
96+
private final String customLocation = Message.getValue("matlab.custom.location");
6697

6798
public String getMatlabRootFolder() {
6899
return matlabRootFolder;
@@ -74,6 +105,7 @@ public void setMatlabRootFolder(String matlabRootFolder) {
74105

75106
@Override
76107
public boolean isApplicable(AbstractProject<?, ?> item) {
108+
isMatrix = item instanceof MatrixProject;
77109
return true;
78110
}
79111

@@ -82,15 +114,24 @@ public String getDisplayName() {
82114
return Message.getValue("Buildwrapper.display.name");
83115
}
84116

117+
public MatlabInstallation[] getInstallations() {
118+
ArrayList<MatlabInstallation> arr;
119+
arr = new ArrayList<>(Arrays.asList(MatlabInstallation.getAll()));
120+
arr.add(new MatlabInstallation(customLocation));
121+
MatlabInstallation[] temp = new MatlabInstallation[arr.size()];
122+
return arr.toArray(temp);
123+
}
85124

86125
/*
87126
* Below methods with 'doCheck' prefix gets called by jenkins when this builder is loaded.
88127
* these methods are used to perform basic validation on UI elements associated with this
89128
* descriptor class.
90129
*/
91130

92-
93131
public FormValidation doCheckMatlabRootFolder(@QueryParameter String matlabRootFolder) {
132+
/*
133+
* If isMatrix or if empty installations or if selectedOption is specify loc
134+
* */
94135
setMatlabRootFolder(matlabRootFolder);
95136
List<Function<String, FormValidation>> listOfCheckMethods =
96137
new ArrayList<Function<String, FormValidation>>();
@@ -136,13 +177,13 @@ public synchronized void setUp(Context context, Run<?, ?> build, FilePath worksp
136177
setEnv(initialEnvironment);
137178

138179
FilePath matlabExecutablePath = new FilePath(launcher.getChannel(),
139-
getLocalMatlab() + "/bin/" + getNodeSpecificExecutable(launcher));
140-
180+
getLocalMatlab(Computer.currentComputer(), listener) + "/bin/" + getNodeSpecificExecutable(launcher));
181+
listener.getLogger().println("\n Using MATLAB : " + matlabExecutablePath.getRemote() + "\n");
141182
if (!matlabExecutablePath.exists()) {
142183
throw new MatlabNotFoundError(Message.getValue("matlab.not.found.error"));
143184
}
144185
// Add "matlabroot" without bin as env variable which will be available across the build.
145-
context.env("matlabroot", getLocalMatlab());
186+
context.env("matlabroot", getLocalMatlab(Computer.currentComputer(), listener));
146187
// Add matlab bin to path to invoke MATLAB directly on command line.
147188
context.env("PATH+matlabroot", matlabExecutablePath.getParent().getRemote());
148189
}

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
*
88
*/
99

10+
import hudson.EnvVars;
11+
import hudson.FilePath;
12+
import hudson.model.Computer;
13+
import hudson.model.Node;
14+
import hudson.model.TaskListener;
15+
16+
import java.io.IOException;
1017
import java.util.List;
18+
import java.util.Objects;
1119
import java.util.function.Predicate;
1220
import java.util.stream.Collectors;
1321

@@ -23,4 +31,37 @@ public static String getCellArrayFrmList(List<String> listOfStr){
2331
filteredListOfStr.replaceAll(val -> "'" + val.replaceAll("'", "''") + "'");
2432
return "{" + String.join(",", filteredListOfStr) + "}";
2533
}
34+
35+
public static void addMatlabToEnvPathFrmAxis(Computer cmp, TaskListener listener, EnvVars env)
36+
throws IOException, InterruptedException {
37+
String name = env.get(Message.getValue("Axis.matlab.key"));
38+
39+
// If no MATLAB axis is set or if 'Use MATLAB version' is selected, return
40+
if (name == null || name.isEmpty() || env.get("matlabroot") != null){
41+
return;
42+
}
43+
44+
String home = getNodeSpecificHome(name, cmp.getNode(), listener);
45+
String pathToExecutable = home + "/bin";
46+
env.put("PATH+matlabroot", pathToExecutable);
47+
}
48+
49+
public static String getNodeSpecificHome(String instName, Node node, TaskListener listener)
50+
throws IOException, InterruptedException {
51+
MatlabInstallation inst = MatlabInstallation.getInstallation(instName);
52+
if(inst != null) {
53+
inst = inst.forNode(node, listener);
54+
FilePath matlabExecutablePath = node.createPath(inst.getHome());
55+
// If no MATLAB version is configured for current node, throw error.
56+
if (matlabExecutablePath == null || !matlabExecutablePath.exists()) {
57+
throw new MatlabNotFoundError(String.format(Message.getValue("matlab.not.found.error.for.node"), instName, Objects
58+
.requireNonNull(node).getDisplayName()));
59+
}
60+
61+
return matlabExecutablePath.getRemote();
62+
}
63+
64+
// Following will error out in BuildWrapper
65+
return "";
66+
}
2667
}
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<?jelly escape-by-default='true'?>
2-
<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-
<f:entry title="MATLAB root " field="matlabRootFolder">
4-
<f:textbox/>
5-
</f:entry>
6-
</j:jelly>
2+
<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" xmlns:i="jelly:fmt" xmlns:p="/lib/hudson/project">
3+
<f:entry help="">
4+
<j:forEach var="installation" items="${descriptor.installations}">
5+
<f:checkbox name="values" json="${installation.name}" checked="${instance.values.contains(installation.name)}" title="${installation.name}" />
6+
<st:nbsp/>
7+
</j:forEach>
8+
</f:entry>
9+
</j:jelly>

src/main/resources/config.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ builder.matlab.automatictestoption.display.name = Automatic
1313
builder.matlab.customcommandoption.display.name = Custom
1414
Releaseinfo.matlab.version.not.found.error = Error finding MATLAB release for given MATLAB root. Verify MATLAB root path.
1515
matlab.not.found.error = Unable to launch MATLAB from the specified location. Verify the path to MATLAB root folder.
16+
matlab.not.found.error.for.node = Unable to launch MATLAB with name %s at node %s . Verify MATLAB tool installation for selected node.
1617
Builder.matlab.modelcoverage.support.warning = To generate a Cobertura model coverage report, use MATLAB R2018b or a newer release.
1718
Builder.matlab.exportstmresults.support.warning = To export Simulink Test Manager results, use MATLAB R2019a or a newer release.
1819
Builder.matlab.runner.script.target.file.linux.name = run_matlab_command.sh
@@ -21,4 +22,6 @@ build.workspace.computer.not.found = Unable to access the computer for this buil
2122
matlab.command.build.step.name = runMATLABCommand
2223
matlab.tests.build.step.name = runMATLABTests
2324
matlab.command.step.display.name = Run MATLAB commands, scripts, or functions
24-
matlab.tests.step.display.name = Run MATLAB tests and generate artifacts
25+
matlab.tests.step.display.name = Run MATLAB tests and generate artifacts
26+
matlab.custom.location = Custom..
27+
Axis.matlab.key = MATLAB

0 commit comments

Comments
 (0)