From 65b1c33083faf2ba1aeaa2c5a164e3ed30752c97 Mon Sep 17 00:00:00 2001 From: shankar Date: Sat, 2 Nov 2019 23:05:01 +1100 Subject: [PATCH] Added support for timezone in cron and percent sign in parameter key/value --- .../ParameterizedCronTab.java | 17 +++++++----- .../ParameterizedCronTabList.java | 22 ++++++++++----- .../Messages.properties | 2 +- .../help-parameterizedSpecification.html | 5 ++++ .../ParameterParserTest.java | 10 +++++++ .../ParameterizedCronTabListTest.java | 12 +++++++++ .../ParameterizedCronTabTest.java | 27 +++++++++++++++++++ 7 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTab.java b/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTab.java index a310360..dc2dacd 100644 --- a/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTab.java +++ b/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTab.java @@ -35,14 +35,19 @@ public ParameterizedCronTab(CronTab cronTab, Map 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); + public static ParameterizedCronTab create(String line, int lineNumber, Hash hash, String timezone) throws ANTLRException { Map parameters = Maps.newHashMap(); - if (lineParts.length == 2) { - parameters = new ParameterParser().parse(lineParts[1]); + 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 getParameterValues() { diff --git a/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabList.java b/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabList.java index 5c5b7bd..f544617 100644 --- a/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabList.java +++ b/src/main/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabList.java @@ -31,15 +31,23 @@ public static ParameterizedCronTabList create(String cronTabSpecification) throw public static ParameterizedCronTabList create(String cronTabSpecification, Hash hash) throws ANTLRException { List 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); diff --git a/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/Messages.properties b/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/Messages.properties index a47c99b..e0dfbce 100644 --- a/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/Messages.properties +++ b/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/Messages.properties @@ -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.TimerTriggerCause.ShortDescription=Started by timer with parameters: {0} diff --git a/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedTimerTrigger/help-parameterizedSpecification.html b/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedTimerTrigger/help-parameterizedSpecification.html index 3aec6db..25178da 100644 --- a/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedTimerTrigger/help-parameterizedSpecification.html +++ b/src/main/resources/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedTimerTrigger/help-parameterizedSpecification.html @@ -29,5 +29,10 @@ 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 +# 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%; diff --git a/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterParserTest.java b/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterParserTest.java index 3be7c38..cbe0779 100644 --- a/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterParserTest.java +++ b/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterParserTest.java @@ -148,4 +148,14 @@ public void checkSanity_UnmatchedEquals() throws Exception { testObject.checkSanity("* * * * *%name=value;name2=", mockParametersDefinitionProperty); } + @Test + public void test_paramValue_with_percent() { + ParameterParser testObject = new ParameterParser(); + + HashMap expected = new HashMap(); + expected.put("name", "value"); + expected.put("percent", "10%"); + assertEquals(expected, testObject.parse("name=value;percent=10%")); + } + } diff --git a/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabListTest.java b/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabListTest.java index f3421f4..605f54a 100644 --- a/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabListTest.java +++ b/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabListTest.java @@ -107,4 +107,16 @@ public void checkSanity_Delegates_ReturnsSame() { } + @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 expected = Maps.newHashMap(); + expected.put("foo", "bar"); + assertEquals(expected, actualCronTab.getParameterValues()); + } + } diff --git a/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabTest.java b/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabTest.java index 1fcd3ea..8d8d8d0 100644 --- a/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabTest.java +++ b/src/test/java/org/jenkinsci/plugins/parameterizedscheduler/ParameterizedCronTabTest.java @@ -8,6 +8,7 @@ import java.util.Locale; import java.util.Map; +import hudson.scheduler.Hash; import org.jenkinsci.plugins.parameterizedscheduler.ParameterizedCronTab; import org.junit.Test; import org.jvnet.localizer.LocaleProvider; @@ -41,4 +42,30 @@ public void ctor_happyPath() throws Exception { } + @Test + public void param_value_with_percent_sign() throws Exception { + String cron = "* * * * *"; + String params = "one=onevalue;two=10%"; + String line = cron +" %" + params; + Map 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_seperator() throws Exception { + String line = "* * * * *"; + Map 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()); + } + }