Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #33 from jenkinsci/multiple-scm-instatination-fix
[IN_PROGRESS][JENKINS-18583] - Fixed PerforceSCM instatination forn Multiple SCMs
  • Loading branch information
rpetti committed Nov 24, 2013
2 parents 02d2fcf + 92e8c1d commit 4c8e35c
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 69 deletions.
102 changes: 59 additions & 43 deletions src/main/java/hudson/plugins/perforce/PerforceSCM.java
@@ -1,5 +1,6 @@
package hudson.plugins.perforce;

import hudson.plugins.perforce.config.DepotType;
import com.tek42.perforce.Depot;
import com.tek42.perforce.PerforceException;
import com.tek42.perforce.model.Changelist;
Expand All @@ -22,6 +23,9 @@
import hudson.matrix.MatrixRun;
import hudson.model.*;
import hudson.model.listeners.ItemListener;
import hudson.plugins.perforce.config.CleanTypeConfig;
import hudson.plugins.perforce.config.MaskViewConfig;
import hudson.plugins.perforce.config.WorkspaceCleanupConfig;
import hudson.plugins.perforce.utils.MacroStringHelper;
import hudson.plugins.perforce.utils.ParameterSubstitutionException;
import hudson.remoting.VirtualChannel;
Expand Down Expand Up @@ -54,6 +58,7 @@
import java.io.StringWriter;
import java.net.InetAddress;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -278,7 +283,13 @@ public class PerforceSCM extends SCM {
private String p4Charset = null;
private String p4CommandCharset = null;

// Plugin constructor, (only?) used when a job configuration is saved
/**
* SCM constructor, (only?) used when a job configuration is saved.
* This constructor uses data classes from {@link hudson.plugins.perforce.config}
* to allow proper handling of hierarchical data in Stapler. In the current
* state, these classes are not being used outside this constructor.
*/
// TODO: move data to configuration classes during the refactoring
@DataBoundConstructor
public PerforceSCM(
String p4User,
Expand Down Expand Up @@ -314,7 +325,11 @@ public PerforceSCM(
PerforceRepositoryBrowser browser,
String excludedUsers,
String excludedFiles,
boolean excludedFilesCaseSensitivity) {
boolean excludedFilesCaseSensitivity,
DepotType depotType,
WorkspaceCleanupConfig cleanWorkspace,
MaskViewConfig useViewMask
) {

this.configVersion = 1L;

Expand All @@ -341,8 +356,39 @@ public PerforceSCM(

this.p4UpstreamProject = Util.fixEmptyAndTrim(p4UpstreamProject);

this.projectPath = Util.fixEmptyAndTrim(projectPath);

//TODO: move optional entries to external classes
// Get data from the depot type
if (depotType != null) {
this.p4Stream = depotType.getP4Stream();
this.clientSpec = depotType.getClientSpec();
this.projectPath = Util.fixEmptyAndTrim(depotType.getProjectPath());
this.useStreamDepot = depotType.useP4Stream();
this.useClientSpec = depotType.useClientSpec();
this.useViewMask = depotType.useProjectPath();
}

// Get data from workspace cleanup settings
if (cleanWorkspace != null) {
setWipeRepoBeforeBuild(cleanWorkspace.isWipeRepoBeforeBuild());

CleanTypeConfig cleanType = cleanWorkspace.getCleanType();
if (cleanType != null) {
setWipeBeforeBuild(cleanType.isWipe());
setQuickCleanBeforeBuild(cleanType.isQuick());
setRestoreChangedDeletedFiles(cleanType.isRestoreChangedDeletedFiles());
}
}

// Setup view mask
if (useViewMask != null) {
setUseViewMask(true);
setViewMask(hudson.Util.fixEmptyAndTrim(useViewMask.getViewMask()));
setUseViewMaskForPolling(useViewMask.isUseViewMaskForPolling());
setUseViewMaskForSyncing(useViewMask.isUseViewMaskForSyncing());
setUseViewMaskForChangeLog(useViewMask.isUseViewMaskForChangeLog());

}

this.clientOwner = Util.fixEmptyAndTrim(clientOwner);

if (p4SysRoot != null) {
Expand Down Expand Up @@ -464,6 +510,7 @@ protected Depot getDepot(Launcher launcher, FilePath workspace, AbstractProject
return depot;
}


/**
* Override of SCM.buildEnvVars() in order to setup the last change we have
* sync'd to as a Hudson
Expand Down Expand Up @@ -1809,45 +1856,14 @@ public String getDisplayName() {

@Override
public SCM newInstance(StaplerRequest req, JSONObject formData) throws FormException {
PerforceSCM newInstance = (PerforceSCM)super.newInstance(req, formData);
String depotType = req.getParameter("p4.depotType");
boolean useStreamDepot = depotType.equals("stream");
boolean useClientSpec = depotType.equals("file");
newInstance.setUseStreamDepot(useStreamDepot);
if (useStreamDepot) {
newInstance.setP4Stream(req.getParameter("p4Stream"));
}
else {
newInstance.setUseClientSpec(useClientSpec);
if (useClientSpec) {
newInstance.setClientSpec(req.getParameter("clientSpec"));
}
else {
newInstance.setProjectPath(req.getParameter("projectPath"));
}
}
newInstance.setUseViewMask(req.getParameter("p4.useViewMask") != null);
newInstance.setViewMask(Util.fixEmptyAndTrim(req.getParameter("p4.viewMask")));
newInstance.setUseViewMaskForPolling(req.getParameter("p4.useViewMaskForPolling") != null);
newInstance.setUseViewMaskForSyncing(req.getParameter("p4.useViewMaskForSyncing") != null);
newInstance.setUseViewMaskForChangeLog(req.getParameter("p4.useViewMaskForChangeLog") != null);

String cleanType = req.getParameter("p4.cleanType");
boolean useWipe = false;
boolean useQuickClean = false;
if(cleanType != null && req.getParameter("p4.cleanWorkspace") != null){
useWipe = cleanType.equals("wipe");
useQuickClean = cleanType.equals("quick");
}
newInstance.setWipeBeforeBuild(useWipe);
newInstance.setQuickCleanBeforeBuild(useQuickClean);

String wipeRepo = req.getParameter("p4.wipeRepoBeforeBuild");
newInstance.setWipeRepoBeforeBuild(wipeRepo != null);

newInstance.setRestoreChangedDeletedFiles(req.getParameter("p4.restoreChangedDeletedFiles") != null);

return newInstance;
return (PerforceSCM)super.newInstance(req, formData);
}

/**Generates a random key for p4.config.instanceID*/
private static final AtomicLong P4_INSTANCE_COUNTER = new AtomicLong();
public String generateP4InstanceID() {
// There's no problem even if the counter reaches overflow
return Long.toString(P4_INSTANCE_COUNTER.incrementAndGet());
}

/**
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/hudson/plugins/perforce/config/CleanTypeConfig.java
@@ -0,0 +1,55 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.perforce.config;

import hudson.plugins.perforce.PerforceSCM;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* Contains workspace cleanup options for {@link PerforceSCM}.
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since TODO: define a version
*/
public class CleanTypeConfig {
String value;
boolean restoreChangedDeletedFiles;

@DataBoundConstructor
public CleanTypeConfig(String value, Boolean restoreChangedDeletedFiles) {
this.value = value;
this.restoreChangedDeletedFiles = restoreChangedDeletedFiles != null ? restoreChangedDeletedFiles.booleanValue() : false;
}

public boolean isQuick() {
return value.equals("quick");
}

public boolean isWipe() {
return value.equals("wipe");
}

public boolean isRestoreChangedDeletedFiles() {
return restoreChangedDeletedFiles;
}
}
76 changes: 76 additions & 0 deletions src/main/java/hudson/plugins/perforce/config/DepotType.java
@@ -0,0 +1,76 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.perforce.config;

import org.kohsuke.stapler.DataBoundConstructor;

/**
* Provides databound-transfer of depot type parameters for ${@link PerforceSCM}.
* Class is developed in order to resolve <a href="https://issues.jenkins-ci.org/browse/JENKINS-18583">JENKINS-18583 issue</a>
* @see PerforceSCMceSCM
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since TODO: define a version
*/
public class DepotType {
public static final String USE_P4STREAM_MARKER="stream";
public static final String USE_CLIENTSPEC_MARKER="file";
public static final String USE_PROJECTPATH_MARKER="map";

String value;
String p4Stream;
String clientSpec;
String projectPath;

@DataBoundConstructor
public DepotType(String value, String p4Stream, String clientSpec, String projectPath) {
this.value = (value != null) ? value : "";
this.p4Stream = p4Stream;
this.clientSpec = clientSpec;
this.projectPath = projectPath;
}

public String getProjectPath() {
return projectPath;
}

public boolean useProjectPath() {
return value.equals(USE_PROJECTPATH_MARKER);
}

public String getClientSpec() {
return clientSpec;
}

public boolean useClientSpec() {
return value.equals(USE_CLIENTSPEC_MARKER);
}

public String getP4Stream() {
return p4Stream;
}

public boolean useP4Stream() {
return value.equals(USE_P4STREAM_MARKER);
}
}
63 changes: 63 additions & 0 deletions src/main/java/hudson/plugins/perforce/config/MaskViewConfig.java
@@ -0,0 +1,63 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.perforce.config;

import org.kohsuke.stapler.DataBoundConstructor;

/**
* Defines masking options for {@link PerforceSCM}.
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since TODO: define a version
*/
public class MaskViewConfig {
String viewMask;
boolean useViewMaskForPolling;
boolean useViewMaskForSyncing;
boolean useViewMaskForChangeLog;

@DataBoundConstructor
public MaskViewConfig(String viewMask, boolean useViewMaskForPolling,
boolean useViewMaskForSyncing, boolean useViewMaskForChangeLog) {
this.viewMask = viewMask;
this.useViewMaskForPolling = useViewMaskForPolling;
this.useViewMaskForSyncing = useViewMaskForSyncing;
this.useViewMaskForChangeLog = useViewMaskForChangeLog;
}

public String getViewMask() {
return viewMask;
}

public boolean isUseViewMaskForPolling() {
return useViewMaskForPolling;
}

public boolean isUseViewMaskForSyncing() {
return useViewMaskForSyncing;
}

public boolean isUseViewMaskForChangeLog() {
return useViewMaskForChangeLog;
}
}

0 comments on commit 4c8e35c

Please sign in to comment.