Skip to content

Commit

Permalink
[FIXED JENKINS-11369] adding toolinstallation support for p4 exe
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Petti committed Feb 27, 2012
2 parents 69cf2bf + 449b34e commit 762fc5c
Show file tree
Hide file tree
Showing 15 changed files with 536 additions and 30 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -3,3 +3,6 @@
*.iws
target
work
.classpath
.settings
.project
93 changes: 83 additions & 10 deletions src/main/java/hudson/plugins/perforce/PerforceSCM.java
Expand Up @@ -90,7 +90,11 @@ public class PerforceSCM extends SCM {
String p4Counter;
String p4Stream;

String p4Exe = "C:\\Program Files\\Perforce\\p4.exe";
/**
* Transient so that old XML data will be read but not saved.
* @deprecated Replaced by {@link #p4Tool}
*/
transient String p4Exe;
String p4SysDrive = "C:";
String p4SysRoot = "C:\\WINDOWS";

Expand All @@ -100,6 +104,11 @@ public class PerforceSCM extends SCM {

private static final int MAX_CHANGESETS_ON_FIRST_BUILD = 50;

/**
* Name of the p4 tool installation
*/
String p4Tool;

/**
* Use ClientSpec text file from depot to prepare the workspace view
*/
Expand Down Expand Up @@ -250,7 +259,7 @@ public PerforceSCM(
String p4Client,
String p4Port,
String projectOptions,
String p4Exe,
String p4Tool,
String p4SysRoot,
String p4SysDrive,
String p4Label,
Expand Down Expand Up @@ -283,6 +292,7 @@ public PerforceSCM(
this.exposeP4Passwd = exposeP4Passwd;
this.p4Client = p4Client;
this.p4Port = p4Port;
this.p4Tool = p4Tool;
this.pollOnlyOnMaster = pollOnlyOnMaster;
this.projectOptions = (projectOptions != null)
? projectOptions
Expand All @@ -300,9 +310,6 @@ public PerforceSCM(

this.projectPath = Util.fixEmptyAndTrim(projectPath);

if (p4Exe != null)
this.p4Exe = Util.fixEmptyAndTrim(p4Exe);

if (p4SysRoot != null && p4SysRoot.length() != 0)
this.p4SysRoot = Util.fixEmptyAndTrim(p4SysRoot);

Expand Down Expand Up @@ -392,7 +399,7 @@ else if(project != null)
depot.setPassword(getDecryptedP4Passwd());
}

depot.setExecutable(p4Exe);
depot.setExecutable(getP4Executable(p4Tool));
depot.setSystemDrive(p4SysDrive);
depot.setSystemRoot(p4SysRoot);

Expand Down Expand Up @@ -446,6 +453,38 @@ else if (pta.getTag() != null) {
}
}

/**
* Get the path to p4 executable from a Perforce tool installation.
*
* @param tool the p4 tool installation
* @return path to p4 executable or empty string if there are no tool installations
*/
public String getP4Executable(String tool) {
PerforceToolInstallation[] installations = ((hudson.plugins.perforce.PerforceToolInstallation.DescriptorImpl)Hudson.getInstance().
getDescriptorByType(PerforceToolInstallation.DescriptorImpl.class)).getInstallations();
for(PerforceToolInstallation i : installations) {
if(i.getName().equals(tool)) {
return i.getP4Exe();
}
}
return "";
}

/**
* Use the old job configuration data. This method is called after the object is read by XStream.
* We want to create tool installations for each individual "p4Exe" path as field "p4Exe" has been removed.
*
* @return the new object which is an instance of PerforceSCM
*/
public Object readResolve() {
if (p4Exe != null)
{
PerforceToolInstallation.migrateOldData(p4Exe);
p4Tool = p4Exe;
}
return this;
}

private Hashtable<String, String> getDefaultSubstitutions(AbstractProject project) {
Hashtable<String, String> subst = new Hashtable<String, String>();
subst.put("JOB_NAME", getSafeJobName(project));
Expand Down Expand Up @@ -1437,6 +1476,16 @@ public SCM newInstance(StaplerRequest req, JSONObject formData) throws FormExcep
return newInstance;
}

/**
* List available tool installations.
*
* @return list of available p4 tool installations
*/
public List<PerforceToolInstallation> getP4Tools() {
PerforceToolInstallation[] p4ToolInstallations = Hudson.getInstance().getDescriptorByType(PerforceToolInstallation.DescriptorImpl.class).getInstallations();
return Arrays.asList(p4ToolInstallations);
}

public String isValidProjectPath(String path) {
if (!path.startsWith("//")) {
return "Path must start with '//' (Example: //depot/ProjectName/...)";
Expand All @@ -1451,11 +1500,11 @@ public String isValidProjectPath(String path) {

protected Depot getDepotFromRequest(StaplerRequest request) {
String port = fixNull(request.getParameter("port")).trim();
String exe = fixNull(request.getParameter("exe")).trim();
String tool = fixNull(request.getParameter("tool")).trim();
String user = fixNull(request.getParameter("user")).trim();
String pass = fixNull(request.getParameter("pass")).trim();

if (port.length() == 0 || exe.length() == 0) { // Not enough entered yet
if (port.length() == 0 || tool.length() == 0) { // Not enough entered yet
return null;
}
Depot depot = new Depot();
Expand All @@ -1468,7 +1517,17 @@ protected Depot getDepotFromRequest(StaplerRequest request) {
depot.setPassword(pass);
}
depot.setPort(port);

String exe = "";
PerforceToolInstallation[] installations = ((hudson.plugins.perforce.PerforceToolInstallation.DescriptorImpl)Hudson.getInstance().
getDescriptorByType(PerforceToolInstallation.DescriptorImpl.class)).getInstallations();
for(PerforceToolInstallation i : installations) {
if(i.getName().equals(tool)) {
exe = i.getP4Exe();
}
}
depot.setExecutable(exe);

try {
Counter counter = depot.getCounters().getCounter("change");
if (counter != null)
Expand Down Expand Up @@ -2117,18 +2176,32 @@ public void setP4SysRoot(String sysRoot) {
}

/**
* @return the p4Exe
* @deprecated Replaced by {@link #getP4Tool()}
*/
public String getP4Exe() {
return p4Exe;
}

/**
* @param exe the p4Exe to set
* @deprecated Replaced by {@link #setP4Tool(String)}
*/
public void setP4Exe(String exe) {
p4Exe = exe;
}

/**
* @return the p4Tool
*/
public String getP4Tool() {
return p4Tool;
}

/**
* @param tool the p4 tool installation to set
*/
public void setP4Tool(String tool) {
p4Tool = tool;
}

/**
* @return the p4Label
Expand Down
158 changes: 158 additions & 0 deletions src/main/java/hudson/plugins/perforce/PerforceToolInstallation.java
@@ -0,0 +1,158 @@
package hudson.plugins.perforce;

import hudson.CopyOnWrite;
import hudson.EnvVars;
import hudson.Extension;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
import hudson.model.EnvironmentSpecific;
import hudson.model.Hudson;
import hudson.model.Node;
import hudson.model.TaskListener;
import hudson.slaves.NodeSpecific;
import hudson.tools.ToolDescriptor;
import hudson.tools.ToolInstallation;
import hudson.tools.ToolProperty;
import hudson.util.FormValidation;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;

import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
* Information about Perforce installation. This includes the path to p4 executable.
*
*/
public final class PerforceToolInstallation extends ToolInstallation implements NodeSpecific<PerforceToolInstallation>, EnvironmentSpecific<PerforceToolInstallation> {

//To store migrated data as all the tool installations are created on one go.
static transient ArrayList<PerforceToolInstallation> p4Tools = new ArrayList<PerforceToolInstallation>();

/**
* Default constructor.
*
* @param name Installation name
* @param home Path to p4.exe
* @param properties Additional tool installation data
*/
@DataBoundConstructor
public PerforceToolInstallation(String name, String home, List<? extends ToolProperty<?>> properties) {
super(name, home, properties);
}

/**
* Get the path to p4.exe
*
* @return Path to p4.exe
*/
public String getP4Exe() {
return getHome();
}

/**
* Migrate old data into new tool installations if needed.
*/
@Initializer(after=InitMilestone.JOB_LOADED)
public static void onLoaded() {
DescriptorImpl descriptor = (DescriptorImpl) Hudson.getInstance().getDescriptor(PerforceToolInstallation.class);
PerforceToolInstallation[] installations = descriptor.getInstallations();

//Allow only one migration round. Old "p4Exe" field is kept in job configuration until the job is saved.
if (installations.length > 0) {
return;
}

if (!p4Tools.isEmpty()) {
Hudson.getInstance().getDescriptorByType(DescriptorImpl.class).setInstallations(p4Tools.toArray(new PerforceToolInstallation[p4Tools.size()]));
}
}

/**
* Migrate data from old job specific "p4Exe" field. Create a tool installation for each
* individual path with the path as the tool name.
*
* @param exe The path to p4 executable
*/
public static void migrateOldData(String exe) {
for (PerforceToolInstallation tool : p4Tools) {
//Tool installation already exists, Unix case
if (File.separatorChar == '/' && tool.getName().equals(exe)) {
return;
}
//Tool installation already exists, Windows case
if (File.separatorChar != '/' && tool.getName().equalsIgnoreCase(exe)) {
return;
}
}
p4Tools.add(new PerforceToolInstallation(exe, exe, Collections.<ToolProperty<?>>emptyList()));
}

public PerforceToolInstallation forNode(Node node, TaskListener log) throws IOException, InterruptedException {
return new PerforceToolInstallation(getName(), translateFor(node, log), Collections.<ToolProperty<?>>emptyList());
}

public PerforceToolInstallation forEnvironment(EnvVars environment) {
return new PerforceToolInstallation(getName(), environment.expand(getHome()), Collections.<ToolProperty<?>>emptyList());
}

@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) Hudson.getInstance().getDescriptor(PerforceToolInstallation.class);
}

@Extension
public static class DescriptorImpl extends ToolDescriptor<PerforceToolInstallation> {
@CopyOnWrite
private volatile PerforceToolInstallation[] installations = new PerforceToolInstallation[0];

public DescriptorImpl() {
super();
load();
}

@Override
public String getDisplayName() {
return "Perforce";
}

@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
super.configure(req, json);
save();
return true;
}

@Override
public PerforceToolInstallation[] getInstallations() {
return installations;
}

@Override
public void setInstallations(PerforceToolInstallation... installations) {
this.installations = installations;
save();
}

/**
* Checks if the path to p4 executable exists.
*/
public FormValidation doCheckHome(@QueryParameter File value)
throws IOException, ServletException {

Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
String path = value.getPath();

return FormValidation.validateExecutable(path);
}
}

}

@@ -0,0 +1 @@
PerforceToolInstallation.onLoaded=Checking p4 executable migration

0 comments on commit 762fc5c

Please sign in to comment.