From 3fdd35764c82bb0f0069400ed64f878510ce5110 Mon Sep 17 00:00:00 2001 From: Hugh Saunders Date: Wed, 17 Jul 2019 10:01:33 +0100 Subject: [PATCH] Move settings to config page as default #119 This commit allows Jenkins users to specify defaults for build monitor views when creating the views from the Jenkins UI. End users can still modify these settings using the widget within build monitor. This is useful because the defaults do not scale to large numbers of builds so if a user is creating a build monitor view that they anticipate will contain a large number of builds they can increase the number of columns and prevent each end user from having to do that individually. This is essentially a rebase of @tcolligon's changes in pr #189 and is related to issue #119. --- build-monitor-acceptance/pom.xml | 20 ++++++ build-monitor-plugin/pom.xml | 9 ++- .../buildmonitor/BuildMonitorDescriptor.java | 30 ++++++++- .../buildmonitor/BuildMonitorView.java | 62 ++++++++++++++++-- .../plugins/buildmonitor/Config.java | 41 +++++++++++- .../buildmonitor/functions/NullSafety.java | 1 + .../BuildMonitorInstallation.java | 3 +- .../BuildMonitorView/configure-entries.jelly | 14 +++- .../buildmonitor/BuildMonitorView/index.jelly | 3 + .../src/main/webapp/scripts/settings.js | 13 ++-- .../BuildMonitorDescriptorTest.java | 64 ++++++++++++++++++- pom.xml | 6 +- 12 files changed, 244 insertions(+), 22 deletions(-) diff --git a/build-monitor-acceptance/pom.xml b/build-monitor-acceptance/pom.xml index 08a67e868..aefc67977 100644 --- a/build-monitor-acceptance/pom.xml +++ b/build-monitor-acceptance/pom.xml @@ -175,6 +175,26 @@ hamcrest-all test + + net.bytebuddy + byte-buddy + 1.9.10 + + + org.eclipse.jetty.websocket + websocket-common + 9.4.10.v20180503 + + + org.eclipse.jetty + jetty-io + 9.4.10.v20180503 + + + org.eclipse.jetty + jetty-util + 9.4.10.v20180503 + diff --git a/build-monitor-plugin/pom.xml b/build-monitor-plugin/pom.xml index 024fa516a..f0b7c43aa 100644 --- a/build-monitor-plugin/pom.xml +++ b/build-monitor-plugin/pom.xml @@ -122,7 +122,7 @@ org.jenkins-ci.modules instance-identity - 2.1 + 2.2 provided @@ -236,7 +236,12 @@ commons-io commons-io - 2.4 + 2.6 + + + commons-beanutils + commons-beanutils + 1.9.3 com.github.detro.ghostdriver diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptor.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptor.java index b58a4931c..cdaae2983 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptor.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptor.java @@ -35,6 +35,34 @@ public FormValidation doCheckIncludeRegex(@QueryParameter String value) { return FormValidation.ok(); } + @SuppressWarnings("unused") // used in the configure-entries.jelly form + public FormValidation doCheckFontSize(@QueryParameter String value) { + try { + float val = Float.parseFloat(value); + if (val >= 0.3 && val <= 2) { + return FormValidation.ok(); + } else { + return FormValidation.error("Must be >= 0.3 and <= 2"); + } + } catch (NumberFormatException e) { + return FormValidation.error("Must be float"); + } + } + + @SuppressWarnings("unused") // used in the configure-entries.jelly form + public FormValidation doCheckNumberOfColumns(@QueryParameter String value) { + try { + int val = Integer.parseInt(value); + if (val >= 1 && val <= 8) { + return FormValidation.ok(); + } else { + return FormValidation.error("Must be >= 1 and <= 8"); + } + } catch (NumberFormatException e) { + return FormValidation.error("Must be integer"); + } + } + @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { req.bindJSON(this, json.getJSONObject("build-monitor")); @@ -53,4 +81,4 @@ public boolean getPermissionToCollectAnonymousUsageStatistics() { public void setPermissionToCollectAnonymousUsageStatistics(boolean collect) { this.permissionToCollectAnonymousUsageStatistics = collect; } -} \ No newline at end of file +} diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java index 12e065443..3364f07e4 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView.java @@ -85,7 +85,7 @@ public String getCsrfCrumbFieldName() { public String currentOrder() { return currentConfig().getOrder().getClass().getSimpleName(); } - + @SuppressWarnings("unused") // used in the configure-entries.jelly form public String currentbuildFailureAnalyzerDisplayedField() { return currentConfig().getBuildFailureAnalyzerDisplayedField().getValue(); @@ -96,6 +96,26 @@ public boolean isDisplayCommitters() { return currentConfig().shouldDisplayCommitters(); } + @SuppressWarnings("unused") // used in the configure-entries.jelly form + public String currentFontSize() { + return String.valueOf(currentConfig().getFontSize()); + } + + @SuppressWarnings("unused") // used in the configure-entries.jelly form + public String currentNumberOfColumns() { + return String.valueOf(currentConfig().getNumberOfColumns()); + } + + @SuppressWarnings("unused") // used in the configure-entries.jelly form + public boolean isColourBlindMode() { + return currentConfig().isColourBlindMode(); + } + + @SuppressWarnings("unused") // used in the configure-entries.jelly form + public String getColourBlindModeValue() { + return isColourBlindMode() ? "1" : "0"; + } + private static final BuildMonitorInstallation installation = new BuildMonitorInstallation(); @SuppressWarnings("unused") // used in index.jelly @@ -121,7 +141,9 @@ protected void submit(StaplerRequest req) throws ServletException, IOException, currentConfig().setDisplayCommitters(json.optBoolean("displayCommitters", true)); currentConfig().setBuildFailureAnalyzerDisplayedField(req.getParameter("buildFailureAnalyzerDisplayedField")); - + submitFontSize(req); + submitNumberOfColumns(req); + submitColourBlindMode(req); try { currentConfig().setOrder(orderIn(requestedOrdering)); } catch (Exception e) { @@ -130,12 +152,42 @@ protected void submit(StaplerRequest req) throws ServletException, IOException, } } + private void submitFontSize(StaplerRequest req) throws FormException { + String fontSize = req.getParameter("fontSize"); + try { + float val = Float.parseFloat(fontSize); + if (val >= 0.3 && val <= 2) { + currentConfig().setFontSize(val); + } + } catch (NumberFormatException e) { + throw new FormException("Font size must be float and not null", fontSize); + } + } + + + private void submitNumberOfColumns(StaplerRequest req) throws FormException { + String numberOfColumns = req.getParameter("numberOfColumns"); + try { + int val = Integer.parseInt(numberOfColumns); + if (val >= 1 && val <= 8) { + currentConfig().setNumberOfColumns(val); + } + } catch (NumberFormatException e) { + throw new FormException("Number of columns must be integer and not null", numberOfColumns); + } + } + + private void submitColourBlindMode(StaplerRequest req) throws FormException { + String colourBlindMode = req.getParameter("colourBlindMode"); + currentConfig().setColourBlindMode(isGiven(colourBlindMode)); + } + /** * Because of how org.kohsuke.stapler.HttpResponseRenderer is implemented * it can only work with net.sf.JSONObject in order to produce correct application/json output * * @return Json representation of JobViews - * @throws Exception + * @throws Exception description */ @JavaScriptMethod public JSONObject fetchJobViews() throws Exception { @@ -196,7 +248,7 @@ private boolean deserailisingFromAnOlderFormat() { // If an older version of config.xml is loaded, "config" field is missing, but "order" is present private void migrateFromOldToNewConfigFormat() { - Config c = new Config(); + Config c = Config.defaultConfig(); c.setOrder(order); config = c; @@ -214,4 +266,4 @@ private void migrateFromOldToNewConfigFormat() { @Deprecated // use Config instead private Comparator> order; // note: this field can be removed when people stop using versions prior to 1.6+build.150 -} \ No newline at end of file +} diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java index c10b3296f..2e1bbeb54 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/Config.java @@ -14,7 +14,11 @@ public class Config { private BuildFailureAnalyzerDisplayedField buildFailureAnalyzerDisplayedField; public static Config defaultConfig() { - return new Config(); + Config config = new Config(); + config.setFontSize(1); + config.setNumberOfColumns(2); + config.setColourBlindMode(false); + return config; } public Comparator> getOrder() { @@ -32,7 +36,31 @@ public static Config defaultConfig() { public void setOrder(Comparator> order) { this.order = order; } - + + public float getFontSize() { + return fontSize; + } + + public void setFontSize(float fontSize) { + this.fontSize = fontSize; + } + + public int getNumberOfColumns() { + return numberOfColumns; + } + + public void setNumberOfColumns(int numberOfColumns) { + this.numberOfColumns = numberOfColumns; + } + + public boolean isColourBlindMode() { + return colourBlindMode; + } + + public void setColourBlindMode(boolean colourBlindMode) { + this.colourBlindMode = colourBlindMode; + } + public BuildFailureAnalyzerDisplayedField getBuildFailureAnalyzerDisplayedField() { return getOrElse(buildFailureAnalyzerDisplayedField, BuildFailureAnalyzerDisplayedField.Name); } @@ -75,4 +103,11 @@ public enum BuildFailureAnalyzerDisplayedField { } private Comparator> order; -} \ No newline at end of file + + private float fontSize; + + private int numberOfColumns; + + private boolean colourBlindMode; + +} diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/functions/NullSafety.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/functions/NullSafety.java index 04eb55cef..02fb1e86b 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/functions/NullSafety.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/functions/NullSafety.java @@ -5,6 +5,7 @@ public class NullSafety { /** * @param value a value that can be a potential null * @param defaultValue a default to be returned if the value is null + * @param a type * * @return either value or defaultValue */ diff --git a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/installation/BuildMonitorInstallation.java b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/installation/BuildMonitorInstallation.java index 672945b88..5d2dabff2 100644 --- a/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/installation/BuildMonitorInstallation.java +++ b/build-monitor-plugin/src/main/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/installation/BuildMonitorInstallation.java @@ -22,6 +22,7 @@ public BuildMonitorInstallation(StaticJenkinsAPIs jenkinsAPIs) { /** * Used to make sure that the anonymous Build Monitor stats are not double-counted, * as in a typical setup there's one Jenkins, but multiple Build Monitors. + * @return anonymous Correlation Id */ public String anonymousCorrelationId() { // we only need to calculate this once @@ -48,4 +49,4 @@ public Audience audience() { public String buildMonitorVersion() { return buildProperties.get("version"); } -} \ No newline at end of file +} diff --git a/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly index 3c39f5625..2e76a79ae 100644 --- a/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly +++ b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/configure-entries.jelly @@ -67,6 +67,18 @@ + + + + + + + + + + + + @@ -98,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/index.jelly b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/index.jelly index cff998f43..828632115 100644 --- a/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/index.jelly +++ b/build-monitor-plugin/src/main/resources/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorView/index.jelly @@ -190,6 +190,9 @@ constant('BUILD_MONITOR_VERSION', '${it.installation.buildMonitorVersion()}'). constant('CSRF_CRUMB_FIELD_NAME', '${it.csrfCrumbFieldName}'). + constant('DEFAULT_SETTINGS_FONTSIZE', '${it.currentFontSize()}'). + constant('DEFAULT_SETTINGS_NUMBEROFCOLUMNS', '${it.currentNumberOfColumns()}'). + constant('DEFAULT_SETTINGS_COLOURBLINDMODE', '${it.getColourBlindModeValue()}'). config(function(proxyProvider, cookieJarProvider, hashCodeProvider) { var hashCodeOf = hashCodeProvider.hashCodeOf; diff --git a/build-monitor-plugin/src/main/webapp/scripts/settings.js b/build-monitor-plugin/src/main/webapp/scripts/settings.js index 39198a01c..4e6ba735d 100644 --- a/build-monitor-plugin/src/main/webapp/scripts/settings.js +++ b/build-monitor-plugin/src/main/webapp/scripts/settings.js @@ -2,12 +2,15 @@ angular. module('buildMonitor.settings', [ 'buildMonitor.services', 'rzModule']). controller('controlPanel', ['$scope', 'cookieJar', 'townCrier', - function ($scope, cookieJar, townCrier) { + 'DEFAULT_SETTINGS_FONTSIZE', 'DEFAULT_SETTINGS_NUMBEROFCOLUMNS', + 'DEFAULT_SETTINGS_COLOURBLINDMODE', + function ($scope, cookieJar, townCrier, DEFAULT_SETTINGS_FONTSIZE, + DEFAULT_SETTINGS_NUMBEROFCOLUMNS, DEFAULT_SETTINGS_COLOURBLINDMODE) { 'use strict'; - $scope.settings.fontSize = cookieJar.get('fontSize', 1); - $scope.settings.numberOfColumns = cookieJar.get('numberOfColumns', 2); - $scope.settings.colourBlind = cookieJar.get('colourBlind', 0); + $scope.settings.fontSize = cookieJar.get('fontSize', DEFAULT_SETTINGS_FONTSIZE); + $scope.settings.numberOfColumns = cookieJar.get('numberOfColumns', DEFAULT_SETTINGS_NUMBEROFCOLUMNS); + $scope.settings.colourBlind = cookieJar.get('colourBlind', DEFAULT_SETTINGS_COLOURBLINDMODE); $scope.settings.reduceMotion = cookieJar.get('reduceMotion', 0); $scope.settings.showBadges = cookieJar.get('showBadges', 0); @@ -21,4 +24,4 @@ angular. townCrier.uponNewVersion(function() { $scope.newVersionAvailable = true; }); - }]); \ No newline at end of file + }]); diff --git a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptorTest.java b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptorTest.java index 4d1028b16..73d842803 100644 --- a/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptorTest.java +++ b/build-monitor-plugin/src/test/java/com/smartcodeltd/jenkinsci/plugins/buildmonitor/BuildMonitorDescriptorTest.java @@ -40,6 +40,68 @@ public void form_validator_should_advise_how_a_regex_could_be_improved() throws assertThat(htmlDecoded(result.getMessage()), containsString("Unmatched closing ')'")); } + @Test + public void form_validator_should_allow_fontsize_in_good_range() throws Exception { + FormValidation result = validator.doCheckFontSize("1.0"); + + assertThat(result.kind, is(OK)); + } + + @Test + public void form_validator_should_refuse_fontsize_under_0_3() throws Exception { + FormValidation result = validator.doCheckFontSize("0"); + + assertThat(result.kind, is(ERROR)); + assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 0.3 and <= 2")); + } + + @Test + public void form_validator_should_refuse_fontsize_over_2() throws Exception { + FormValidation result = validator.doCheckFontSize("2.1"); + + assertThat(result.kind, is(ERROR)); + assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 0.3 and <= 2")); + } + + @Test + public void form_validator_should_refuse_fontsize_not_float() throws Exception { + FormValidation result = validator.doCheckFontSize("a"); + + assertThat(result.kind, is(ERROR)); + assertThat(htmlDecoded(result.getMessage()), containsString("Must be float")); + } + + @Test + public void form_validator_should_allow_numberofcolumns_in_good_range() throws Exception { + FormValidation result = validator.doCheckNumberOfColumns("1"); + + assertThat(result.kind, is(OK)); + } + + @Test + public void form_validator_should_refuse_numberofcolumns_under_1() throws Exception { + FormValidation result = validator.doCheckNumberOfColumns("0"); + + assertThat(result.kind, is(ERROR)); + assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 1 and <= 8")); + } + + @Test + public void form_validator_should_refuse_numberofcolumns_over_8() throws Exception { + FormValidation result = validator.doCheckNumberOfColumns("10"); + + assertThat(result.kind, is(ERROR)); + assertThat(htmlDecoded(result.getMessage()), containsString("Must be >= 1 and <= 8")); + } + + @Test + public void form_validator_should_refuse_numberofcolumns_not_integer() throws Exception { + FormValidation result = validator.doCheckNumberOfColumns("a"); + + assertThat(result.kind, is(ERROR)); + assertThat(htmlDecoded(result.getMessage()), containsString("Must be integer")); + } + private String htmlDecoded(String message) { return StringEscapeUtils.unescapeHtml(message); } @@ -47,4 +109,4 @@ private String htmlDecoded(String message) { private String itShouldAllow(String regex) { return "should allow " + regex; } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index 0505ba3d6..b5fd520d8 100644 --- a/pom.xml +++ b/pom.xml @@ -4,8 +4,8 @@ 4.0.0 - 2.46.3 - 2.38 + 2.164.3 + 2.53 8 UTF-8 1.8 @@ -15,7 +15,7 @@ org.jenkins-ci.plugins plugin - 3.8 + 3.47 build-monitor