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

Added support for multiple SVN Modules. #31

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Future;

/**
Expand Down Expand Up @@ -90,7 +91,7 @@ public synchronized void doPerform(StaplerRequest req, StaplerResponse rsp) thro
* <p>
* This requires that the calling thread owns the workspace.
*/
/*package*/ abstract long perform(TaskListener listener, P param) throws IOException, InterruptedException;
/*package*/ abstract List<Long> perform(TaskListener listener, P param) throws IOException, InterruptedException;

/**
* Which page to render in the top page?
Expand Down
438 changes: 249 additions & 189 deletions src/main/java/jenkins/plugins/svnmerge/FeatureBranchProperty.java

Large diffs are not rendered by default.

240 changes: 127 additions & 113 deletions src/main/java/jenkins/plugins/svnmerge/IntegratableProjectAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,24 +94,28 @@ public List<AbstractProject<?,?>> getBranches() {
*
* @return
*/
public RepositoryLayoutInfo getRepositoryLayout() {
public ArrayList<RepositoryLayoutInfo> getRepositoryLayout() {
ArrayList<RepositoryLayoutInfo> toReturn = new ArrayList<RepositoryLayoutInfo>();
SCM scm = project.getScm();
if (!(scm instanceof SubversionSCM)) {
return null;
}
//TODO: check for multiple locations ?

SubversionSCM svn = (SubversionSCM) scm;
ModuleLocation firstLocation = svn.getLocations()[0];
// expand system and node environment variables as well as the project parameters
firstLocation = Utility.getExpandedLocation(firstLocation, project);
return getRepositoryLayout(firstLocation);
for(ModuleLocation ml : svn.getLocations()){
// expand system and node environment variables as well as the project parameters
ml = Utility.getExpandedLocation(ml, project);
toReturn.add(getRepositoryLayout(ml));
}

return toReturn;
}

private RepositoryLayoutInfo getRepositoryLayout(ModuleLocation location) {
return new RepositoryLayoutInfo(location.getURL());
}

@RequirePOST
@RequirePOST
public void doNewBranch(StaplerRequest req, StaplerResponse rsp,
@QueryParameter String name,
@QueryParameter boolean attach,
Expand Down Expand Up @@ -139,123 +143,133 @@ public void doNewBranch(StaplerRequest req, StaplerResponse rsp,
sendError("This project doesn't use Subversion as SCM");
return;
}
// TODO: check for multiple locations

SubversionSCM svn = (SubversionSCM) scm;
ModuleLocation firstLocation = svn.getLocations()[0];
// expand system and node environment variables as well as the project parameters
firstLocation = Utility.getExpandedLocation(firstLocation, project);

RepositoryLayoutInfo layoutInfo = getRepositoryLayout(firstLocation);

branchLocation = Util.fixEmptyAndTrim(branchLocation);
tagLocation = Util.fixEmptyAndTrim(tagLocation);

if (layoutInfo.getLayout() == RepositoryLayoutEnum.CUSTOM) {
//Create list with all new locations. This will be later copied to the new job
List<ModuleLocation> locationsToCopy = new ArrayList<ModuleLocation>();

for(ModuleLocation currentLocation : svn.getLocations()){
// expand system and node environment variables as well as the project parameters
currentLocation = Utility.getExpandedLocation(currentLocation, project);

RepositoryLayoutInfo layoutInfo = getRepositoryLayout(currentLocation);

branchLocation = Util.fixEmptyAndTrim(branchLocation);
tagLocation = Util.fixEmptyAndTrim(tagLocation);

if (layoutInfo.getLayout() == RepositoryLayoutEnum.CUSTOM) {
/*
* in case of custom layout the user must provide the full new branch url
* (and optionally the full new tag url)
*/
if (StringUtils.isEmpty(branchLocation)) {
sendError("Branch Location is required for custom repository layout");
}
if (!attach && createTag && StringUtils.isEmpty(tagLocation)) {
sendError("Tag Location is required for custom repository layout");
}
}

String branchUrl;
if (StringUtils.isNotEmpty(branchLocation)) {
//using override value
branchUrl = branchLocation;
} else {
//using default value
branchUrl = layoutInfo.getDefaultNewBranchUrl().replace("<new_branch_name>", name);
}

if (!attach) {
SvnClientManager svnMgr = SubversionSCM.createClientManager(
svn.createAuthenticationProvider(project, firstLocation));

List<String> urlsToCopyTo = new ArrayList<String>();
SVNURL svnUrl = null;
try {
svnUrl = SVNURL.parseURIEncoded(branchUrl);
SVNInfo info = svnMgr.getWCClient().doInfo(svnUrl, SVNRevision.HEAD, SVNRevision.HEAD);
if(info.getKind()== SVNNodeKind.DIR) {
// ask the user if we should attach
req.getView(this,"_attach.jelly").forward(req,rsp);
return;
} else {
sendError(info.getURL()+" already exists.");
return;
}
} catch (SVNException e) {
// path doesn't exist, the new branch can be created
}
urlsToCopyTo.add(branchUrl);

String tagUrl = null;
if (createTag) {
//can be true only when not attaching
if (StringUtils.isNotEmpty(tagLocation)) {
//using override value
tagUrl = tagLocation;
} else {
//using default value
tagUrl = layoutInfo.getDefaultNewDevTagUrl().replace("<new_branch_name>", name);
}
try {
svnUrl = SVNURL.parseURIEncoded(tagUrl);
SVNInfo info = svnMgr.getWCClient().doInfo(svnUrl, SVNRevision.HEAD, SVNRevision.HEAD);
sendError(info.getURL()+" already exists.");
return;
} catch (SVNException e) {
// path doesn't exist, the new tag can be created
}
urlsToCopyTo.add(tagUrl);
}

if (!createSVNCopy(svnMgr, firstLocation, urlsToCopyTo, commitMessage, req, rsp)) {
return;
if (StringUtils.isEmpty(branchLocation)) {
sendError("Branch Location is required for custom repository layout");
}
if (!attach && createTag && StringUtils.isEmpty(tagLocation)) {
sendError("Tag Location is required for custom repository layout");
}
}
}

// if the request wasn't forwarded
// copy a job, and adjust its properties for integration
AbstractProject<?,?> copy = Jenkins.getInstance().copy(project, project.getName() + "-" + name.replaceAll("/", "-"));
BulkChange bc = new BulkChange(copy);

try {
String branchUrl;
if (StringUtils.isNotEmpty(branchLocation)) {
//using override value
branchUrl = branchLocation;
} else {
//using default value
branchUrl = layoutInfo.getDefaultNewBranchUrl().replace("<new_branch_name>", name);
}

if (!attach) {
SvnClientManager svnMgr = SubversionSCM.createClientManager(
svn.createAuthenticationProvider(project, currentLocation));

List<String> urlsToCopyTo = new ArrayList<String>();
SVNURL svnUrl = null;
try {
svnUrl = SVNURL.parseURIEncoded(branchUrl);
SVNInfo info = svnMgr.getWCClient().doInfo(svnUrl, SVNRevision.HEAD, SVNRevision.HEAD);
if(info.getKind()== SVNNodeKind.DIR) {
// ask the user if we should attach
req.getView(this,"_attach.jelly").forward(req,rsp);
return;
} else {
sendError(info.getURL()+" already exists.");
return;
}
} catch (SVNException e) {
// path doesn't exist, the new branch can be created
}
urlsToCopyTo.add(branchUrl);

String tagUrl = null;
if (createTag) {
//can be true only when not attaching
if (StringUtils.isNotEmpty(tagLocation)) {
//using override value
tagUrl = tagLocation;
} else {
//using default value
tagUrl = layoutInfo.getDefaultNewDevTagUrl().replace("<new_branch_name>", name);
}
try {
svnUrl = SVNURL.parseURIEncoded(tagUrl);
SVNInfo info = svnMgr.getWCClient().doInfo(svnUrl, SVNRevision.HEAD, SVNRevision.HEAD);
sendError(info.getURL()+" already exists.");
return;
} catch (SVNException e) {
// path doesn't exist, the new tag can be created
}
urlsToCopyTo.add(tagUrl);
}

if (!createSVNCopy(svnMgr, currentLocation, urlsToCopyTo, commitMessage, req, rsp)) {
return;
}
}
//Add new location, we will copy in new job's Subversion
locationsToCopy.add(currentLocation.withRemote(branchUrl));
}

// if the request wasn't forwarded
// copy a job, and adjust its properties for integration
AbstractProject<?,?> copy = Jenkins.getInstance().copy(project, project.getName() + "-" + name.replaceAll("/", "-"));
BulkChange bc = new BulkChange(copy);

// moving the copy to its parent location
moveProjectToItsUpstreamProjectLocation(copy, project);
// the copy doesn't born accepting integration from subversion feature branches..
copy.removeProperty(IntegratableProject.class);
try {

// moving the copy to its parent location
moveProjectToItsUpstreamProjectLocation(copy, project);
// the copy doesn't born accepting integration from subversion feature branches..
copy.removeProperty(IntegratableProject.class);
// ... and it's a feature branch of its upstream project (which can
// be located anywhere in the tree, that's why we are pointing
// to its full name)
((AbstractProject)copy).addProperty(new FeatureBranchProperty(project.getFullName())); // pointless cast for working around javac bug as of JDK1.6.0_02
// update the SCM config to point to the branch
SubversionSCM svnScm = (SubversionSCM)copy.getScm();
copy.setScm(
new SubversionSCM(
Arrays.asList(firstLocation.withRemote(branchUrl)),
svnScm.getWorkspaceUpdater(),
svnScm.getBrowser(),
svnScm.getExcludedRegions(),
svnScm.getExcludedUsers(),
svnScm.getExcludedRevprop(),
svnScm.getExcludedCommitMessages(),
svnScm.getIncludedRegions(),
svnScm.isIgnoreDirPropChanges(),
svnScm.isFilterChangelog(),
svnScm.getAdditionalCredentials()
));
} finally {
bc.commit();
}

rsp.sendRedirect2(req.getContextPath()+"/"+copy.getUrl());
((AbstractProject)copy).addProperty(new FeatureBranchProperty(project.getFullName())); // pointless cast for working around javac bug as of JDK1.6.0_02
// update the SCM config to point to the branch
SubversionSCM svnScm = (SubversionSCM)copy.getScm();


copy.setScm(
new SubversionSCM(
locationsToCopy,
svnScm.getWorkspaceUpdater(),
svnScm.getBrowser(),
svnScm.getExcludedRegions(),
svnScm.getExcludedUsers(),
svnScm.getExcludedRevprop(),
svnScm.getExcludedCommitMessages(),
svnScm.getIncludedRegions(),
svnScm.isIgnoreDirPropChanges(),
svnScm.isFilterChangelog(),
svnScm.getAdditionalCredentials()
));
} finally {
bc.commit();
}

rsp.sendRedirect2(req.getContextPath()+"/"+copy.getUrl());

}

/**
Expand Down Expand Up @@ -293,7 +307,7 @@ private <I extends AbstractItem & TopLevelItem> void moveProjectToItsUpstreamPro
/**
* Utility method for SVN copies creation.
* First checks if all the given urls already exist; if any exist, creates a copy for each of them.
* @param scm the project scm
* @param svnMgr the project scm
* @param urlsToCopyTo a list of urls to copy to (i.e. where the copies'll be created).
* @param commitMessage the commit message to use
* @param req the original StaplerRequest
Expand Down
Loading