diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e9e88694a..cfa98f4782 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add branch link provider to access branch links in plugins ([#1243](https://github.com/scm-manager/scm-manager/pull/1243))
- Add key value input field component ([#1246](https://github.com/scm-manager/scm-manager/pull/1246))
+- Add Jexl parser ([#1251](https://github.com/scm-manager/scm-manager/pull/1251))
### Changed
- Adding start delay to liveness and readiness probes in helm chart template
diff --git a/scm-core/pom.xml b/scm-core/pom.xml
index d3bce80abf..2ada8e2e76 100644
--- a/scm-core/pom.xml
+++ b/scm-core/pom.xml
@@ -216,6 +216,22 @@
2.6
+
+ org.apache.commons
+ commons-jexl
+ 2.1.1
+
+
+ commons-logging
+ commons-logging
+
+
+ org.slf4j
+ jcl-over-slf4j
+
+
+
+
diff --git a/scm-core/src/main/java/sonia/scm/util/JexlUrlExpression.java b/scm-core/src/main/java/sonia/scm/util/JexlUrlExpression.java
new file mode 100644
index 0000000000..a6b8742cc3
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/util/JexlUrlExpression.java
@@ -0,0 +1,55 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package sonia.scm.util;
+
+import org.apache.commons.jexl2.MapContext;
+import org.apache.commons.jexl2.UnifiedJEXL.Expression;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+public class JexlUrlExpression {
+
+ private static final Logger logger = LoggerFactory.getLogger(JexlUrlExpression.class);
+
+ private final Expression expression;
+
+ public JexlUrlExpression(Expression expression) {
+ this.expression = expression;
+ }
+
+ public String evaluate(Map environment) {
+ String url = Util.EMPTY_STRING;
+ Object result = expression.evaluate(new MapContext(environment));
+
+ if (result != null) {
+ url = result.toString();
+ }
+
+ logger.trace("result of expression evaluation: {}", url);
+
+ return url;
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/util/JexlUrlParser.java b/scm-core/src/main/java/sonia/scm/util/JexlUrlParser.java
new file mode 100644
index 0000000000..c4657450ea
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/util/JexlUrlParser.java
@@ -0,0 +1,40 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package sonia.scm.util;
+
+import org.apache.commons.jexl2.JexlEngine;
+import org.apache.commons.jexl2.UnifiedJEXL;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JexlUrlParser {
+
+ private static final Logger logger = LoggerFactory.getLogger(JexlUrlParser.class);
+ private final UnifiedJEXL uel = new UnifiedJEXL(new JexlEngine());
+
+ public JexlUrlExpression parse(String urlPattern) {
+ logger.trace("try to parse url pattern: {}", urlPattern);
+ return new JexlUrlExpression(uel.parse(urlPattern));
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/web/data/EncodedStringList.java b/scm-core/src/main/java/sonia/scm/web/data/EncodedStringList.java
new file mode 100644
index 0000000000..9f652dd65c
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/web/data/EncodedStringList.java
@@ -0,0 +1,47 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package sonia.scm.web.data;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.common.base.Joiner;
+
+import java.util.List;
+
+public final class EncodedStringList {
+ private final List list;
+
+ public EncodedStringList(List list) {
+ this.list = list;
+ }
+
+ @Override
+ public String toString() {
+ return Joiner.on(',').join(Encoder.encode(list));
+ }
+
+ public List getList() {
+ return list;
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/web/data/Encoder.java b/scm-core/src/main/java/sonia/scm/web/data/Encoder.java
new file mode 100644
index 0000000000..d69bfc31a8
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/web/data/Encoder.java
@@ -0,0 +1,58 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package sonia.scm.web.data;
+
+import com.google.common.collect.Lists;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.List;
+
+public final class Encoder {
+
+ private static final String ENCODING = "UTF-8";
+ private static final Logger logger = LoggerFactory.getLogger(Encoder.class);
+
+ private Encoder() {
+ }
+
+ public static String encode(String value) {
+ if (value != null) {
+ try {
+ value = URLEncoder.encode(value, ENCODING);
+ } catch (UnsupportedEncodingException ex) {
+ logger.error("encoding is not supported", ex);
+ }
+
+ }
+
+ return value;
+ }
+
+ public static List encode(List values) {
+ return Lists.transform(values, Encoder::encode);
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedChangeset.java b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedChangeset.java
new file mode 100644
index 0000000000..d074ade672
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedChangeset.java
@@ -0,0 +1,66 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.web.data;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.repository.Changeset;
+
+public final class ImmutableEncodedChangeset {
+
+ private final Changeset changeset;
+
+ public ImmutableEncodedChangeset(Changeset changeset) {
+ this.changeset = changeset;
+ }
+
+ public ImmutableEncodedPerson getAuthor() {
+ return new ImmutableEncodedPerson(changeset.getAuthor());
+ }
+
+ public EncodedStringList getBranches() {
+ return new EncodedStringList(changeset.getBranches());
+ }
+
+ public Long getDate() {
+ return changeset.getDate();
+ }
+
+ public String getDescription() {
+ return Encoder.encode(changeset.getDescription());
+ }
+
+ public String getId() {
+ return changeset.getId();
+ }
+
+ public EncodedStringList getParents() {
+ return new EncodedStringList(changeset.getParents());
+ }
+
+ public EncodedStringList getTags() {
+ return new EncodedStringList(changeset.getTags());
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedModifications.java b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedModifications.java
new file mode 100644
index 0000000000..7b412cbc98
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedModifications.java
@@ -0,0 +1,60 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.web.data;
+
+import sonia.scm.repository.Added;
+import sonia.scm.repository.Modifications;
+import sonia.scm.repository.Modified;
+import sonia.scm.repository.Removed;
+
+import java.util.stream.Collectors;
+
+public final class ImmutableEncodedModifications {
+
+ private final Modifications modifications;
+
+ public ImmutableEncodedModifications(Modifications modifications) {
+ this.modifications = modifications;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("A:%s;M:%s;R:%s", getAdded(), getModified(), getRemoved());
+ }
+
+ public EncodedStringList getAdded() {
+ return new EncodedStringList(modifications.getAdded().stream().map(Added::getPath).collect(Collectors.toList()));
+
+ }
+
+ public EncodedStringList getModified() {
+ return new EncodedStringList(modifications.getModified().stream().map(Modified::getPath).collect(Collectors.toList()));
+ }
+
+ public EncodedStringList getRemoved() {
+ return new EncodedStringList(modifications.getRemoved().stream().map(Removed::getPath).collect(Collectors.toList()));
+ }
+
+}
diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedPerson.java b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedPerson.java
new file mode 100644
index 0000000000..c5ede4cdfa
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedPerson.java
@@ -0,0 +1,43 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package sonia.scm.web.data;
+
+import sonia.scm.repository.Person;
+
+public final class ImmutableEncodedPerson {
+
+ private final Person person;
+
+ public ImmutableEncodedPerson(Person person) {
+ this.person = person;
+ }
+
+ public String getMail() {
+ return Encoder.encode(person.getMail());
+ }
+
+ public String getName() {
+ return Encoder.encode(person.getName());
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedRepository.java b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedRepository.java
new file mode 100644
index 0000000000..965bdc4754
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/web/data/ImmutableEncodedRepository.java
@@ -0,0 +1,64 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package sonia.scm.web.data;
+
+import sonia.scm.repository.Repository;
+
+public final class ImmutableEncodedRepository {
+
+ private final Repository repository;
+
+ public ImmutableEncodedRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public String getContact() {
+ return Encoder.encode(repository.getContact());
+ }
+
+ public Long getCreationDate() {
+ return repository.getCreationDate();
+ }
+
+ public String getDescription() {
+ return Encoder.encode(repository.getDescription());
+ }
+
+ public String getId() {
+ return repository.getId();
+ }
+
+ public Long getLastModified() {
+ return repository.getLastModified();
+ }
+
+ public String getName() {
+ return repository.getName();
+ }
+
+ public String getType() {
+ return repository.getType();
+ }
+
+}
diff --git a/scm-core/src/test/java/sonia/scm/util/JexlUrlParserTest.java b/scm-core/src/test/java/sonia/scm/util/JexlUrlParserTest.java
new file mode 100644
index 0000000000..2d5ec98e0e
--- /dev/null
+++ b/scm-core/src/test/java/sonia/scm/util/JexlUrlParserTest.java
@@ -0,0 +1,59 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.util;
+
+import org.junit.jupiter.api.Test;
+import sonia.scm.repository.Changeset;
+import sonia.scm.repository.Person;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class JexlUrlParserTest {
+
+ @Test
+ void shouldParseUrlWithoutExpression() {
+ JexlUrlParser jexlUrlParser = new JexlUrlParser();
+ Map env = new HashMap<>();
+ env.put("changeset", new Changeset("1", 1L, Person.toPerson("trillian")));
+
+ String parsedUrl = jexlUrlParser.parse("http://hitchhiker.org").evaluate(env);
+
+ assertThat(parsedUrl).isEqualTo("http://hitchhiker.org");
+ }
+
+ @Test
+ void shouldParseUrlWithExpression() {
+ JexlUrlParser jexlUrlParser = new JexlUrlParser();
+ Map env = new HashMap<>();
+ env.put("changeset", new Changeset("1", 1L, Person.toPerson("trillian")));
+
+ String parsedUrl = jexlUrlParser.parse("http://${changeset.author.name}.org").evaluate(env);
+
+ assertThat(parsedUrl).isEqualTo("http://trillian.org");
+ }
+}