diff --git a/CHANGELOG.md b/CHANGELOG.md index fb2a970..a761674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Changelog of Pull Request Notifier for Stash. ## 1.18 +* Triggers can be named. To make it easier to keep track of them in large installations. * Building against latest Stash version (3.11.1) using latest Atlassian Maven Plugin Suite version (6.0.3) ## 1.17 diff --git a/src/main/java/se/bjurr/prnfs/admin/AdminFormValues.java b/src/main/java/se/bjurr/prnfs/admin/AdminFormValues.java index b505a78..dd08ca2 100644 --- a/src/main/java/se/bjurr/prnfs/admin/AdminFormValues.java +++ b/src/main/java/se/bjurr/prnfs/admin/AdminFormValues.java @@ -14,7 +14,9 @@ public final class AdminFormValues extends ArrayList> { private static final long serialVersionUID = 9084184120202816120L; public static final String VALUE = "value"; + public static final String DEFAULT_NAME = "Unnamed trigger"; + public enum FIELDS { - user, password, events, FORM_IDENTIFIER, url, filter_string, filter_regexp, method, post_content, proxy_user, proxy_password, proxy_server, proxy_port, header_name, header_value + user, password, events, FORM_IDENTIFIER, url, filter_string, filter_regexp, method, post_content, proxy_user, proxy_password, proxy_server, proxy_port, header_name, header_value, name } } diff --git a/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java b/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java index 22e501e..6c42e7d 100644 --- a/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java +++ b/src/main/java/se/bjurr/prnfs/listener/PrnfsPullRequestEventListener.java @@ -135,7 +135,7 @@ public void handleEvent(PullRequestEvent pullRequestEvent) { postContent = Optional.of(renderer.render(notification.getPostContent().get())); } String renderedUrl = renderer.render(notification.getUrl()); - logger.info(action.getName() + " "// + logger.info(notification.getName() + " > " + action.getName() + " "// + pr.getFromRef().getId() + "(" + pr.getFromRef().getLatestChangeset() + ") -> " // + pr.getToRef().getId() + "(" + pr.getToRef().getLatestChangeset() + ")" + " " // + renderedUrl); diff --git a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java index 2946a39..f1e9c54 100644 --- a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java +++ b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotification.java @@ -6,6 +6,7 @@ import static com.google.common.base.Strings.emptyToNull; import static com.google.common.base.Strings.nullToEmpty; import static java.util.regex.Pattern.compile; +import static se.bjurr.prnfs.admin.AdminFormValues.DEFAULT_NAME; import java.net.URL; import java.util.List; @@ -29,10 +30,11 @@ public class PrnfsNotification { private final String proxyPassword; private final String proxyServer; private final Integer proxyPort; + private final String name; public PrnfsNotification(List triggers, String url, String user, String password, String filterString, String filterRegexp, String method, String postContent, List
headers, String proxyUser, - String proxyPassword, String proxyServer, String proxyPort) throws ValidationException { + String proxyPassword, String proxyServer, String proxyPort, String name) throws ValidationException { this.proxyUser = emptyToNull(nullToEmpty(proxyUser).trim()); this.proxyPassword = emptyToNull(nullToEmpty(proxyPassword).trim()); this.proxyServer = emptyToNull(nullToEmpty(proxyServer).trim()); @@ -66,6 +68,7 @@ public PrnfsNotification(List triggers, String url, Stri this.triggers = checkNotNull(triggers); this.filterString = filterString; this.filterRegexp = filterRegexp; + this.name = firstNonNull(emptyToNull(nullToEmpty(name).trim()), DEFAULT_NAME); } public Optional getFilterRegexp() { @@ -96,6 +99,10 @@ public Optional getProxyUser() { return fromNullable(proxyUser); } + public String getName() { + return name; + } + public List getTriggers() { return triggers; } diff --git a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java index d939ff9..29fa3bd 100644 --- a/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java +++ b/src/main/java/se/bjurr/prnfs/settings/PrnfsNotificationBuilder.java @@ -28,13 +28,14 @@ public static PrnfsNotificationBuilder prnfsNotificationBuilder() { private String proxyPassword; private String proxyServer; private String proxyPort; + private String name; private PrnfsNotificationBuilder() { } public PrnfsNotification build() throws ValidationException { return new PrnfsNotification(triggers, url, user, password, filterString, filterRegexp, method, postContent, headers, - proxyUser, proxyPassword, proxyServer, proxyPort); + proxyUser, proxyPassword, proxyServer, proxyPort, name); } public PrnfsNotificationBuilder withPassword(String password) { @@ -101,4 +102,9 @@ public PrnfsNotificationBuilder withProxyPassword(String s) { this.proxyPassword = checkNotNull(s); return this; } + + public PrnfsNotificationBuilder withName(String name) { + this.name = name; + return this; + } } diff --git a/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java b/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java index 82defce..9f2183d 100644 --- a/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java +++ b/src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java @@ -9,6 +9,7 @@ import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newTreeMap; import static java.lang.System.currentTimeMillis; +import static se.bjurr.prnfs.admin.AdminFormValues.DEFAULT_NAME; import static se.bjurr.prnfs.admin.AdminFormValues.NAME; import static se.bjurr.prnfs.admin.AdminFormValues.VALUE; import static se.bjurr.prnfs.settings.PrnfsNotificationBuilder.prnfsNotificationBuilder; @@ -34,10 +35,6 @@ import com.google.gson.Gson; public class SettingsStorage { - /** - * Every form should have a field with this name, with a unique value. - */ - public static final String FORM_IDENTIFIER_NAME = "FORM_IDENTIFIER"; private static final Gson gson = new Gson(); private static Logger logger = LoggerFactory.getLogger(SettingsStorage.class); @@ -73,8 +70,8 @@ public static Logger getLogger() { private static Map getNotificationsMap(PluginSettings pluginSettings) { final Map allNotificationsMap = newTreeMap(); for (final AdminFormValues a : getSettingsAsFormValues(pluginSettings)) { - if (tryFind(a, predicate(FORM_IDENTIFIER_NAME)).isPresent()) { - allNotificationsMap.put(find(a, predicate(FORM_IDENTIFIER_NAME)).get(VALUE), a); + if (tryFind(a, predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())).isPresent()) { + allNotificationsMap.put(find(a, predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())).get(VALUE), a); } } return allNotificationsMap; @@ -152,6 +149,9 @@ public static PrnfsNotification getPrnfsNotification(AdminFormValues adminFormVa prnfsNotificationBuilder .withPostContent(find(adminFormValues, predicate(AdminFormValues.FIELDS.post_content.name())).get(VALUE)); } + if (tryFind(adminFormValues, predicate(AdminFormValues.FIELDS.name.name())).isPresent()) { + prnfsNotificationBuilder.withName(find(adminFormValues, predicate(AdminFormValues.FIELDS.name.name())).get(VALUE)); + } return prnfsNotificationBuilder.build(); } @@ -172,7 +172,7 @@ public static List getSettingsAsFormValues(PluginSettings setti @SuppressWarnings("unchecked") final List settingsList = newArrayList((List) settings.get(STORAGE_KEY)); for (final String storedJson : settingsList) { - toReturn.add(gson.fromJson(storedJson, AdminFormValues.class)); + toReturn.add(injectConfigurationName(gson.fromJson(storedJson, AdminFormValues.class))); } } catch (final Exception e) { logger.error("Unable to deserialize settings", e); @@ -180,6 +180,21 @@ public static List getSettingsAsFormValues(PluginSettings setti return toReturn; } + /** + * Inject a default name for the trigger. To make the plugin backwards + * compatible. + */ + private static AdminFormValues injectConfigurationName(AdminFormValues adminFormValues) { + final Optional> nameMapOpt = tryFind(adminFormValues, + predicate(AdminFormValues.FIELDS.name.name())); + if (nameMapOpt.isPresent()) { + return adminFormValues; + } + adminFormValues.add(ImmutableMap. builder().put(NAME, AdminFormValues.FIELDS.name.name()) + .put(VALUE, DEFAULT_NAME).build()); + return adminFormValues; + } + @VisibleForTesting public static void setLogger(Logger loggerParam) { logger = loggerParam; @@ -189,9 +204,10 @@ private static void storeNotificationsMap(PluginSettings pluginSettings, Map allNotificationsMap) throws ValidationException { final List toStore = newArrayList(); for (final AdminFormValues adminFormValues : allNotificationsMap.values()) { - final Optional> formIdOpt = tryFind(adminFormValues, predicate(FORM_IDENTIFIER_NAME)); + final Optional> formIdOpt = tryFind(adminFormValues, + predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())); if (!formIdOpt.isPresent() || formIdOpt.get().get(VALUE).trim().isEmpty()) { - throw new ValidationException(FORM_IDENTIFIER_NAME, "Not set!"); + throw new ValidationException(AdminFormValues.FIELDS.FORM_IDENTIFIER.name(), "Not set!"); } toStore.add(new Gson().toJson(adminFormValues)); } @@ -202,15 +218,16 @@ public static void storeSettings(PluginSettings pluginSettings, final AdminFormV throws ValidationException { final Map allNotificationsMap = getNotificationsMap(pluginSettings); - final Optional> formIdOpt = tryFind(config, predicate(FORM_IDENTIFIER_NAME)); + final Optional> formIdOpt = tryFind(config, + predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())); if (!formIdOpt.isPresent() || formIdOpt.get().get(VALUE).trim().isEmpty()) { final String generatedIdentifier = formIdentifierGnerator(); - removeIf(config, predicate(FORM_IDENTIFIER_NAME)); - config.add(new ImmutableMap.Builder().put(NAME, FORM_IDENTIFIER_NAME) + removeIf(config, predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())); + config.add(new ImmutableMap.Builder().put(NAME, AdminFormValues.FIELDS.FORM_IDENTIFIER.name()) .put(VALUE, generatedIdentifier).build()); } - allNotificationsMap.put(find(config, predicate(FORM_IDENTIFIER_NAME)).get(VALUE), config); + allNotificationsMap.put(find(config, predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())).get(VALUE), config); storeNotificationsMap(pluginSettings, allNotificationsMap); } diff --git a/src/main/resources/admin.css b/src/main/resources/admin.css index 4df15e7..b8e0dd5 100644 --- a/src/main/resources/admin.css +++ b/src/main/resources/admin.css @@ -57,3 +57,11 @@ td > input[type="text"] { margin: 0 10% 0 0; float:left } + +.expandable .content { + display: none; +} + +.expandable.expanded .content { + display: inherit; +} diff --git a/src/main/resources/admin.js b/src/main/resources/admin.js index a1d0916..6917cb8 100644 --- a/src/main/resources/admin.js +++ b/src/main/resources/admin.js @@ -45,6 +45,17 @@ }); }); + $('.expandable').each(function(index, el) { + var $element = $(el); + $element.find('.toggle').click(function() { + $element.toggleClass('expanded'); + }); + }); + //If there are only a few triggers configured, they can be expanded by default without confusion. + if ($('.expandable').length < 4) { + $('.expandable').addClass('expanded'); + } + $('.headers').keyup(function(e) { var $headers = $(this); adjustHeaders($headers); @@ -79,6 +90,7 @@ var $template = $(".prnfs-template").clone(); $('input[name="delete"]',$template).remove(); $('input[name=method][value=GET]', $template).attr('checked','checked'); + $('.expandable',$template).addClass('expanded'); $(".prnfs").append($template.html()); } @@ -91,6 +103,7 @@ $.each(configs, function(index, config) { var $template = $(".prnfs-template").clone(); $.each(config, function(fieldIndex,field_map) { + $('.variable[data-variable="'+field_map.name+'"]', $template).html(field_map.value); $('input[type="text"][name="'+field_map.name+'"]', $template).attr('value', field_map.value); $('input[type="password"][name="'+field_map.name+'"]', $template).attr('value', field_map.value); $('textarea[name="'+field_map.name+'"]', $template).text(field_map.value); diff --git a/src/main/resources/admin.vm b/src/main/resources/admin.vm index 9284b1e..18229b7 100644 --- a/src/main/resources/admin.vm +++ b/src/main/resources/admin.vm @@ -51,8 +51,20 @@
-
+ +
+
diff --git a/src/test/java/se/bjurr/prnfs/admin/NotificationsStorageTest.java b/src/test/java/se/bjurr/prnfs/admin/NotificationsStorageTest.java index 338ac6d..2c01523 100644 --- a/src/test/java/se/bjurr/prnfs/admin/NotificationsStorageTest.java +++ b/src/test/java/se/bjurr/prnfs/admin/NotificationsStorageTest.java @@ -1,6 +1,7 @@ package se.bjurr.prnfs.admin; import static com.atlassian.stash.pull.PullRequestAction.OPENED; +import static se.bjurr.prnfs.admin.AdminFormValues.DEFAULT_NAME; import static se.bjurr.prnfs.admin.utils.NotificationBuilder.notificationBuilder; import static se.bjurr.prnfs.admin.utils.PrnfsTestBuilder.prnfsTestBuilder; @@ -15,6 +16,7 @@ public void testThatANewNotificationCanBeStored() { notificationBuilder().withFieldValue(AdminFormValues.FIELDS.url, "http://bjurr.se/") .withFieldValue(AdminFormValues.FIELDS.events, OPENED.name()).build()).store().hasNotifications(1) .hasFieldValueAt(AdminFormValues.FIELDS.url, "http://bjurr.se/", "0") + .hasFieldValueAt(AdminFormValues.FIELDS.name, DEFAULT_NAME, "0") .hasNoneEmptyFieldAt(AdminFormValues.FIELDS.FORM_IDENTIFIER, "0"); } diff --git a/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java b/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java index fe3f8d8..f793fff 100644 --- a/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java +++ b/src/test/java/se/bjurr/prnfs/admin/utils/PrnfsTestBuilder.java @@ -19,7 +19,6 @@ import static se.bjurr.prnfs.listener.PrnfsPullRequestEventListener.setInvoker; import static se.bjurr.prnfs.listener.UrlInvoker.getHeaderValue; import static se.bjurr.prnfs.settings.PrnfsPredicates.predicate; -import static se.bjurr.prnfs.settings.SettingsStorage.FORM_IDENTIFIER_NAME; import static se.bjurr.prnfs.settings.SettingsStorage.fakeRandom; import java.util.List; @@ -162,7 +161,7 @@ private Map getAdminFormFields() { new Function() { @Override public String apply(AdminFormValues input) { - return find(input, predicate(FORM_IDENTIFIER_NAME)).get(VALUE); + return find(input, predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())).get(VALUE); } }); } @@ -273,7 +272,8 @@ public PullRequestEventBuilder triggerPullRequestEventBuilder() { } public PrnfsTestBuilder withNotification(AdminFormValues adminFormValues) { - final Optional> existing = tryFind(adminFormValues, predicate(FORM_IDENTIFIER_NAME)); + final Optional> existing = tryFind(adminFormValues, + predicate(AdminFormValues.FIELDS.FORM_IDENTIFIER.name())); if (existing.isPresent()) { this.adminFormValuesMap.put(existing.get().get(VALUE), adminFormValues); } else {