提交 b2c28f12 编写于 作者: S stephenconnolly

Issue number 912:

Not so bad to implement as SCM is an abstract class.
In SCM and AbstractProject, provided a default getModuleRoots that just returns getModuleRoot wrapped in an array.
In CVSSCM and SubversionSCM, override getModuleRoots to return multiple roots when appropriate.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@5296 71c3de6d-444a-0410-be80-ed276b4c234a
上级 63d10328
......@@ -206,6 +206,17 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
return getScm().getModuleRoot(getWorkspace());
}
/**
* Returns the root directories of all checked-out modules.
* <p>
* Some SCMs support checking out multiple modules into the same workspace.
* In these cases, the returned array will have a length greater than one.
* @return The roots of all modules checked out from the SCM.
*/
public FilePath[] getModuleRoots() {
return getScm().getModuleRoots(getWorkspace());
}
public int getQuietPeriod() {
return quietPeriod!=null ? quietPeriod : Hudson.getInstance().getQuietPeriod();
}
......
......@@ -159,6 +159,18 @@ public class CVSSCM extends SCM implements Serializable {
return workspace.child(getAllModulesNormalized()[0]);
}
public FilePath[] getModuleRoots(FilePath workspace) {
if (!flatten) {
final String[] moduleLocations = getAllModulesNormalized();
FilePath[] moduleRoots = new FilePath[moduleLocations.length];
for (int i = 0; i < moduleLocations.length; i++) {
moduleRoots[i] = workspace.child(moduleLocations[i]);
}
return moduleRoots;
}
return new FilePath[]{getModuleRoot(workspace)};
}
public ChangeLogParser createChangeLogParser() {
return new CVSChangeLogParser();
}
......@@ -222,7 +234,7 @@ public class CVSSCM extends SCM implements Serializable {
// archive the workspace to support later tagging
File archiveFile = getArchiveFile(build);
final OutputStream os = new RemoteOutputStream(new FileOutputStream(archiveFile));
ws.act(new FileCallable<Void>() {
public Void invoke(File ws, VirtualChannel channel) throws IOException {
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(os));
......@@ -950,7 +962,7 @@ public class CVSSCM extends SCM implements Serializable {
// check .cvspass file to see if it has entry.
// CVS handles authentication only if it's pserver.
if(v.startsWith(":pserver")) {
if(m.group(2)==null) {// if password is not specified in CVSROOT
if(m.group(2)==null) {// if password is not specified in CVSROOT
String cvspass = getCvspassFile();
File passfile;
if(cvspass.equals("")) {
......
......@@ -57,7 +57,7 @@ public abstract class SCM implements Describable<SCM>, ExtensionPoint {
*
* <p>
* This method attempts to find applicable browser
* from other job configurations.
* from other job configurations.
*/
public final RepositoryBrowser getEffectiveBrowser() {
RepositoryBrowser b = getBrowser();
......@@ -182,7 +182,7 @@ public abstract class SCM implements Describable<SCM>, ExtensionPoint {
* <p>
* If this SCM is configured to create a directory, try to
* return that directory so that builders can work seamlessly.
*
*
* <p>
* If SCM doesn't need to create any directory inside workspace,
* or in any other tricky cases, it should revert to the default
......@@ -195,6 +195,37 @@ public abstract class SCM implements Describable<SCM>, ExtensionPoint {
return workspace;
}
/**
* Gets the top directories of all the checked out modules.
*
* <p>
* Some SCMs support checking out multiple modules inside a workspace, which
* creates directory layout like this:
*
* <pre>
* workspace <- workspace root
* +- xyz <- directory checked out by SCM
* +- .svn
* +- build.xml <- user file
* +- abc <- second module from different SCM root
* +- .svn
* +- build.xml <- user file
* </pre>
*
* This method takes the workspace root as a parameter, and is expected to return
* all the module roots that were checked out from SCM.
*
* <p>
* For normal SCMs, the array will be of length <code>1</code> and it's contents
* will be identical to calling {@link getModuleRoot(FilePath)}.
*
* @param workspace The workspace root directory
* @return An array of all module roots.
*/
public FilePath[] getModuleRoots(FilePath workspace) {
return new FilePath[] { getModuleRoot(workspace), };
}
/**
* The returned object will be used to parse <tt>changelog.xml</tt>.
*/
......
......@@ -329,7 +329,7 @@ public class SubversionSCM extends SCM implements Serializable {
* <p>
* Use canonical path to avoid SVNKit/symlink problem as described in
* https://wiki.svnkit.com/SVNKit_FAQ
*
*
* @return null
* if the operation failed. Otherwise the set of local workspace paths
* (relative to the workspace root) that has loaded due to svn:external.
......@@ -667,6 +667,18 @@ public class SubversionSCM extends SCM implements Serializable {
return workspace;
}
public FilePath[] getModuleRoots(FilePath workspace) {
final ModuleLocation[] moduleLocations = getLocations();
if (moduleLocations.length > 0) {
FilePath[] moduleRoots = new FilePath[moduleLocations.length];
for (int i = 0; i < moduleLocations.length; i++) {
moduleRoots[i] = workspace.child(moduleLocations[i].local);
}
return moduleRoots;
}
return new FilePath[] { getModuleRoot(workspace) };
}
private static String getLastPathComponent(String s) {
String[] tokens = s.split("/");
return tokens[tokens.length-1]; // return the last token
......@@ -1034,16 +1046,16 @@ public class SubversionSCM extends SCM implements Serializable {
// found a matching path
List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>();
repository.getDir(p,rev,false,entries);
// build up the name list
List<String> paths = new ArrayList<String>();
for (SVNDirEntry e : entries)
if(e.getKind()==SVNNodeKind.DIR)
paths.add(e.getName());
String head = SVNPathUtil.head(repoPath.substring(p.length() + 1));
String candidate = EditDistance.findNearest(head,paths);
error("'%1$s/%2$s' doesn't exist in the repository. Maybe you meant '%1$s/%3$s'?",
p, head, candidate);
return;
......@@ -1079,11 +1091,11 @@ public class SubversionSCM extends SCM implements Serializable {
public SVNNodeKind checkRepositoryPath(SVNURL repoURL) throws SVNException {
SVNRepository repository = null;
try {
repository = getRepository(repoURL);
repository.testConnection();
long rev = repository.getLatestRevision();
String repoPath = getRelativePath(repoURL, repository);
return repository.checkPath(repoPath, rev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册