diff --git a/job-dsl-core/src/main/docs/examples/javaposse/jobdsl/dsl/DslFactory/dashboardView.groovy b/job-dsl-core/src/main/docs/examples/javaposse/jobdsl/dsl/DslFactory/dashboardView.groovy index 810cc4882..e796e1417 100644 --- a/job-dsl-core/src/main/docs/examples/javaposse/jobdsl/dsl/DslFactory/dashboardView.groovy +++ b/job-dsl-core/src/main/docs/examples/javaposse/jobdsl/dsl/DslFactory/dashboardView.groovy @@ -8,9 +8,21 @@ dashboardView('example') { buildButton() } topPortlets { + jenkinsJobsList { + displayName('acme jobs') + } + } + leftPortlets { testStatisticsChart() } + rightPortlets { + testTrendChart() + } bottomPortlets { + iframe { + effectiveUrl('http://example.com') + } testStatisticsGrid() + buildStatistics() } } diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/DashboardView.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/DashboardView.groovy index 37c5304f2..f2a97434d 100644 --- a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/DashboardView.groovy +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/DashboardView.groovy @@ -49,4 +49,8 @@ class DashboardView extends ListView { } } } + + static enum DisplayStatus { + ALL, SUCCESS, FAILED, SKIPPED + } } diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/BuildStatisticsContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/BuildStatisticsContext.groovy new file mode 100644 index 000000000..8948803e6 --- /dev/null +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/BuildStatisticsContext.groovy @@ -0,0 +1,15 @@ +package javaposse.jobdsl.dsl.views.portlets + +import javaposse.jobdsl.dsl.Context + +class BuildStatisticsContext implements Context { + + String displayName = 'Build statistics' + + /** + * Sets the display name for the portlet. Defaults to {@code 'Build statistics'}. + */ + void displayName(String displayName) { + this.displayName = displayName + } +} diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/DashboardPortletContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/DashboardPortletContext.groovy index 4ccc01d46..9be8240c5 100644 --- a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/DashboardPortletContext.groovy +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/DashboardPortletContext.groovy @@ -11,6 +11,55 @@ class DashboardPortletContext implements Context { protected final List portletNodes = [] + /** + * Add a build statistics. + * + * @since 1.46 + */ + void buildStatistics(@DslContext(BuildStatisticsContext) Closure closure = null) { + BuildStatisticsContext context = new BuildStatisticsContext() + ContextHelper.executeInContext(closure, context) + + portletNodes << new NodeBuilder().'hudson.plugins.view.dashboard.stats.StatBuilds' { + id(generatePortletId()) + name(context.displayName ?: '') + } + } + + /** + * Add a iframe portlet. + * + * @since 1.46 + */ + void iframe(@DslContext(IframeContext) Closure closure = null) { + IframeContext context = new IframeContext() + ContextHelper.executeInContext(closure, context) + + portletNodes << new NodeBuilder().'hudson.plugins.view.dashboard.core.IframePortlet' { + id(generatePortletId()) + name(context.displayName ?: '') + iframeSource(context.iframeSource ?: '') + effectiveSource(context.effectiveSource ?: '') + effectiveUrl(context.effectiveUrl ?: '') + divStyle(context.divStyle ?: '') + } + } + + /** + * Add a jenkins jobs list. + * + * @since 1.46 + */ + void jenkinsJobsList(@DslContext(JenkinsJobsListContext) Closure closure = null) { + JenkinsJobsListContext context = new JenkinsJobsListContext() + ContextHelper.executeInContext(closure, context) + + portletNodes << new NodeBuilder().'hudson.plugins.view.dashboard.core.HudsonStdJobsPortlet' { + id(generatePortletId()) + name(context.displayName ?: '') + } + } + /** * Adds a test statistics chart. */ @@ -41,6 +90,26 @@ class DashboardPortletContext implements Context { } } + /** + * Adds a trend chart. + * + * @since 1.46 + */ + void testTrendChart(@DslContext(TestTrendChartContext) Closure closure = null) { + TestTrendChartContext context = new TestTrendChartContext() + ContextHelper.executeInContext(closure, context) + + portletNodes << new NodeBuilder().'hudson.plugins.view.dashboard.test.TestTrendChart' { + id(generatePortletId()) + name(context.displayName ?: '') + graphWidth(context.graphWidth ?: 200) + graphHeight(context.graphHeight ?: 300) + dateRange(context.dateRange ?: 30) + dateShift(context.dateShift ?: 0) + displayStatus(context.displayStatus) + } + } + private static String generatePortletId() { "dashboard_portlet_${RANDOM.nextInt(32000)}" } diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/IframeContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/IframeContext.groovy new file mode 100644 index 000000000..c65926318 --- /dev/null +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/IframeContext.groovy @@ -0,0 +1,47 @@ +package javaposse.jobdsl.dsl.views.portlets + +import javaposse.jobdsl.dsl.Context + +class IframeContext implements Context { + + String displayName = 'Iframe Portlet' + String iframeSource = '' + String effectiveSource = '' + String effectiveUrl = '' + String divStyle = 'width:100%;height:1000px;' + + /** + * Sets the display name for the portlet. Defaults to {@code 'Iframe Portlet'}. + */ + void displayName(String displayName) { + this.displayName = displayName + } + + /** + * Sets the iframe source for portlet. Defaults is empty. + */ + void iframeSource(String iframeSource) { + this.iframeSource = iframeSource + } + + /** + * Sets the effective source for portlet. Defaults is empty. + */ + void effectiveSource(String effectiveSource) { + this.effectiveSource = effectiveSource + } + + /** + * Sets the effective url for portlet. Defaults is empty. + */ + void effectiveUrl(String effectiveUrl) { + this.effectiveUrl = effectiveUrl + } + + /** + * Sets the div style for portlet. Defaults to {@code 'width:100%;height:1000px;'}. + */ + void divStyle(String divStyle) { + this.divStyle = divStyle + } +} diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/JenkinsJobsListContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/JenkinsJobsListContext.groovy new file mode 100644 index 000000000..69195fa8e --- /dev/null +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/JenkinsJobsListContext.groovy @@ -0,0 +1,14 @@ +package javaposse.jobdsl.dsl.views.portlets + +import javaposse.jobdsl.dsl.Context + +class JenkinsJobsListContext implements Context { + String displayName = 'Jenkins Jobs List' + + /** + * Sets the display name for the portlet. Defaults to {@code 'Jenkins Jobs List'}. + */ + void displayName(String displayName) { + this.displayName = displayName + } +} diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/TestTrendChartContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/TestTrendChartContext.groovy new file mode 100644 index 000000000..da79afc46 --- /dev/null +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/views/portlets/TestTrendChartContext.groovy @@ -0,0 +1,56 @@ +package javaposse.jobdsl.dsl.views.portlets + +import javaposse.jobdsl.dsl.Context +import javaposse.jobdsl.dsl.views.DashboardView.DisplayStatus + +class TestTrendChartContext implements Context { + + String displayName = 'Test Trend Chart' + Integer graphWidth = 300 + Integer graphHeight = 200 + Integer dateRange = 30 + Integer dateShift = 0 + DisplayStatus displayStatus = DisplayStatus.ALL + + /** + * Sets the display name for the portlet. Defaults to {@code 'Test Trend Chart'}. + */ + void displayName(String displayName) { + this.displayName = displayName + } + + /** + * Sets the graph width for the this portlet. Defaults to {@code '300'}. + */ + void graphWidth(Integer graphWidth) { + this.graphWidth = graphWidth + } + + /** + * Sets the graph height for this portlet. Defaults to {@code '200'} + */ + void graphHeight(Integer graphHeight) { + this.graphHeight = graphHeight + } + + /** + * Sets the date range for thies portlet. Defaults to {@code '0'} + */ + void dateRange(Integer dateRange) { + this.dateRange = dateRange + } + + /** + * Sets the date shift for this portlet. Defaults to {@code '0'} + */ + void dateShift(Integer dateShift) { + this.dateShift = dateShift + } + + /** + * Sets the display status for this portlet. Defaults to {@code DisplayStatus.ALL}. + */ + void displayStatus(DisplayStatus displayStatus) { + this.displayStatus = displayStatus + } +} diff --git a/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/views/DashboardViewSpec.groovy b/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/views/DashboardViewSpec.groovy index 01a31aff0..6e26f6d5d 100644 --- a/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/views/DashboardViewSpec.groovy +++ b/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/views/DashboardViewSpec.groovy @@ -22,6 +22,114 @@ class DashboardViewSpec extends ListViewSpec { position << ['topPortlets', 'bottomPortlets', 'leftPortlets', 'rightPortlets'] } + def 'test build statistics with no options'() { + when: + view.topPortlets { + buildStatistics() + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.stats.StatBuilds' + children().size() == 2 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'Build statistics' + } + } + + def 'test build statistics with all options'() { + when: + view.topPortlets { + buildStatistics { + displayName('bar') + } + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.stats.StatBuilds' + children().size() == 2 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'bar' + } + } + + def 'test iframe with no options'() { + when: + view.topPortlets { + iframe() + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.core.IframePortlet' + children().size() == 6 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'Iframe Portlet' + iframeSource[0].value() == '' + effectiveSource[0].value() == '' + effectiveUrl[0].value() == '' + divStyle[0].value() == 'width:100%;height:1000px;' + } + } + + def 'test iframe with all options'() { + when: + view.topPortlets { + iframe { + displayName('bar') + iframeSource('one') + effectiveSource('two') + effectiveUrl('three') + divStyle('four') + } + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.core.IframePortlet' + children().size() == 6 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'bar' + iframeSource[0].value() == 'one' + effectiveSource[0].value() == 'two' + effectiveUrl[0].value() == 'three' + divStyle[0].value() == 'four' + } + } + + def 'test jenkins jobs list with no options'() { + when: + view.topPortlets { + jenkinsJobsList() + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.core.HudsonStdJobsPortlet' + children().size() == 2 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'Jenkins Jobs List' + } + } + + def 'test jenkins jobs list with all options'() { + when: + view.topPortlets { + jenkinsJobsList { + displayName('bar') + } + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.core.HudsonStdJobsPortlet' + children().size() == 2 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'bar' + } + } + def 'test statistics chart with no options'() { when: view.topPortlets { @@ -97,6 +205,53 @@ class DashboardViewSpec extends ListViewSpec { } } + def 'test trend chart with no options'() { + when: + view.topPortlets { + testTrendChart() + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.test.TestTrendChart' + children().size() == 7 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'Test Trend Chart' + graphWidth[0].value() == 300 + graphHeight[0].value() == 200 + dateRange[0].value() == 30 + dateShift[0].value() == 0 + displayStatus[0].value() == DashboardView.DisplayStatus.ALL + } + } + + def 'test trend chart with all options'() { + when: + view.topPortlets { + testTrendChart { + displayName('bar') + graphWidth(100) + graphHeight(200) + dateRange(7) + dateShift(1) + displayStatus(DashboardView.DisplayStatus.SUCCESS) + } + } + + then: + with(view.node.topPortlets[0].children()[0]) { + name() == 'hudson.plugins.view.dashboard.test.TestTrendChart' + children().size() == 7 + id[0].value() ==~ /dashboard_portlet_\d+/ + name[0].value() == 'bar' + graphWidth[0].value() == 100 + graphHeight[0].value() == 200 + dateRange[0].value() == 7 + dateShift[0].value() == 1 + displayStatus[0].value() == DashboardView.DisplayStatus.SUCCESS + } + } + protected String getDefaultXml() { '''