diff --git a/core/src/main/java/hudson/org/apache/tools/ant/taskdefs/AbstractCvsTask.java b/core/src/main/java/hudson/org/apache/tools/ant/taskdefs/AbstractCvsTask.java index 1a0b5a97468e8d0ac4d435494ba8058de3bdf7dc..7e3fcea4f9396d2a7ae5bf4774d10e7f2f32db74 100644 --- a/core/src/main/java/hudson/org/apache/tools/ant/taskdefs/AbstractCvsTask.java +++ b/core/src/main/java/hudson/org/apache/tools/ant/taskdefs/AbstractCvsTask.java @@ -70,7 +70,7 @@ public abstract class AbstractCvsTask extends Task { /** * the package/module to check out. */ - private String cvsPackage; + private String[] cvsPackage; /** * the tag */ @@ -564,7 +564,7 @@ public abstract class AbstractCvsTask extends Task { * * @param p package or module to operate upon */ - public void setPackage(String p) { + public void setPackage(String... p) { this.cvsPackage = p; } @@ -573,7 +573,7 @@ public abstract class AbstractCvsTask extends Task { * * @return package/module */ - public String getPackage() { + public String[] getPackage() { return this.cvsPackage; } @@ -745,7 +745,8 @@ public abstract class AbstractCvsTask extends Task { } c.setExecutable(cvsExe); if (cvsPackage != null) { - c.createArgument().setLine(cvsPackage); + for (String s : cvsPackage) + c.createArgument().setValue(s); } if (this.compression > 0 && this.compression <= MAXIMUM_COMRESSION_LEVEL) { c.createArgument(true).setValue("-z" + this.compression); diff --git a/core/src/main/java/hudson/scm/CVSSCM.java b/core/src/main/java/hudson/scm/CVSSCM.java index bff56f08f0e8eb5f74ba6185004fc93ef0e42a79..858fea2bb93fb6c595349ccd815f7f9a3be3b67d 100644 --- a/core/src/main/java/hudson/scm/CVSSCM.java +++ b/core/src/main/java/hudson/scm/CVSSCM.java @@ -65,6 +65,7 @@ import java.util.Set; import java.util.StringTokenizer; import java.util.TimeZone; import java.util.TreeSet; +import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -91,7 +92,8 @@ public class CVSSCM extends SCM implements Serializable { * Module names. * * This could be a whitespace/NL-separated list of multiple modules. - * Modules could be either directories or files. + * Modules could be either directories or files. "\ " is used to escape + * " ", which is needed for modules with whitespace in it. */ private String module; @@ -155,7 +157,7 @@ public class CVSSCM extends SCM implements Serializable { if(flatten) return workspace; - return workspace.child(new StringTokenizer(module).nextToken()); + return workspace.child(getAllModulesNormalized()[0]); } public ChangeLogParser createChangeLogParser() { @@ -166,14 +168,13 @@ public class CVSSCM extends SCM implements Serializable { return module; } - private String getAllModulesNormalized() { - StringBuilder buf = new StringBuilder(); - StringTokenizer tokens = new StringTokenizer(module); - while(tokens.hasMoreTokens()) { - if(buf.length()>0) buf.append(' '); - buf.append(tokens.nextToken()); - } - return buf.toString(); + private String[] getAllModulesNormalized() { + // split by whitespace, except "\ " + String[] r = module.split("(? moduleNames = new TreeSet(Collections.list(new StringTokenizer(module))); + final Set moduleNames = new TreeSet(Arrays.asList(getAllModulesNormalized())); // Add in any existing CVS dirs, in case project checked out its own. moduleNames.addAll(workspace.act(new FileCallable>() { @@ -497,9 +496,8 @@ public class CVSSCM extends SCM implements Serializable { if(flatten) { return isUpdatableModule(dir); } else { - StringTokenizer tokens = new StringTokenizer(module); - while(tokens.hasMoreTokens()) { - File module = new File(dir,tokens.nextToken()); + for (String m : getAllModulesNormalized()) { + File module = new File(dir,m); if(!isUpdatableModule(module)) return false; } @@ -1227,9 +1225,7 @@ public class CVSSCM extends SCM implements Serializable { // run cvs tag command listener.getLogger().println("tagging the workspace"); - StringTokenizer tokens = new StringTokenizer(CVSSCM.this.module); - while(tokens.hasMoreTokens()) { - String m = tokens.nextToken(); + for (String m : getAllModulesNormalized()) { FilePath path = new FilePath(destdir).child(m); boolean isDir = path.isDirectory(); diff --git a/core/src/test/java/hudson/scm/SubversionSCMTest.java b/core/src/test/java/hudson/scm/SubversionSCMTest.java index 3b8d3a589080c2fc506c5f60b123e0b009759caa..ec6a1154fb65df916060387e69010d8cc3717b52 100644 --- a/core/src/test/java/hudson/scm/SubversionSCMTest.java +++ b/core/src/test/java/hudson/scm/SubversionSCMTest.java @@ -2,6 +2,8 @@ package hudson.scm; import junit.framework.TestCase; +import java.util.Arrays; + /** * @author Kohsuke Kawaguchi */ @@ -14,6 +16,15 @@ public class SubversionSCMTest extends TestCase { check("svn+ssh://foobar/"); } + public void test2() { + String[] r = "abc\\ def ghi".split("(?