diff --git a/core/src/main/java/hudson/tools/ToolInstaller.java b/core/src/main/java/hudson/tools/ToolInstaller.java index f1d91e2af88c1eaa7dcfb10bfaa038df8d977b65..0651fca1161096a4122a9e63463aeefa9e776138 100644 --- a/core/src/main/java/hudson/tools/ToolInstaller.java +++ b/core/src/main/java/hudson/tools/ToolInstaller.java @@ -32,6 +32,8 @@ import jenkins.model.Jenkins; import hudson.model.Label; import hudson.model.Node; import hudson.model.TaskListener; + +import java.io.File; import java.io.IOException; import org.kohsuke.stapler.DataBoundConstructor; @@ -102,7 +104,7 @@ public abstract class ToolInstaller implements Describable, Exten * @param tool the tool being installed * @param node the computer on which to install the tool * @return {@link ToolInstallation#getHome} if specified, else a path within the local - * Hudson work area named according to {@link ToolInstallation#getName} + * Jenkins work area named according to {@link ToolInstallation#getName} * @since 1.310 */ protected final FilePath preferredLocation(ToolInstallation tool, Node node) { @@ -111,8 +113,7 @@ public abstract class ToolInstaller implements Describable, Exten } String home = Util.fixEmptyAndTrim(tool.getHome()); if (home == null) { - // XXX should this somehow uniquify paths among ToolInstallation.all()? - home = tool.getName().replaceAll("[^A-Za-z0-9_.-]+", "_"); + home = sanitize(tool.getDescriptor().getDisplayName()) + File.separatorChar + sanitize(tool.getName()); } FilePath root = node.getRootPath(); if (root == null) { @@ -121,6 +122,10 @@ public abstract class ToolInstaller implements Describable, Exten return root.child("tools").child(home); } + private String sanitize(String s) { + return s != null ? s.replaceAll("[^A-Za-z0-9_.-]+", "_") : null; + } + public ToolInstallerDescriptor getDescriptor() { return (ToolInstallerDescriptor) Jenkins.getInstance().getDescriptorOrDie(getClass()); }