Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate build steps by adding two new builders #72

Merged
merged 23 commits into from
Mar 3, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9cef36d
Added new Builders for script and test run.
nbhoski Feb 12, 2020
9c2bc9c
Added new Builders for script and test run.
nbhoski Feb 12, 2020
f8c6f4d
Merge branch 'CI-368-add-new-builders' of https:/mathwork…
nbhoski Feb 13, 2020
2365534
Added Unit tests and changed Command construct utility.
nbhoski Feb 19, 2020
719b57d
Added Script builder tests
nbhoski Feb 19, 2020
a00a94b
Resolved codehause issues.
nbhoski Feb 20, 2020
a98285e
Updated as per review comments.
nbhoski Feb 20, 2020
95f7742
Updated run matlab command UI & help content.
nbhoski Feb 24, 2020
ff3f51e
Adopted run_matlab_runner script file to construct matlab command.
nbhoski Feb 25, 2020
1e4ac95
Changes updated to work with bash & remove unwanted util class.
nbhoski Feb 26, 2020
2ec6b1c
Updated Test builder
nbhoski Feb 26, 2020
3640322
UPdated test cases
nbhoski Feb 26, 2020
45c5193
Updated descriptor names-review comment.
nbhoski Feb 27, 2020
34ba3a5
Refactored the common code using default methods.
nbhoski Feb 27, 2020
1e76537
Updated review comments.
nbhoski Feb 28, 2020
51b2e30
Updated tests
nbhoski Feb 28, 2020
f1f4cb8
Updated custom command help
nbhoski Feb 28, 2020
77c82ef
Updated matlab-Root help content.
nbhoski Mar 2, 2020
dd51fce
Added hlep file for Build Wrapper Use MATLAB version.
nbhoski Mar 2, 2020
fef070e
UPdated the FormvalidationUtil to get matlabroot in correct way.
nbhoski Mar 2, 2020
7a4edf8
Updated help content.
nbhoski Mar 2, 2020
3d764b3
formatted help text for junit,tap & cobertura.
nbhoski Mar 2, 2020
06f1582
Updated form validation logic to get matlab root value.
nbhoski Mar 3, 2020
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
52 changes: 51 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,31 @@
<url>http:/jenkinsci/matlab-plugin</url>
<tag>HEAD</tag>
</scm>

<build>
<plugins>
<!-- Plugin to download the matlab run scripts and keep it under class
path -->
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<id>get-matlab-runner-scripts</id>
<phase>validate</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://ssd.mathworks.com/supportfiles/ci/run-matlab-command/v0/run-matlab-command.zip</url>
<unpack>true</unpack>
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
Expand Down Expand Up @@ -92,6 +115,33 @@
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<!-- Delete the runner files during clean operation -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>default-clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<filesets>
<fileset>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*.bat</include>
<include>**/*.sh</include>
<include>**/*.txt</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
Expand Down
155 changes: 155 additions & 0 deletions src/main/java/com/mathworks/ci/AddMatlabToPathBuildWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package com.mathworks.ci;

/**
* Copyright 2019-2020 The MathWorks, Inc.
*
* This class is BuildWrapper which accepts the "matlabroot" from user and updates the PATH varible with it.
* which could be later used across build.
*
*/

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;
import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractProject;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.tasks.BuildWrapperDescriptor;
import hudson.util.FormValidation;
import hudson.util.FormValidation.Kind;
import jenkins.tasks.SimpleBuildWrapper;

public class AddMatlabToPathBuildWrapper extends SimpleBuildWrapper {

private String matlabRootFolder;
private EnvVars env;

@DataBoundConstructor
public AddMatlabToPathBuildWrapper() {}

public String getMatlabRootFolder() {
mw-akumar marked this conversation as resolved.
Show resolved Hide resolved
return this.matlabRootFolder;
}

@DataBoundSetter
public void setMatlabRootFolder(String matlabRootFolder) {
this.matlabRootFolder = matlabRootFolder;
}

private String getLocalMatlab() {
return this.env == null ? getMatlabRootFolder() : this.env.expand(getMatlabRootFolder());
}

private void setEnv(EnvVars env) {
this.env = env;
}

@Symbol("Matlab")
@Extension
public static final class MatlabBuildWrapperDescriptor extends BuildWrapperDescriptor {
nbhoski marked this conversation as resolved.
Show resolved Hide resolved

MatlabReleaseInfo rel;
String matlabRootFolder;

public String getMatlabRootFolder() {
return matlabRootFolder;
}

public void setMatlabRootFolder(String matlabRootFolder) {
this.matlabRootFolder = matlabRootFolder;
}

@Override
public boolean isApplicable(AbstractProject<?, ?> item) {
return true;
}

@Override
public String getDisplayName() {
return Message.getValue("Buildwrapper.display.name");
}


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


public FormValidation doCheckMatlabRootFolder(@QueryParameter String matlabRootFolder) {
setMatlabRootFolder(matlabRootFolder);
List<Function<String, FormValidation>> listOfCheckMethods =
new ArrayList<Function<String, FormValidation>>();
listOfCheckMethods.add(chkMatlabEmpty);
listOfCheckMethods.add(chkMatlabSupportsRunTests);

return getFirstErrorOrWarning(listOfCheckMethods, matlabRootFolder);
}

public FormValidation getFirstErrorOrWarning(
List<Function<String, FormValidation>> validations, String matlabRootFolder) {
if (validations == null || validations.isEmpty())
return FormValidation.ok();
for (Function<String, FormValidation> val : validations) {
FormValidation validationResult = val.apply(matlabRootFolder);
if (validationResult.kind.compareTo(Kind.ERROR) == 0
|| validationResult.kind.compareTo(Kind.WARNING) == 0) {
return validationResult;
}
}
return FormValidation.ok();
}

Function<String, FormValidation> chkMatlabEmpty = (String matlabRootFolder) -> {
if (matlabRootFolder.isEmpty()) {
return FormValidation.error(Message.getValue("Builder.matlab.root.empty.error"));
}
return FormValidation.ok();
};

Function<String, FormValidation> chkMatlabSupportsRunTests = (String matlabRootFolder) -> {
final MatrixPatternResolver resolver = new MatrixPatternResolver(matlabRootFolder);
if (!resolver.hasVariablePattern()) {
try {
FilePath matlabRootPath = new FilePath(new File(matlabRootFolder));
rel = new MatlabReleaseInfo(matlabRootPath);
if (rel.verLessThan(
MatlabBuilderConstants.BASE_MATLAB_VERSION_RUNTESTS_SUPPORT)) {
return FormValidation
.error(Message.getValue("Builder.matlab.test.support.error"));
}
} catch (MatlabVersionNotFoundException e) {
return FormValidation
.warning(Message.getValue("Builder.invalid.matlab.root.warning"));
}
}
return FormValidation.ok();
};
}

@Override
public void setUp(Context context, Run<?, ?> build, FilePath workspace, Launcher launcher,
TaskListener listener, EnvVars initialEnvironment)
throws IOException, InterruptedException {
CommandConstructUtil utils = new CommandConstructUtil(launcher, getLocalMatlab());
// Set Environment variable

setEnv(initialEnvironment);
String nodeSpecificFileSep = utils.getNodeSpecificFileSeperator();
// Add "matlabroot" without bin as env variable which will be available across the build.
context.env("matlabroot", getLocalMatlab());
// Add matlab bin to path to invoke MATLAB directly on command line.
context.env("PATH+matlabroot", getLocalMatlab() + nodeSpecificFileSep + "bin");
}
}
102 changes: 102 additions & 0 deletions src/main/java/com/mathworks/ci/CommandConstructUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.mathworks.ci;
/*
* Copyright 2020-2021 The MathWorks, Inc.
nbhoski marked this conversation as resolved.
Show resolved Hide resolved
*
* MATLAB command construction utility class used to construct the startup command based on the
* builders. Author : Nikhil Bhoski email : [email protected] Date : 11/02/2020
*/
nbhoski marked this conversation as resolved.
Show resolved Hide resolved

import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.FilenameUtils;
import hudson.FilePath;
import hudson.Launcher;

public class CommandConstructUtil {

private Launcher launcher;
private String matlabRoot;

public Launcher getLauncher() {
return launcher;
}

public void setLauncher(Launcher launcher) {
this.launcher = launcher;
}

public String getMatlabRoot() {
return matlabRoot;
}


/*
* Constructor to accepts the current launcher instance of the build with two parameters
* launcher : Launcher associated with current build instance matlabRoot: Expanded string value
* of MATLAB root
*/

public CommandConstructUtil(Launcher launcher, String matlabRoot) {
this.launcher = launcher;
this.matlabRoot = matlabRoot;
}

/*
* New set of methods for new changes with run matlab command script
*/

public String constructCommandForTest(String inputArguments) {
String runCommand;
String matlabFunctionName = FilenameUtils.removeExtension(
Message.getValue(MatlabBuilderConstants.MATLAB_RUNNER_TARGET_FILE));
runCommand = "exit(" + matlabFunctionName + "(" + inputArguments + "))";
if(isUnix()) {
runCommand = getBashCompatibleCommandString(runCommand);
}
return runCommand;
}

public String constructCommandForRunCommand(String command) {
String runCommand = command;
if(isUnix()) {
runCommand = getBashCompatibleCommandString(command);
}
return runCommand;
}

public String getNodeSpecificFileSeperator() {
if (getLauncher().isUnix()) {
return "/";
} else {
return "\\";
}
}

public boolean isUnix() {
return this.launcher.isUnix();
}

/*
* This Method is to escape all open and closing brackets and single quotes
* to make it compatible with /bin/bash -c command on linux
*
*/
private String getBashCompatibleCommandString(String command) {
return command.replaceAll("'","\\\\'").replaceAll("\\(", "\\\\(").replaceAll("\\)", "\\\\)");
}

public void copyMatlabScratchFileInWorkspace(String matlabRunnerResourcePath,
String matlabRunnerTarget, FilePath targetWorkspace)
throws IOException, InterruptedException {
final ClassLoader classLoader = getClass().getClassLoader();
FilePath targetFile =
new FilePath(targetWorkspace, Message.getValue(matlabRunnerTarget));
InputStream in = classLoader.getResourceAsStream(matlabRunnerResourcePath);
targetFile.copyFrom(in);
//set executable permission to the file on Unix.
if(isUnix()) {
targetFile.chmod(0777);
}

}
}
4 changes: 3 additions & 1 deletion src/main/java/com/mathworks/ci/MatlabBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ public void setMatlabRoot(String matlabRoot) {
// Overridden Method used to show the text under build dropdown
@Override
public String getDisplayName() {
return Message.getBuilderDisplayName();
// No name for this descriptor as its deprecated all the jobs will be
// automatically delegated to the new TestRun or Script builders.
return "";
}

@Override
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/mathworks/ci/MatlabBuilderConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ public class MatlabBuilderConstants {
static final String STM_RESULTS = "'SimulinkTestResults'";
static final String COBERTURA_CODE_COVERAGE = "'CoberturaCodeCoverage'";
static final String COBERTURA_MODEL_COVERAGE = "'CoberturaModelCoverage'";

// Matlab Runner files
static final String BAT_RUNNER_SCRIPT = "run_matlab_command.bat";
static final String SHELL_RUNNER_SCRIPT = "run_matlab_command.sh";
}
Loading