Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #15 from synopsys-arc-oss/master
[JENKINS-18814,JENKINS-22075] - Handling of deleted tools
  • Loading branch information
oleg-nenashev committed Mar 15, 2014
2 parents c7217ae + 56b546e commit f502329
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 62 deletions.
Expand Up @@ -44,6 +44,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;

import org.kohsuke.stapler.DataBoundConstructor;

Expand All @@ -62,7 +63,7 @@ public class CustomTool extends ToolInstallation implements
private final String exportedPaths;
private final LabelSpecifics[] labelSpecifics;
private static final LabelSpecifics[] EMPTY_LABELS = new LabelSpecifics[0];
private transient String correctedHome;
private transient String correctedHome = null;
private final ToolVersionConfig toolVersion;
private final String additionalVariables;

Expand Down Expand Up @@ -101,7 +102,10 @@ public LabelSpecifics[] getLabelSpecifics() {
return (labelSpecifics!=null) ? labelSpecifics : EMPTY_LABELS;
}

/**Check if the tool has additional variables set*/
/**
* Check if the tool has additional environment variables set.
* @return true when the tool injects additional environment variables.
*/
public boolean hasAdditionalVariables() {
return additionalVariables != null;
}
Expand Down Expand Up @@ -180,6 +184,12 @@ public void setInstallations(CustomTool... installations) {
save();
}

/**
* Gets a {@link CustomTool} by its name.
* @param name A name of the tool to be retrieved.
* @return A {@link CustomTool} or null if it has no found
*/
@CheckForNull
public CustomTool byName(String name) {
for (CustomTool tool : getInstallations()) {
if (tool.getName().equals(name)) {
Expand Down
Expand Up @@ -28,7 +28,6 @@
import hudson.Extension;
import hudson.Launcher;
import hudson.Proc;
import hudson.Util;
import hudson.matrix.MatrixBuild;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
Expand All @@ -42,10 +41,11 @@
import hudson.tasks.BuildWrapperDescriptor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import net.sf.json.JSONObject;

Expand All @@ -68,32 +68,49 @@ public class CustomToolInstallWrapper extends BuildWrapper {
*
*/
public static class SelectedTool {
private String name;
private final String name;

@DataBoundConstructor
public SelectedTool(String name) {
this.name = name;
}

public String getName() {
return name;
}

@Override
public String toString() {
return name;
}

@CheckForNull
public CustomTool toCustomTool() {
return ((CustomTool.DescriptorImpl)Hudson.getInstance().getDescriptor(CustomTool.class)).byName(name);
}

@Nonnull
public CustomTool toCustomToolValidated() throws CustomToolException {
CustomTool tool = toCustomTool();
if (tool == null) {
throw new CustomToolException(
Messages.CustomTool_GetToolByName_ErrorMessage(name));
}
return tool;
}
}

private SelectedTool[] selectedTools = new SelectedTool[0];
private MulticonfigWrapperOptions multiconfigOptions;
private boolean convertHomesToUppercase;
private final MulticonfigWrapperOptions multiconfigOptions;
private final boolean convertHomesToUppercase;

@DataBoundConstructor
public CustomToolInstallWrapper(SelectedTool[] selectedTools, MulticonfigWrapperOptions multiconfigOptions, boolean convertHomesToUppercase) {
this.selectedTools = (selectedTools != null) ? selectedTools : new SelectedTool[0];
this.multiconfigOptions = (multiconfigOptions != null) ? multiconfigOptions : MulticonfigWrapperOptions.DEFAULT;
this.convertHomesToUppercase = convertHomesToUppercase;
}

public boolean isConvertHomesToUppercase() {
return convertHomesToUppercase;
}
Expand All @@ -104,13 +121,15 @@ public Environment setUp(AbstractBuild build, Launcher launcher,

final EnvVars buildEnv = build.getEnvironment(listener);
final Node node = build.getBuiltOn();

return new Environment(){
return new Environment() {
@Override
public void buildEnvVars(Map<String, String> env) {
public void buildEnvVars(Map<String, String> env) {

// TODO: Inject Home dirs as well
for (CustomTool tool : customTools()) {
if (tool.hasVersions()) {
for (SelectedTool selectedTool : selectedTools) {
CustomTool tool = selectedTool.toCustomTool();
if (tool != null && tool.hasVersions()) {
ToolVersion version = ToolVersion.getEffectiveToolVersion(tool, buildEnv, node);
if (version != null && !env.containsKey(version.getVariableName())) {
env.put(version.getVariableName(), version.getDefaultVersion());
Expand All @@ -125,22 +144,16 @@ public SelectedTool[] getSelectedTools() {
return selectedTools.clone();
}

private List<CustomTool> customTools() {
List<CustomTool> tools = new ArrayList<CustomTool>();
for (SelectedTool selected : selectedTools) {
tools.add(selected.toCustomTool());
}
return tools;
}

/**
* The heart of the beast. Installs selected tools and exports their paths to the
* PATH and their HOMEs as environment variables.
* @return A decorated launcher
*/
@Override
public Launcher decorateLauncher(AbstractBuild build, final Launcher launcher,
BuildListener listener) throws IOException, InterruptedException,
RunnerAbortedException {
RunnerAbortedException {

EnvVars buildEnv = build.getEnvironment(listener);
final EnvVars homes = new EnvVars();
final EnvVars versions = new EnvVars();
Expand All @@ -149,20 +162,21 @@ public Launcher decorateLauncher(AbstractBuild build, final Launcher launcher,
final List<EnvVariablesInjector> additionalVarInjectors = new LinkedList<EnvVariablesInjector>();

// Handle multi-configuration build
if (MatrixBuild.class.isAssignableFrom(build.getClass())) {
CustomToolsLogger.LogMessage(listener, "Skipping installation of tools at the master job");
if (build instanceof MatrixBuild) {
CustomToolsLogger.logMessage(listener, "Skipping installation of tools at the master job");
if (multiconfigOptions.isSkipMasterInstallation()) {
return launcher;
}
}

// Each tool can export zero or many directories to the PATH
Node node = Computer.currentComputer().getNode();
for (CustomTool tool : customTools()) {
CustomToolsLogger.LogMessage(listener, tool.getName(), "Starting installation");
for (SelectedTool selectedToolName : selectedTools) {
CustomTool tool = selectedToolName.toCustomToolValidated();
CustomToolsLogger.logMessage(listener, tool.getName(), "Starting installation");

// Check versioning
CheckVersions(tool, listener, buildEnv, node, versions);
checkVersions(tool, listener, buildEnv, node, versions);

// This installs the tool if necessary
CustomTool installed = tool
Expand Down Expand Up @@ -191,16 +205,16 @@ public Launcher decorateLauncher(AbstractBuild build, final Launcher launcher,
if (!spec.appliesTo(node)) {
continue;
}
CustomToolsLogger.LogMessage(listener, installed.getName(), "Label specifics from '"+spec.getLabel()+"' will be applied");
CustomToolsLogger.logMessage(listener, installed.getName(), "Label specifics from '"+spec.getLabel()+"' will be applied");

if (spec.hasAdditionalVars()) {
additionalVarInjectors.add(EnvVariablesInjector.Create(spec.getAdditionalVars()));
}
}

CustomToolsLogger.LogMessage(listener, installed.getName(), "Tool is installed at "+ installed.getHome());
CustomToolsLogger.logMessage(listener, installed.getName(), "Tool is installed at "+ installed.getHome());
String homeDirVarName = (convertHomesToUppercase ? installed.getName().toUpperCase() : installed.getName()) +"_HOME";
CustomToolsLogger.LogMessage(listener, installed.getName(), "Setting "+ homeDirVarName+"="+installed.getHome());
CustomToolsLogger.logMessage(listener, installed.getName(), "Setting "+ homeDirVarName+"="+installed.getHome());
homes.put(homeDirVarName, installed.getHome());
}

Expand Down Expand Up @@ -248,7 +262,15 @@ private EnvVars toEnvVars(String[] envs) {
}

/**
* Check versions and modify build environment if required.
* @deprecated The method is deprecated. It will be removed in future versions.
*/
public void CheckVersions (CustomTool tool, BuildListener listener, EnvVars buildEnv, Node node, EnvVars target)
throws CustomToolException {
checkVersions(tool, listener, buildEnv, node, target);
}

/**
* Checks versions and modify build environment if required.
* @param tool Custom Tool
* @param listener Build Listener
* @param buildEnv Build Environment (can be modified)
Expand All @@ -257,16 +279,16 @@ private EnvVars toEnvVars(String[] envs) {
* @throws CustomToolException
* @since 0.4
*/
public void CheckVersions (CustomTool tool, BuildListener listener, EnvVars buildEnv, Node node, EnvVars target) throws CustomToolException {
public void checkVersions (CustomTool tool, BuildListener listener, EnvVars buildEnv, Node node, EnvVars target) throws CustomToolException {
// Check version
if (tool.hasVersions()) {
ToolVersion version = ToolVersion.getEffectiveToolVersion(tool, buildEnv, node);
if (version == null) {
CustomToolsLogger.LogMessage(listener, tool.getName(), "Error: No version has been specified, no default version. Failing the build...");
CustomToolsLogger.logMessage(listener, tool.getName(), "Error: No version has been specified, no default version. Failing the build...");
throw new CustomToolException("Version has not been specified for the "+tool.getName());
}

CustomToolsLogger.LogMessage(listener, tool.getName(), "Version "+version.getActualVersion()+" has been specified by "+version.getVersionSource());
CustomToolsLogger.logMessage(listener, tool.getName(), "Version "+version.getActualVersion()+" has been specified by "+version.getVersionSource());

// Override default versions
if (version.getVersionSource().equals(ToolVersion.DEFAULTS_SOURCE)) {
Expand Down
Expand Up @@ -18,18 +18,34 @@
import hudson.model.BuildListener;

/**
*
* Provides logging routines for the plugin.
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since 0.3
*/
public class CustomToolsLogger {
public static final String LOG_PREFIX = "[CustomTools] - ";

/**
* @deprecated Use {@link #logMessage(hudson.model.BuildListener, java.lang.String)}
* instead.
*/
public static void LogMessage(BuildListener listener, String message) {
listener.getLogger().println(CustomToolsLogger.LOG_PREFIX+message);
logMessage(listener, message);
}

/**
* @deprecated Use {@link #logMessage(hudson.model.BuildListener, java.lang.String, java.lang.String)}
* instead.
*/
public static void LogMessage(BuildListener listener, String toolName, String message) {
logMessage(listener, toolName, message);
}

public static void logMessage(BuildListener listener, String message) {
listener.getLogger().println(CustomToolsLogger.LOG_PREFIX+message);
}

public static void logMessage(BuildListener listener, String toolName, String message) {
listener.getLogger().println(CustomToolsLogger.LOG_PREFIX+toolName+": "+message);
}
}
Expand Up @@ -33,7 +33,21 @@ public class EnvVariablesInjector extends TreeMap<String, EnvVariablesInjector.E
{
private EnvVariablesInjector(){}

/**
* @deprecated Use {@link #create(java.lang.String)} instead.
* This method will be removed in future versions.
*/
public static EnvVariablesInjector Create(String props) throws IOException {
return create(props);
}

/**
* Creates a new injector for the specified properties.
* @param props Properties in Java Properties format
* @return A new injector
* @throws IOException Cannot load properties from the string
*/
public static EnvVariablesInjector create(String props) throws IOException {
Properties prop = new Properties();
StringReader rdr = new StringReader(props);
prop.load(rdr);
Expand All @@ -48,12 +62,20 @@ public static EnvVariablesInjector Create(String props) throws IOException {
return vars;
}

/**
* @deprecated Use {@link #injectVariables(hudson.EnvVars)} instead.
* This method will be removed in future versions.
*/
public void Inject(EnvVars target) throws IOException {
injectVariables(target);
}

/**
* Inject variables into EnvVars
* @param target Target variables
* @throws IOException Exception during modification of EnvVars
*/
public void Inject(EnvVars target) throws IOException {
public void injectVariables(EnvVars target) throws IOException {
for (Entry<String, EnvVariablesInjector.Entity> entry: entrySet()) {
entry.getValue().Inject(target);
}
Expand Down Expand Up @@ -94,17 +116,25 @@ public Entity(String envName, String envValue, String listDelimiter,
{
this.envName = envName;
this.envValue = envValue;
this.listDelimiter = listDelimiter;
this.isList = isList;
this.isOverrides = isOverrides;
// this.listDelimiter = listDelimiter;
// this.isList = isList;
// this.isOverrides = isOverrides;
}

/**
* @deprecated Use {@link #injectVariables(hudson.EnvVars)} instead.
* This method will be removed in future versions.
*/
public void Inject(EnvVars target) throws IOException {
injectVariables(target);
}

/**
* Inject variables into EnvVars
* @param target Target environment
* @throws IOException Exception during modification of EnvVars
*/
public void Inject(EnvVars target) throws IOException {
public void injectVariables(EnvVars target) throws IOException {
//TODO: check overrides
//TODO: check lists
//TODO: substitute, check, etc.
Expand All @@ -115,7 +145,5 @@ public void Inject(EnvVars target) throws IOException {

target.put(envName, newEnvValue);
}
}


}
}
Expand Up @@ -19,7 +19,6 @@
import hudson.Extension;
import hudson.Util;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.Label;
import hudson.model.Node;
Expand All @@ -33,9 +32,10 @@
* @since 0.3
*/
public class LabelSpecifics extends AbstractDescribableImpl<LabelSpecifics> implements Serializable {
private String label;
private String additionalVars;
private String exportedPaths;

private final String label;
private final String additionalVars;
private final String exportedPaths;

@DataBoundConstructor
public LabelSpecifics(String label, String additionalVars, String exportedPaths) {
Expand Down

0 comments on commit f502329

Please sign in to comment.