Skip to content
Permalink
Browse files

Fix JENKINS-18014

Changed the way that macros are escaped to using something similar to Groovy with two $'s. This required actually looking for the items that matched with two $'s and then handling that case special.
  • Loading branch information
slide committed Jun 23, 2013
1 parent b29b7ff commit e1523eca5fb78fad1112193829ee4782620d9ce5
@@ -164,26 +164,31 @@ public static String expand(AbstractBuild<?,?> context, TaskListener listener, S
}

while (tokenizer.find()) {
String tokenName = tokenizer.getTokenName();
ListMultimap<String,String> args = tokenizer.getArgs();
Map<String,String> map = new HashMap<String, String>();
for (Entry<String, String> e : args.entries()) {
map.put(e.getKey(),e.getValue());
}

String replacement = null;
for (TokenMacro tm : all) {
if (tm.acceptsMacroName(tokenName)) {
replacement = tm.evaluate(context,listener,tokenName,map,args);
if(tm.hasNestedContent()) {
replacement = expand(context,listener,replacement,throwException,privateTokens);
if(tokenizer.isEscaped()) {
replacement = tokenizer.group().substring(1);
} else {
String tokenName = tokenizer.getTokenName();
ListMultimap<String,String> args = tokenizer.getArgs();
Map<String,String> map = new HashMap<String, String>();
for (Entry<String, String> e : args.entries()) {
map.put(e.getKey(),e.getValue());
}

for (TokenMacro tm : all) {
if (tm.acceptsMacroName(tokenName)) {
replacement = tm.evaluate(context,listener,tokenName,map,args);
if(tm.hasNestedContent()) {
replacement = expand(context,listener,replacement,throwException,privateTokens);
}
break;
}
break;
}

if (replacement == null && throwException)
throw new MacroEvaluationException(String.format("Unrecognized macro '%s' in '%s'", tokenName, stringWithMacro));
}
if (replacement==null&&throwException)
throw new MacroEvaluationException(String.format("Unrecognized macro '%s' in '%s'", tokenName, stringWithMacro));
else if(replacement==null) // just put the token back in since we don't want to throw the exception
if (replacement == null && !throwException) // just put the token back in since we don't want to throw the exception
tokenizer.appendReplacement(sb, tokenizer.group());
else
tokenizer.appendReplacement(sb, replacement);
@@ -62,16 +62,18 @@

private static final String delimitedTokenRegex = "\\{" + spaceRegex + "(" + tokenNameRegex + ")" + argsRegex + spaceRegex + "\\}";

private static final String tokenRegex = "(?<!\\\\)\\$((" + tokenNameRegex + ")|(" + delimitedTokenRegex + "))";
private static final String tokenRegex = "(\\$?)\\$((" + tokenNameRegex + ")|(" + delimitedTokenRegex + "))";

private static final Pattern argPattern = Pattern.compile(argRegex);

private static final Pattern tokenPattern = Pattern.compile(tokenRegex);

private static final String ESCAPE_STRING = "$$";

private final Matcher tokenMatcher;

private String tokenName = null;

private ListMultimap<String,String> args = null;

Tokenizer(String origText) {
@@ -89,20 +91,28 @@ String getTokenName() {
String group() {
return tokenMatcher.group();
}

boolean isEscaped() {
return tokenMatcher.group().startsWith(ESCAPE_STRING);
}

boolean find() {
if (tokenMatcher.find()) {
tokenName = tokenMatcher.group(2);
if (tokenMatcher.find()) {
if(isEscaped()) {
return true;
}

tokenName = tokenMatcher.group(3);
if (tokenName == null) {
tokenName = tokenMatcher.group(4);
tokenName = tokenMatcher.group(5);
}
args = Multimaps.newListMultimap(new TreeMap<String, Collection<String>>(),new Supplier<List<String>>() {
public List<String> get() {
return new ArrayList<String>();
}
});
if (tokenMatcher.group(5) != null) {
parseArgs(tokenMatcher.group(5), args);
if (tokenMatcher.group(6) != null) {
parseArgs(tokenMatcher.group(6), args);
}
return true;
} else {
@@ -70,12 +70,12 @@ public void testEscaped() throws Exception {
FreeStyleBuild b = p.scheduleBuild2(0).get();

listener = new StreamTaskListener(System.out);
assertEquals("\\${TEST_NESTED}",TokenMacro.expand(b,listener,"\\${TEST_NESTED}"));
assertEquals("\\$TEST_NESTED",TokenMacro.expand(b,listener,"\\$TEST_NESTED"));
assertEquals("\\$TEST_NESTED{abc=[def, ghi], jkl=[true]}",TokenMacro.expand(b,listener,"\\$TEST_NESTED$TEST_NESTED"));
assertEquals("\\${TEST_NESTED}{abc=[def, ghi], jkl=[true]}",TokenMacro.expand(b,listener,"\\${TEST_NESTED}$TEST_NESTED"));
assertEquals("{abc=[def, ghi], jkl=[true]}\\$TEST_NESTED",TokenMacro.expand(b,listener,"$TEST_NESTED\\$TEST_NESTED"));
assertEquals("{abc=[def, ghi], jkl=[true]}\\${TEST_NESTED}",TokenMacro.expand(b,listener,"$TEST_NESTED\\${TEST_NESTED}"));
assertEquals("${TEST_NESTED}",TokenMacro.expand(b,listener,"$${TEST_NESTED}"));
assertEquals("$TEST_NESTED",TokenMacro.expand(b,listener,"$$TEST_NESTED"));
assertEquals("$TEST_NESTED{abc=[def, ghi], jkl=[true]}",TokenMacro.expand(b,listener,"$$TEST_NESTED$TEST_NESTED"));
assertEquals("${TEST_NESTED}{abc=[def, ghi], jkl=[true]}",TokenMacro.expand(b,listener,"$${TEST_NESTED}$TEST_NESTED"));
assertEquals("{abc=[def, ghi], jkl=[true]}$TEST_NESTED",TokenMacro.expand(b,listener,"$TEST_NESTED$$TEST_NESTED"));
assertEquals("{abc=[def, ghi], jkl=[true]}${TEST_NESTED}",TokenMacro.expand(b,listener,"$TEST_NESTED$${TEST_NESTED}"));
}

public void testPrivate() throws Exception {

0 comments on commit e1523ec

Please sign in to comment.
You can’t perform that action at this time.