Skip to content

[JENKINS-52009] Added support for timezone in cron and percent sign in parameter key/value #47

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

Merged
merged 2 commits into from
Jan 1, 2021
Merged
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 @@ -2,10 +2,10 @@

import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import antlr.ANTLRException;
import com.google.common.collect.Maps;
import hudson.scheduler.CronTab;
import hudson.scheduler.CronTabList;
import hudson.scheduler.Hash;
Expand Down Expand Up @@ -34,14 +34,19 @@ public ParameterizedCronTab(CronTab cronTab, Map<String, String> parameters) {
* Used to spread out token like "@daily". Null to preserve the legacy behaviour
* of not spreading it out at all.
*/
public static ParameterizedCronTab create(String line, int lineNumber, Hash hash) throws ANTLRException {
String[] lineParts = line.split("%");
CronTab cronTab = new CronTab(lineParts[0].trim(), lineNumber, hash);
Map<String, String> parameters = new HashMap<>();
if (lineParts.length == 2) {
parameters = new ParameterParser().parse(lineParts[1]);
public static ParameterizedCronTab create(String line, int lineNumber, Hash hash, String timezone) throws ANTLRException {
Map<String, String> parameters = Maps.newHashMap();
int firstPercentIdx = line.indexOf("%");
if(firstPercentIdx != -1) {
String cronLinePart = line.substring(0, firstPercentIdx).trim();
String paramsLinePart = line.substring(firstPercentIdx + 1).trim();
CronTab cronTab = new CronTab(cronLinePart, lineNumber, hash, timezone);
parameters = new ParameterParser().parse(paramsLinePart);
return new ParameterizedCronTab(cronTab, parameters);
} else {
CronTab cronTab = new CronTab(line, lineNumber, hash, timezone);
return new ParameterizedCronTab(cronTab, parameters);
}
return new ParameterizedCronTab(cronTab, parameters);
}

public Map<String, String> getParameterValues() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,23 @@ public static ParameterizedCronTabList create(String cronTabSpecification) throw
public static ParameterizedCronTabList create(String cronTabSpecification, Hash hash) throws ANTLRException {
List<ParameterizedCronTab> result = new ArrayList<>();
int lineNumber = 0;
String timezone = null;
for (String line : cronTabSpecification.split("\\r?\\n")) {
lineNumber++;
line = line.trim();
if (line.length() == 0 || line.startsWith("#"))
continue; // ignorable line
try {
result.add(ParameterizedCronTab.create(line, lineNumber, hash));
} catch (ANTLRException e) {
throw new ANTLRException(String.format("Invalid input: \"%s\": %s", line, e.toString()), e);
if(line.length() > 0 && !line.startsWith("#")) {
lineNumber++;
if(lineNumber == 1 && line.startsWith("TZ=")) {
timezone = CronTabList.getValidTimezone(line.replace("TZ=", ""));
if (timezone == null) {
throw new ANTLRException("Invalid or unsupported timezone '" + line + "'");
}
} else {
try {
result.add(ParameterizedCronTab.create(line, lineNumber, hash, timezone));
} catch (ANTLRException e) {
throw new ANTLRException(String.format("Invalid input: \"%s\": %s", line, e.toString()), e);
}
}
}
}
return new ParameterizedCronTabList(result);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ParameterizedTimerTrigger.DisplayName=Build periodically with parameters
ParameterizedTimerTrigger.MissingWhitespace=You appear to be missing whitespace between * and *.
ParameterizedTimerTrigger.MoreThanOnePercent=You can only use one percent sign to separate the cron from the parameters.
ParameterizedTimerTrigger.MoreThanOnePercent=First percent sign is used to separate the cron from the parameters.
ParameterizedTimerTrigger.TrailingSemicolon=I need you to remove that semicolon from the end of the line.
ParameterizedTimerTrigger.UndefinedParameter=You have tried to schedule with parameters ({0}), which are not among saved project parameters: {1}
ParameterizedTimerTrigger.EmptyParameter=You have tried to schedule with empty values for parameters ({0}), is this intentional?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
H/15 * * * * %name=value

# every ten minutes in the first half of every hour (three times, perhaps at :04, :14, :24)
H(0-29)/10 * * * * %name=value;othername=othervalue
H(0-29)/10 * * * * % name=value; othername=othervalue
# every fifteen minutes with timezone
TZ=Australia/Sydney
H/15 * * * * %name=value
# every fifteen minutes with percent sign in param key/value
H/15 * * * * %name=value;key=10%;
</pre>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,14 @@ public void checkSanity_NullParameters() throws Exception {
testObject.checkSanity("* * * * *%name=value", null));
}

@Test
public void test_paramValue_with_percent() {
ParameterParser testObject = new ParameterParser();

HashMap<String, String> expected = new HashMap<String, String>();
expected.put("name", "value");
expected.put("percent", "10%");
assertEquals(expected, testObject.parse("name=value;percent=10%"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

import com.google.common.collect.Maps;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
Expand Down Expand Up @@ -102,4 +102,16 @@ public void checkSanity_Delegates_ReturnsSame() {
assertSame(sanityValue, testObject.checkSanity());
}

@Test
public void create_with_timezone() throws Exception {
ParameterizedCronTabList testObject = ParameterizedCronTabList.create("TZ=Australia/Sydney \n * * * * *%foo=bar");
assertTrue(testObject.checkSanity(), testObject.checkSanity().startsWith("Do you really mean \"every minute\""));
ParameterizedCronTab actualCronTab = testObject.check(new GregorianCalendar());
assertTrue(actualCronTab != null);

Map<String, String> expected = Maps.newHashMap();
expected.put("foo", "bar");
assertEquals(expected, actualCronTab.getParameterValues());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import java.util.Locale;
import java.util.Map;

import hudson.scheduler.Hash;

import com.google.common.collect.Maps;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

Expand Down Expand Up @@ -38,4 +41,30 @@ public void ctor_happyPath() throws Exception {
assertTrue(testObject.checkSanity().startsWith("Do you really mean"));
}

@Test
public void param_value_with_percent_sign() throws Exception {
String cron = "* * * * *";
String params = "one=onevalue;two=10%";
String line = cron +" %" + params;
Map<String, String> parameters = Maps.newHashMap();
parameters.put("one", "onevalue");
parameters.put("two", "10%");
CronTab testCronTab = new CronTab("* * * * *");
ParameterizedCronTab testObject = new ParameterizedCronTab(testCronTab, parameters);

ParameterizedCronTab parameterizedCronTab = ParameterizedCronTab.create(line, 1, Hash.from(line), null);
assertEquals(parameters, parameterizedCronTab.getParameterValues());

}

@Test
public void with_no_params_separator() throws Exception {
String line = "* * * * *";
Map<String, String> parameters = Maps.newHashMap();
CronTab testCronTab = new CronTab("* * * * *");
ParameterizedCronTab testObject = new ParameterizedCronTab(testCronTab, parameters);
ParameterizedCronTab parameterizedCronTab = ParameterizedCronTab.create(line, 1, Hash.from(line), null);
assertEquals(parameters, parameterizedCronTab.getParameterValues());
}

}