From 6d87fe6057f49c18cb243cfadaa93ecd6993c14c Mon Sep 17 00:00:00 2001
From: Rainer Burgstaller
Date: Fri, 10 Feb 2017 22:36:49 +0100
Subject: [PATCH 1/3] Support specification of variable patterns
- this change allows the use of system environment patterns for
project and branch specification such as
${PROJECT_NAME}
- Example:
the gerrit host has a configured environment variable defined as
export PROJECT_NAME=myproject
now when we push a review commit for "myproject" then the gerrit
trigger will automatically react
- one use case for this is to be able to specfiy a generic seed
job for a jenkins instance which will automatically trigger
a build on the variable based project
---
.../hudsontrigger/data/CompareType.java | 10 +++-
.../hudsontrigger/data/CompareUtil.java | 50 +++++++++++++++++--
.../help-GerritTriggerConfiguration.html | 4 +-
...GerritProjectWithFilesInterestingTest.java | 16 ++++++
4 files changed, 72 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java
index 451efef4e..4925cfdcb 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java
@@ -46,7 +46,13 @@ public enum CompareType {
/**
* Regular expression comparison.
*/
- REG_EXP(new RegExpCompareUtil());
+ REG_EXP(new RegExpCompareUtil()),
+
+ /**
+ * Plain comparison however, the pattern will be expanded with the system environment.
+ * This allows comparisons such as "${PROJECTNAME}".
+ */
+ PLAIN_VAR(new CompareUtil.PlainVarCompareUtil());
/**
* Gets a list of all CompareType's displayNames.
@@ -88,7 +94,7 @@ public static CompareType findByOperator(char operator) {
return PLAIN;
}
- private CompareUtil util;
+ CompareUtil util;
/**
* Private Constructor.
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
index b8df9df82..d6cad3567 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
@@ -23,11 +23,14 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
-import java.io.File;
+import hudson.EnvVars;
import org.apache.tools.ant.types.selectors.SelectorUtils;
+import java.io.File;
+
/**
* Base interface for the compare-algorithms.
+ *
* @author Robert Sandell <robert.sandell@sonyericsson.com>
*/
public interface CompareUtil {
@@ -56,7 +59,7 @@ public interface CompareUtil {
* Compares based on Ant-style paths.
* like my/**/something*.git
*/
- static class AntCompareUtil implements CompareUtil {
+ class AntCompareUtil implements CompareUtil {
@Override
public boolean matches(String pattern, String str) {
@@ -80,9 +83,9 @@ public char getOperator() {
}
/**
- * Compares with pattern.equals(str).
+ * Compares with pattern.equalsIgnoreCase(str).
*/
- static class PlainCompareUtil implements CompareUtil {
+ class PlainCompareUtil implements CompareUtil {
@Override
public boolean matches(String pattern, String str) {
@@ -105,7 +108,7 @@ public char getOperator() {
* string.matches(pattern)
* @see java.util.regex.Pattern
*/
- static class RegExpCompareUtil implements CompareUtil {
+ class RegExpCompareUtil implements CompareUtil {
@Override
public boolean matches(String pattern, String str) {
@@ -122,4 +125,41 @@ public char getOperator() {
return '~';
}
}
+
+ /**
+ * Compares just like plain comparison, however, patterns are expanded using the
+ * given system environment settings.
+ */
+ class PlainVarCompareUtil implements CompareUtil {
+ private final EnvVars systemEnvVars;
+
+ public PlainVarCompareUtil() {
+ systemEnvVars = new EnvVars(EnvVars.masterEnvVars);
+ }
+
+ /**
+ * Test only method to allow injecting test properties into our environment.
+ * @param key the key to inject into the env vars.
+ * @param value the value associated with the key.
+ */
+ void inject(String key, String value) {
+ systemEnvVars.put(key, value);
+ }
+
+ @Override
+ public boolean matches(String pattern, String str) {
+ String expandedPattern = systemEnvVars.expand(pattern);
+ return expandedPattern.equalsIgnoreCase(str);
+ }
+
+ @Override
+ public String getName() {
+ return "PlainVar";
+ }
+
+ @Override
+ public char getOperator() {
+ return ':';
+ }
+ }
}
diff --git a/src/main/webapp/trigger/help-GerritTriggerConfiguration.html b/src/main/webapp/trigger/help-GerritTriggerConfiguration.html
index ef4bd54ff..fe27dc7bd 100644
--- a/src/main/webapp/trigger/help-GerritTriggerConfiguration.html
+++ b/src/main/webapp/trigger/help-GerritTriggerConfiguration.html
@@ -8,7 +8,9 @@
You can specify the name pattern in three different ways, as provided by the "Type" drop-down menu.
- - Plain: The exact name in Gerrit, case sensitive equality.
+ - Plain: The exact name in Gerrit, case insensitive equality.
+ - PlainVar: The exact name in Gerrit, case insensitive equality, allows usage of system environment
+ variables defined on the gerrit host (e.g.
${ENVIRONMENT}).
- Path: ANT style pattern. Ex: "**/base/*"
- RegExp: Regular expression.
diff --git a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java
index 1d93c3a98..a27893a89 100644
--- a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java
+++ b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java
@@ -23,6 +23,7 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -60,6 +61,13 @@ public void testInteresting() {
scenarioWithFiles.project, scenarioWithFiles.branch, scenarioWithFiles.topic, scenarioWithFiles.files));
}
+ @BeforeClass
+ public static void setupEnv() {
+ // this is a somewhat hacky way to deal with the fact that the compare util was already set up before
+ // we get the chance to update the system environment
+ ((CompareUtil.PlainVarCompareUtil) CompareType.PLAIN_VAR.util).inject("PROJECTNAME", "myproject");
+ }
+
/**
* The parameters.
* @return parameters
@@ -213,6 +221,14 @@ public static Collection getParameters() {
parameters.add(new InterestingScenarioWithFiles[]{new InterestingScenarioWithFiles(
config, "vendor/semc/master/project", "origin/master", null, files, false), });
+ branches = new LinkedList();
+ branch = new Branch(CompareType.PLAIN, "master");
+ branches.add(branch);
+ config = new GerritProject(CompareType.PLAIN_VAR, "${PROJECTNAME}", branches, null, null, null,
+ false);
+ parameters.add(new InterestingScenarioWithFiles[]{new InterestingScenarioWithFiles(
+ config, "myproject", "master", null, null, true),});
+
return parameters;
}
From e52b82c48ef028f6a142b3a9ddee7cee3dc68b58 Mon Sep 17 00:00:00 2001
From: Rainer Burgstaller
Date: Tue, 21 Feb 2017 06:54:38 +0100
Subject: [PATCH 2/3] implemented review comments, improved env var handling
---
.../trigger/hudsontrigger/GerritTrigger.java | 68 ++++++++++++++++---
.../trigger/hudsontrigger/data/Branch.java | 6 +-
.../hudsontrigger/data/CompareType.java | 15 ++--
.../hudsontrigger/data/CompareUtil.java | 56 ++++-----------
.../trigger/hudsontrigger/data/FilePath.java | 6 +-
.../hudsontrigger/data/GerritProject.java | 32 +++++----
.../trigger/hudsontrigger/data/Topic.java | 6 +-
.../help-GerritTriggerConfiguration.html | 5 +-
.../hudsontrigger/GerritTriggerTest.java | 11 +--
.../data/GerritProjectInterestingTest.java | 7 +-
...GerritProjectWithFilesInterestingTest.java | 15 ++--
11 files changed, 129 insertions(+), 98 deletions(-)
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java
index 56c00415a..d1be8f5f7 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java
@@ -67,6 +67,7 @@
import com.sonymobile.tools.gerrit.gerritevents.dto.events.RefUpdated;
import com.sonymobile.tools.gerrit.gerritevents.dto.rest.Notify;
+import hudson.EnvVars;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.Util;
@@ -85,8 +86,12 @@
import hudson.model.Queue;
import hudson.model.Run;
import hudson.model.Result;
+import hudson.slaves.EnvironmentVariablesNodeProperty;
+import hudson.slaves.NodeProperty;
+import hudson.slaves.NodePropertyDescriptor;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
+import hudson.util.DescribableList;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import hudson.util.ListBoxModel.Option;
@@ -178,6 +183,9 @@ public class GerritTrigger extends Trigger {
private List triggerOnEvents;
private boolean dynamicTriggerConfiguration;
private String triggerConfigURL;
+ private final EnvVars envVars;
+ private int globalHashVarsHash;
+ private int systemEnvVarsHash;
private GerritTriggerTimerTask gerritTriggerTimerTask;
private GerritTriggerInformationAction triggerInformationAction;
@@ -194,8 +202,10 @@ public GerritTrigger(List gerritProjects) {
this.skipVote = new SkipVote(false, false, false, false);
this.escapeQuotes = true;
this.serverName = ANY_SERVER;
+ this.envVars = initEnvVars();
+
try {
- DescriptorImpl descriptor = (DescriptorImpl)getDescriptor();
+ DescriptorImpl descriptor = (DescriptorImpl) getDescriptor();
if (descriptor != null) {
ListBoxModel options = descriptor.doFillNotificationLevelItems(this.serverName);
if (!options.isEmpty()) {
@@ -334,6 +344,23 @@ public GerritTrigger(List gerritProjects, SkipVote skipVote, Inte
this.gerritTriggerTimerTask = null;
this.triggerInformationAction = new GerritTriggerInformationAction();
this.notificationLevel = notificationLevel;
+ this.envVars = initEnvVars();
+ }
+
+ /**
+ * Initializes the environment variables used for expansion.
+ */
+ private EnvVars initEnvVars() {
+ EnvVars result = new EnvVars(EnvVars.masterEnvVars);
+ DescribableList, NodePropertyDescriptor> globalProps =
+ Jenkins.getActiveInstance().getGlobalNodeProperties();
+ EnvironmentVariablesNodeProperty envVarsProp = globalProps.get(EnvironmentVariablesNodeProperty.class);
+ EnvVars globalEnvVars = envVarsProp.getEnvVars();
+ result.putAll(globalEnvVars);
+
+ systemEnvVarsHash = EnvVars.masterEnvVars.hashCode();
+ globalHashVarsHash = globalEnvVars.hashCode();
+ return result;
}
/**
@@ -960,14 +987,15 @@ public boolean equals(Object obj) {
}
logger.trace("entering isInteresting projects configured: {} the event: {}", allGerritProjects.size(), event);
+ updateEnvVarsIfNecessary();
for (GerritProject p : allGerritProjects) {
try {
if (event instanceof ChangeBasedEvent) {
ChangeBasedEvent changeBasedEvent = (ChangeBasedEvent)event;
if (isServerInteresting(event)
- && p.isInteresting(changeBasedEvent.getChange().getProject(),
- changeBasedEvent.getChange().getBranch(),
- changeBasedEvent.getChange().getTopic())) {
+ && p.isInteresting(changeBasedEvent.getChange().getProject(),
+ changeBasedEvent.getChange().getBranch(),
+ changeBasedEvent.getChange().getTopic(), envVars)) {
boolean containsFilePathsOrForbiddenFilePaths =
((p.getFilePaths() != null && p.getFilePaths().size() > 0)
@@ -975,11 +1003,11 @@ public boolean equals(Object obj) {
if (isFileTriggerEnabled() && containsFilePathsOrForbiddenFilePaths) {
if (isServerInteresting(event)
- && p.isInteresting(changeBasedEvent.getChange().getProject(),
- changeBasedEvent.getChange().getBranch(),
- changeBasedEvent.getChange().getTopic(),
- changeBasedEvent.getFiles(
- new GerritQueryHandler(getServerConfig(event))))) {
+ && p.isInteresting(changeBasedEvent.getChange().getProject(),
+ changeBasedEvent.getChange().getBranch(),
+ changeBasedEvent.getChange().getTopic(),
+ changeBasedEvent.getFiles(
+ new GerritQueryHandler(getServerConfig(event))), envVars)) {
logger.trace("According to {} the event is interesting.", p);
return true;
}
@@ -991,20 +1019,38 @@ public boolean equals(Object obj) {
} else if (event instanceof RefUpdated) {
RefUpdated refUpdated = (RefUpdated)event;
if (isServerInteresting(event) && p.isInteresting(refUpdated.getRefUpdate().getProject(),
- refUpdated.getRefUpdate().getRefName(), null)) {
+ refUpdated.getRefUpdate().getRefName(), null, envVars)) {
logger.trace("According to {} the event is interesting.", p);
return true;
}
}
} catch (PatternSyntaxException pse) {
logger.error(MessageFormat.format("Exception caught for project {0} and pattern {1}, message: {2}",
- new Object[]{job.getName(), p.getPattern(), pse.getMessage()}));
+ new Object[]{job.getName(), p.getPattern(), pse.getMessage()}));
}
}
logger.trace("Nothing interesting here, move along folks!");
return false;
}
+ /**
+ * Checks if the current system env vars are still the same and updates our local copy if necessary
+ */
+ private void updateEnvVarsIfNecessary() {
+ EnvironmentVariablesNodeProperty envVarsProp =
+ Jenkins.getActiveInstance().getGlobalNodeProperties().get(EnvironmentVariablesNodeProperty.class);
+ EnvVars globalEnvVars = envVarsProp.getEnvVars();
+ int newSystemEnvVarsHash = EnvVars.masterEnvVars.hashCode();
+ int newGlobalEnvVarsHash = globalEnvVars.hashCode();
+ if (newSystemEnvVarsHash != systemEnvVarsHash || newGlobalEnvVarsHash != globalHashVarsHash) {
+ this.envVars.clear();
+ this.envVars.putAll(EnvVars.masterEnvVars);
+ this.envVars.putAll(globalEnvVars);
+ systemEnvVarsHash = newSystemEnvVarsHash;
+ globalHashVarsHash = newGlobalEnvVarsHash;
+ }
+ }
+
/**
* Check whether the event provider contains the same server name as the serverName field.
*
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Branch.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Branch.java
index d884dfb8d..1831d11c1 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Branch.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Branch.java
@@ -23,6 +23,7 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
+import hudson.EnvVars;
import hudson.Extension;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
@@ -90,10 +91,11 @@ public void setPattern(String pattern) {
/**
* Tells if the given branch is matched by this rule.
* @param branch the branch
+ * @param envVars the environment variables exisiting on the jenkins host.
* @return true if the branch matches.
*/
- public boolean isInteresting(String branch) {
- return compareType.matches(pattern, branch);
+ public boolean isInteresting(String branch, EnvVars envVars) {
+ return compareType.matches(pattern, branch, envVars);
}
/**
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java
index 4925cfdcb..0fe1a403e 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareType.java
@@ -26,6 +26,8 @@
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.CompareUtil.AntCompareUtil;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.CompareUtil.PlainCompareUtil;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.CompareUtil.RegExpCompareUtil;
+import hudson.EnvVars;
+
import java.util.LinkedList;
import java.util.List;
@@ -46,13 +48,7 @@ public enum CompareType {
/**
* Regular expression comparison.
*/
- REG_EXP(new RegExpCompareUtil()),
-
- /**
- * Plain comparison however, the pattern will be expanded with the system environment.
- * This allows comparisons such as "${PROJECTNAME}".
- */
- PLAIN_VAR(new CompareUtil.PlainVarCompareUtil());
+ REG_EXP(new RegExpCompareUtil());
/**
* Gets a list of all CompareType's displayNames.
@@ -108,10 +104,11 @@ private CompareType(CompareUtil util) {
* Tells if the given string matches the given pattern based on the algorithm of this CompareType instance.
* @param pattern the pattern
* @param str the string
+ * @param envVars the environment variables exisiting on the jenkins host.
* @return true if the string matches the pattern.
*/
- public boolean matches(String pattern, String str) {
- return util.matches(pattern, str);
+ public boolean matches(String pattern, String str, EnvVars envVars) {
+ return util.matches(pattern, str, envVars);
}
/**
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
index d6cad3567..6063357f0 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
@@ -39,9 +39,10 @@ public interface CompareUtil {
* Tells if the given pattern matches the string according to the implemented comparer/algorithm.
* @param pattern the pattern to use.
* @param str the string to match on.
+ * @param envVars the environment variables exisiting on the jenkins host.
* @return true if the string matches the pattern.
*/
- boolean matches(String pattern, String str);
+ boolean matches(String pattern, String str, EnvVars envVars);
/**
* Returns the human-readable name of the util.
@@ -62,13 +63,14 @@ public interface CompareUtil {
class AntCompareUtil implements CompareUtil {
@Override
- public boolean matches(String pattern, String str) {
+ public boolean matches(String pattern, String str, EnvVars envVars) {
// Replace the Git directory separator character (always '/')
// with the platform specific directory separator before
// invoking Ant's platform specific path matching.
String safePattern = pattern.replace('/', File.separatorChar);
+ String expandedPattern = envVars.expand(safePattern);
String safeStr = str.replace('/', File.separatorChar);
- return SelectorUtils.matchPath(safePattern, safeStr);
+ return SelectorUtils.matchPath(expandedPattern, safeStr);
}
@Override
@@ -88,8 +90,10 @@ public char getOperator() {
class PlainCompareUtil implements CompareUtil {
@Override
- public boolean matches(String pattern, String str) {
- return pattern.equalsIgnoreCase(str);
+ public boolean matches(String pattern, String str, EnvVars envVars) {
+ String expandedPattern = envVars.expand(pattern);
+
+ return expandedPattern.equalsIgnoreCase(str);
}
@Override
@@ -111,8 +115,9 @@ public char getOperator() {
class RegExpCompareUtil implements CompareUtil {
@Override
- public boolean matches(String pattern, String str) {
- return str.matches(pattern);
+ public boolean matches(String pattern, String str, EnvVars envVars) {
+ String expandedPattern = envVars.expand(pattern);
+ return str.matches(expandedPattern);
}
@Override
@@ -125,41 +130,4 @@ public char getOperator() {
return '~';
}
}
-
- /**
- * Compares just like plain comparison, however, patterns are expanded using the
- * given system environment settings.
- */
- class PlainVarCompareUtil implements CompareUtil {
- private final EnvVars systemEnvVars;
-
- public PlainVarCompareUtil() {
- systemEnvVars = new EnvVars(EnvVars.masterEnvVars);
- }
-
- /**
- * Test only method to allow injecting test properties into our environment.
- * @param key the key to inject into the env vars.
- * @param value the value associated with the key.
- */
- void inject(String key, String value) {
- systemEnvVars.put(key, value);
- }
-
- @Override
- public boolean matches(String pattern, String str) {
- String expandedPattern = systemEnvVars.expand(pattern);
- return expandedPattern.equalsIgnoreCase(str);
- }
-
- @Override
- public String getName() {
- return "PlainVar";
- }
-
- @Override
- public char getOperator() {
- return ':';
- }
- }
}
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/FilePath.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/FilePath.java
index 1d332fe3e..3d2851ed4 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/FilePath.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/FilePath.java
@@ -23,6 +23,7 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
+import hudson.EnvVars;
import hudson.Extension;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
@@ -92,11 +93,12 @@ public void setPattern(String pattern) {
/**
* Tells if the given files are matched by this rule.
* @param files the files in the patch set.
+ * @param envVars the environment variables exisiting on the jenkins host.
* @return true if the files match.
*/
- public boolean isInteresting(List files) {
+ public boolean isInteresting(List files, EnvVars envVars) {
for (String file : files) {
- if (compareType.matches(pattern, file)) {
+ if (compareType.matches(pattern, file, envVars)) {
return true;
}
}
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java
index 693e834e6..554c2d71e 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java
@@ -25,6 +25,8 @@
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
import static com.sonyericsson.hudson.plugins.gerrit.trigger.GerritServer.ANY_SERVER;
+
+import hudson.EnvVars;
import hudson.Extension;
import hudson.RelativePath;
import hudson.model.Describable;
@@ -210,23 +212,24 @@ public void setForbiddenFilePaths(List forbiddenFilePaths) {
* @param branch the branch.
* @param topic the topic.
* @param files the files.
+ * @param envVars the environment variables exisiting on the jenkins host.
* @return true is the rules match.
*/
- public boolean isInteresting(String project, String branch, String topic, List files) {
- if (compareType.matches(pattern, project)) {
+ public boolean isInteresting(String project, String branch, String topic, List files, EnvVars envVars) {
+ if (compareType.matches(pattern, project, envVars)) {
for (Branch b : branches) {
boolean foundInterestingForbidden = false;
boolean foundInterestingTopicOrFile = false;
- if (b.isInteresting(branch)) {
+ if (b.isInteresting(branch, envVars)) {
if (forbiddenFilePaths != null) {
for (FilePath ffp : forbiddenFilePaths) {
- if (ffp.isInteresting(files)) {
+ if (ffp.isInteresting(files, envVars)) {
foundInterestingForbidden = true;
break;
}
}
}
- if (isInterestingTopic(topic) && isInterestingFile(files)) {
+ if (isInterestingTopic(topic, envVars) && isInterestingFile(files, envVars)) {
foundInterestingTopicOrFile = true;
}
if (disableStrictForbiddenFileVerification) {
@@ -253,13 +256,14 @@ public boolean isInteresting(String project, String branch, String topic, List 0) {
for (Topic t : topics) {
- if (t.isInteresting(topic)) {
+ if (t.isInteresting(topic, envVars)) {
return true;
}
}
@@ -288,12 +293,13 @@ private boolean isInterestingTopic(String topic) {
* Compare files to see if the rules specified is a match.
*
* @param files the files.
+ * @param envVars the environment variables exisiting on the jenkins host.
* @return true if the rules match or no rules.
*/
- private boolean isInterestingFile(List files) {
+ private boolean isInterestingFile(List files, EnvVars envVars) {
if (filePaths != null && filePaths.size() > 0) {
for (FilePath f : filePaths) {
- if (f.isInteresting(files)) {
+ if (f.isInteresting(files, envVars)) {
return true;
}
}
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Topic.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Topic.java
index 4834d4d2b..416fafce1 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Topic.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/Topic.java
@@ -23,6 +23,7 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
+import hudson.EnvVars;
import hudson.Extension;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
@@ -89,13 +90,14 @@ public void setPattern(String pattern) {
/**
* Tells if the given topic are matched by this rule.
* @param topic the topic in change.
+ * @param envVars the environment variables exisiting on the jenkins host.
* @return true if the topic match.
*/
- public boolean isInteresting(String topic) {
+ public boolean isInteresting(String topic, EnvVars envVars) {
if (topic == null) {
topic = "";
}
- if (compareType.matches(pattern, topic)) {
+ if (compareType.matches(pattern, topic, envVars)) {
return true;
}
return false;
diff --git a/src/main/webapp/trigger/help-GerritTriggerConfiguration.html b/src/main/webapp/trigger/help-GerritTriggerConfiguration.html
index fe27dc7bd..b1257972b 100644
--- a/src/main/webapp/trigger/help-GerritTriggerConfiguration.html
+++ b/src/main/webapp/trigger/help-GerritTriggerConfiguration.html
@@ -8,9 +8,8 @@
You can specify the name pattern in three different ways, as provided by the "Type" drop-down menu.
- - Plain: The exact name in Gerrit, case insensitive equality.
- - PlainVar: The exact name in Gerrit, case insensitive equality, allows usage of system environment
- variables defined on the gerrit host (e.g.
${ENVIRONMENT}).
+ - Plain: The exact name in Gerrit, case insensitive equality, allows usage of system environment
+ variables defined on the jenkins host (e.g.
${ENVIRONMENT}).
- Path: ANT style pattern. Ex: "**/base/*"
- RegExp: Regular expression.
diff --git a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerTest.java b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerTest.java
index 84177b39a..31c130f9b 100644
--- a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerTest.java
+++ b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerTest.java
@@ -49,6 +49,7 @@
import com.sonymobile.tools.gerrit.gerritevents.dto.events.PatchsetCreated;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.RefUpdated;
+import hudson.EnvVars;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
@@ -758,7 +759,7 @@ public void testGerritEvent() {
PowerMockito.when(ToGerritRunListener.getInstance()).thenReturn(listener);
GerritProject gP = mock(GerritProject.class);
- doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class));
+ doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class), any(EnvVars.class));
when(gP.getFilePaths()).thenReturn(null);
@@ -838,7 +839,7 @@ public void testGerritEventNotInteresting() {
PowerMockito.when(ToGerritRunListener.getInstance()).thenReturn(listener);
GerritProject gP = mock(GerritProject.class);
- doReturn(false).when(gP).isInteresting(any(String.class), any(String.class), any(String.class));
+ doReturn(false).when(gP).isInteresting(any(String.class), any(String.class), any(String.class), any(EnvVars.class));
when(gP.getFilePaths()).thenReturn(null);
GerritTrigger trigger = Setup.createDefaultTrigger(project);
@@ -882,7 +883,7 @@ public void testGerritEventManualEvent() {
PowerMockito.when(ToGerritRunListener.getInstance()).thenReturn(listener);
GerritProject gP = mock(GerritProject.class);
- doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class));
+ doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class), any(EnvVars.class));
when(gP.getFilePaths()).thenReturn(null);
GerritTrigger trigger = Setup.createDefaultTrigger(project);
@@ -1029,7 +1030,7 @@ public void testGerritEventSilentMode() {
PowerMockito.when(ToGerritRunListener.getInstance()).thenReturn(listener);
GerritProject gP = mock(GerritProject.class);
- doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class));
+ doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class), any(EnvVars.class));
when(gP.getFilePaths()).thenReturn(null);
GerritTrigger trigger = Setup.createDefaultTrigger(null);
@@ -1060,7 +1061,7 @@ public void testGerritEventManualEventSilentMode() {
PowerMockito.when(ToGerritRunListener.getInstance()).thenReturn(listener);
GerritProject gP = mock(GerritProject.class);
- doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class));
+ doReturn(true).when(gP).isInteresting(any(String.class), any(String.class), any(String.class), any(EnvVars.class));
when(gP.getFilePaths()).thenReturn(null);
GerritTrigger trigger = Setup.createDefaultTrigger(project);
diff --git a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectInterestingTest.java b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectInterestingTest.java
index 015916357..249c51516 100644
--- a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectInterestingTest.java
+++ b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectInterestingTest.java
@@ -23,6 +23,7 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
+import hudson.EnvVars;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -42,6 +43,7 @@
public class GerritProjectInterestingTest {
private final InterestingScenario scenario;
+ private EnvVars envVars;
/**
* Constructor.
@@ -49,17 +51,18 @@ public class GerritProjectInterestingTest {
*/
public GerritProjectInterestingTest(InterestingScenario scenario) {
this.scenario = scenario;
+ envVars = new EnvVars();
}
/**
- * Tests {@link GerritProject#isInteresting(String, String, String)}.
+ * Tests {@link GerritProject#isInteresting(String, String, String, hudson.EnvVars)}.
*/
@Test
public void testInteresting() {
assertEquals(scenario.expected, scenario.config.isInteresting(
scenario.project,
scenario.branch,
- scenario.topic));
+ scenario.topic, envVars));
}
/**
diff --git a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java
index a27893a89..ba7e438c6 100644
--- a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java
+++ b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProjectWithFilesInterestingTest.java
@@ -23,6 +23,7 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data;
+import hudson.EnvVars;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,7 +44,7 @@
public class GerritProjectWithFilesInterestingTest {
private final InterestingScenarioWithFiles scenarioWithFiles;
-
+ private static EnvVars envVars = new EnvVars();
/**
* Constructor.
* @param scenarioWithFiles scenarioWithFiles
@@ -53,19 +54,23 @@ public GerritProjectWithFilesInterestingTest(InterestingScenarioWithFiles scenar
}
/**
- * Tests {@link GerritProject#isInteresting(String, String, String, java.util.List)}.
+ * Tests {@link GerritProject#isInteresting(String, String, String, List, hudson.EnvVars)}.
*/
@Test
public void testInteresting() {
assertEquals(scenarioWithFiles.expected, scenarioWithFiles.config.isInteresting(
- scenarioWithFiles.project, scenarioWithFiles.branch, scenarioWithFiles.topic, scenarioWithFiles.files));
+ scenarioWithFiles.project, scenarioWithFiles.branch, scenarioWithFiles.topic, scenarioWithFiles.files, envVars));
}
+
+ /**
+ * Sets up the test environment.
+ */
@BeforeClass
public static void setupEnv() {
// this is a somewhat hacky way to deal with the fact that the compare util was already set up before
// we get the chance to update the system environment
- ((CompareUtil.PlainVarCompareUtil) CompareType.PLAIN_VAR.util).inject("PROJECTNAME", "myproject");
+ envVars.put("PROJECTNAME", "myproject");
}
/**
@@ -224,7 +229,7 @@ public static Collection getParameters() {
branches = new LinkedList();
branch = new Branch(CompareType.PLAIN, "master");
branches.add(branch);
- config = new GerritProject(CompareType.PLAIN_VAR, "${PROJECTNAME}", branches, null, null, null,
+ config = new GerritProject(CompareType.PLAIN, "${PROJECTNAME}", branches, null, null, null,
false);
parameters.add(new InterestingScenarioWithFiles[]{new InterestingScenarioWithFiles(
config, "myproject", "master", null, null, true),});
From e54aa5696bdfbb45a5f7d5902dd82da85810cfe1 Mon Sep 17 00:00:00 2001
From: Rainer Burgstaller
Date: Wed, 1 Mar 2017 06:32:33 +0100
Subject: [PATCH 3/3] implemented further review comments
- now we synchronize access to the global EnvVars in order to be
thread safe
- keep original public API and deprecate it
---
.../trigger/hudsontrigger/GerritTrigger.java | 3 +-
.../hudsontrigger/data/CompareUtil.java | 44 ++++++++++++++++---
.../hudsontrigger/data/GerritProject.java | 13 +++++-
3 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java
index d1be8f5f7..4b09edbd5 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTrigger.java
@@ -1036,12 +1036,13 @@ public boolean equals(Object obj) {
/**
* Checks if the current system env vars are still the same and updates our local copy if necessary
*/
- private void updateEnvVarsIfNecessary() {
+ private synchronized void updateEnvVarsIfNecessary() {
EnvironmentVariablesNodeProperty envVarsProp =
Jenkins.getActiveInstance().getGlobalNodeProperties().get(EnvironmentVariablesNodeProperty.class);
EnvVars globalEnvVars = envVarsProp.getEnvVars();
int newSystemEnvVarsHash = EnvVars.masterEnvVars.hashCode();
int newGlobalEnvVarsHash = globalEnvVars.hashCode();
+
if (newSystemEnvVarsHash != systemEnvVarsHash || newGlobalEnvVarsHash != globalHashVarsHash) {
this.envVars.clear();
this.envVars.putAll(EnvVars.masterEnvVars);
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
index 6063357f0..fc6b32c94 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/CompareUtil.java
@@ -39,7 +39,16 @@ public interface CompareUtil {
* Tells if the given pattern matches the string according to the implemented comparer/algorithm.
* @param pattern the pattern to use.
* @param str the string to match on.
- * @param envVars the environment variables exisiting on the jenkins host.
+ * @return true if the string matches the pattern.
+ * @deprecated use {@link #matches(String, String, EnvVars)} instead.
+ */
+ boolean matches(String pattern, String str);
+
+ /**
+ * Tells if the given pattern matches the string according to the implemented comparer/algorithm.
+ * @param pattern the pattern to use.
+ * @param str the string to match on.
+ * @param envVars the environment variables exisiting on the jenkins host. Can be {@code null}.
* @return true if the string matches the pattern.
*/
boolean matches(String pattern, String str, EnvVars envVars);
@@ -56,11 +65,32 @@ public interface CompareUtil {
*/
char getOperator();
+ abstract class AbstractCompareUtil implements CompareUtil {
+ @Override
+ public boolean matches(String pattern, String str) {
+ return matches(pattern, str, null);
+ }
+
+ /**
+ * Expands the pattern in case it contains tokens that can be resolved with the given envVars.
+ * @param pattern the pattern to expand.
+ * @param envVars the envVars to use for expansion, if {@code null} then the unmodified pattern will be returned
+ * @return the expanded string, if no envVars were provided will return the initial unmodified pattern
+ */
+ protected String expandWithEnvVarsIfPossible(String pattern, EnvVars envVars) {
+ if (envVars != null) {
+ return envVars.expand(pattern);
+ } else {
+ return pattern;
+ }
+ }
+ }
+
/**
* Compares based on Ant-style paths.
* like my/**/something*.git
*/
- class AntCompareUtil implements CompareUtil {
+ class AntCompareUtil extends AbstractCompareUtil {
@Override
public boolean matches(String pattern, String str, EnvVars envVars) {
@@ -68,7 +98,7 @@ public boolean matches(String pattern, String str, EnvVars envVars) {
// with the platform specific directory separator before
// invoking Ant's platform specific path matching.
String safePattern = pattern.replace('/', File.separatorChar);
- String expandedPattern = envVars.expand(safePattern);
+ String expandedPattern = expandWithEnvVarsIfPossible(safePattern, envVars);
String safeStr = str.replace('/', File.separatorChar);
return SelectorUtils.matchPath(expandedPattern, safeStr);
}
@@ -87,11 +117,11 @@ public char getOperator() {
/**
* Compares with pattern.equalsIgnoreCase(str).
*/
- class PlainCompareUtil implements CompareUtil {
+ class PlainCompareUtil extends AbstractCompareUtil {
@Override
public boolean matches(String pattern, String str, EnvVars envVars) {
- String expandedPattern = envVars.expand(pattern);
+ String expandedPattern = expandWithEnvVarsIfPossible(pattern, envVars);
return expandedPattern.equalsIgnoreCase(str);
}
@@ -112,11 +142,11 @@ public char getOperator() {
* string.matches(pattern)
* @see java.util.regex.Pattern
*/
- class RegExpCompareUtil implements CompareUtil {
+ class RegExpCompareUtil extends AbstractCompareUtil {
@Override
public boolean matches(String pattern, String str, EnvVars envVars) {
- String expandedPattern = envVars.expand(pattern);
+ String expandedPattern = expandWithEnvVarsIfPossible(pattern, envVars);
return str.matches(expandedPattern);
}
diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java
index 554c2d71e..e45d140e4 100644
--- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java
+++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/data/GerritProject.java
@@ -256,7 +256,18 @@ public boolean isInteresting(String project, String branch, String topic, List