提交 69fe8f30 编写于 作者: J Jesse Glick

Merge branch 'master' of github.com:jenkinsci/jenkins

......@@ -55,6 +55,8 @@ import hudson.util.ArgumentListBuilder;
import hudson.util.NullStream;
import hudson.util.StreamTaskListener;
import hudson.util.VariableResolver;
import hudson.util.VariableResolver.ByMap;
import hudson.util.VariableResolver.Union;
import hudson.util.FormValidation;
import hudson.util.XStream2;
import net.sf.json.JSONObject;
......@@ -264,7 +266,6 @@ public class Maven extends Builder {
String targets = Util.replaceMacro(this.targets,vr);
targets = env.expand(targets);
String pom = env.expand(this.pom);
String properties = env.expand(this.properties);
int startIndex = 0;
int endIndex;
......@@ -314,7 +315,8 @@ public class Maven extends Builder {
Set<String> sensitiveVars = build.getSensitiveBuildVariables();
args.addKeyValuePairs("-D",build.getBuildVariables(),sensitiveVars);
args.addKeyValuePairsFromPropertyString("-D",properties,vr,sensitiveVars);
final VariableResolver<String> resolver = new Union<String>(new ByMap<String>(env), vr);
args.addKeyValuePairsFromPropertyString("-D",this.properties,resolver,sensitiveVars);
if (usesPrivateRepository())
args.add("-Dmaven.repo.local=" + build.getWorkspace().child(".repository"));
args.addTokenized(normalizedTarget);
......
......@@ -192,16 +192,11 @@ public class ArgumentListBuilder implements Serializable, Cloneable {
* The persisted form of {@link Properties}. For example, "abc=def\nghi=jkl". Can be null, in which
* case this method becomes no-op.
* @param vr
* {@link VariableResolver} to be performed on the values.
* {@link VariableResolver} to resolve variables in properties string.
* @since 1.262
*/
public ArgumentListBuilder addKeyValuePairsFromPropertyString(String prefix, String properties, VariableResolver vr) throws IOException {
if(properties==null) return this;
for (Entry<Object,Object> entry : Util.loadProperties(properties).entrySet()) {
addKeyValuePair(prefix, (String)entry.getKey(), Util.replaceMacro(entry.getValue().toString(),vr), false);
}
return this;
public ArgumentListBuilder addKeyValuePairsFromPropertyString(String prefix, String properties, VariableResolver<String> vr) throws IOException {
return addKeyValuePairsFromPropertyString(prefix, properties, vr, null);
}
/**
......@@ -213,21 +208,47 @@ public class ArgumentListBuilder implements Serializable, Cloneable {
* The persisted form of {@link Properties}. For example, "abc=def\nghi=jkl". Can be null, in which
* case this method becomes no-op.
* @param vr
* {@link VariableResolver} to be performed on the values.
* {@link VariableResolver} to resolve variables in properties string.
* @param propsToMask
* Set containing key names to mark as masked in the argument list. Key
* names that do not exist in the set will be added unmasked.
* @since 1.378
*/
public ArgumentListBuilder addKeyValuePairsFromPropertyString(String prefix, String properties, VariableResolver vr, Set<String> propsToMask) throws IOException {
public ArgumentListBuilder addKeyValuePairsFromPropertyString(String prefix, String properties, VariableResolver<String> vr, Set<String> propsToMask) throws IOException {
if(properties==null) return this;
properties = Util.replaceMacro(properties, propertiesGeneratingResolver(vr));
for (Entry<Object,Object> entry : Util.loadProperties(properties).entrySet()) {
addKeyValuePair(prefix, (String)entry.getKey(), Util.replaceMacro(entry.getValue().toString(),vr), (propsToMask == null) ? false : propsToMask.contains((String)entry.getKey()));
addKeyValuePair(prefix, (String)entry.getKey(), entry.getValue().toString(), (propsToMask == null) ? false : propsToMask.contains(entry.getKey()));
}
return this;
}
/**
* Creates a resolver generating values to be safely placed in properties string.
*
* {@link Properties#load} generally removes single backslashes from input and that
* is not desirable for outcomes of macro substitution as the values can
* contain them but user has no way to escape them.
*
* @param original Resolution will be delegated to this resolver. Resolved
* values will be escaped afterwards.
* @see https://issues.jenkins-ci.org/browse/JENKINS-10539
*/
private static VariableResolver<String> propertiesGeneratingResolver(final VariableResolver<String> original) {
return new VariableResolver<String>() {
public String resolve(String name) {
final String value = original.resolve(name);
if (value == null) return null;
// Substitute one backslash with two
return value.replaceAll("\\\\", "\\\\\\\\");
}
};
}
public String[] toCommandArray() {
return args.toArray(new String[args.size()]);
}
......
......@@ -23,6 +23,9 @@
*/
package hudson.util;
import static org.hamcrest.CoreMatchers.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
......@@ -183,4 +186,45 @@ public class ArgumentListBuilderTest extends Assert {
assertNotNull("The mask array should not be null", array);
assertArrayEquals("The mask array was incorrect", new boolean[]{false,false,false}, array);
}
@Test
public void addKeyValuePairsFromPropertyString() throws IOException {
final Map<String, String> map = new HashMap<String, String>();
map.put("PATH", "C:\\Windows");
final VariableResolver<String> resolver = new VariableResolver.ByMap<String>(map);
final String properties = "my.path=$PATH";
ArgumentListBuilder builder = new ArgumentListBuilder();
builder.addKeyValuePairsFromPropertyString("", properties, resolver);
assertEquals("my.path=C:\\Windows", builder.toString());
builder = new ArgumentListBuilder();
builder.addKeyValuePairsFromPropertyString("", properties, resolver, null);
assertEquals("my.path=C:\\Windows", builder.toString());
}
@Test
public void numberOfBackslashesInPropertiesShouldBePreservedAfterMacroExpansion() throws IOException {
final Map<String, String> map = new HashMap<String, String>();
map.put("ONE", "one\\backslash");
map.put("TWO", "two\\\\backslashes");
map.put("FOUR", "four\\\\\\\\backslashes");
final String properties = new StringBuilder()
.append("one=$ONE\n")
.append("two=$TWO\n")
.append("four=$FOUR\n")
.toString()
;
final String args = new ArgumentListBuilder()
.addKeyValuePairsFromPropertyString("", properties, new VariableResolver.ByMap<String>(map))
.toString()
;
assertThat(args, containsString("one=one\\backslash"));
assertThat(args, containsString("two=two\\\\backslashes"));
assertThat(args, containsString("four=four\\\\\\\\backslashes"));
}
}
......@@ -206,6 +206,34 @@ public class MavenTest {
assertFalse(buildLog.contains("-Dpassword=12345"));
}
@Test
public void parametersReferencedFromPropertiesShouldRetainBackslashes() throws Exception {
final String properties = "global.path=$GLOBAL_PATH\nmy.path=$PATH\\\\Dir";
final StringParameterDefinition parameter = new StringParameterDefinition("PATH", "C:\\Windows");
final Entry envVar = new Entry("GLOBAL_PATH", "D:\\Jenkins");
FreeStyleProject project = j.createFreeStyleProject();
project.getBuildersList().add(new Maven("--help",null,null,properties,null));
project.addProperty(new ParametersDefinitionProperty(parameter));
j.jenkins.getNodeProperties().replaceBy(Collections.singleton(
new EnvironmentVariablesNodeProperty(envVar)
));
FreeStyleBuild build = project.scheduleBuild2(0).get();
@SuppressWarnings("deprecation")
String buildLog = build.getLog();
assertNotNull(buildLog);
assertTrue(
"Parameter my.path should preserve backslashes in:\n" + buildLog,
buildLog.contains("-Dmy.path=C:\\Windows\\Dir")
);
assertTrue(
"Parameter global.path should preserve backslashes in:\n" + buildLog,
buildLog.contains("-Dglobal.path=D:\\Jenkins")
);
}
@Test public void defaultSettingsProvider() throws Exception {
{
FreeStyleProject p = j.createFreeStyleProject();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册