Skip to content

Commit c2903ba

Browse files
committed
Merge branch 'plotplugin'
Conflicts: job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/helpers/publisher/PublisherContextSpec.groovy
2 parents 105ee6d + b2e4131 commit c2903ba

File tree

7 files changed

+319
-0
lines changed

7 files changed

+319
-0
lines changed

docs/Home.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Have a look at the [Jenkins Job DSL Gradle example](https://github.com/sheehan/j
2323
* Added `ignorePostCommitHooks` option for SCM trigger
2424
* Added support for [PostBuildScript Plugin](https://wiki.jenkins-ci.org/display/JENKINS/PostBuildScript+Plugin)
2525
* The enum argument of `localRepository` for the Maven job and context has changed, see [[Migration]]
26+
* Added partial support for [Plot Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Plot+Plugin)
2627
* 1.30 (March 08 2015)
2728
* Added support for [Custom Tools Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Custom+Tools+Plugin)
2829
* Added support for [Flaky Test Handler Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Flaky+Test+Handler+Plugin)

docs/Job-reference.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ freeStyleJob(String name) { // since 1.30
227227
mailer(String recipients, Boolean dontNotifyEveryUnstableBuild = false,
228228
Boolean sendToIndividuals = false)
229229
mavenDeploymentLinker(String regex) // since 1.23
230+
plotBuildData(Closure closure) // since 1.31
230231
pmd(String pattern, Closure staticAnalysisClosure = null)
231232
postBuildScripts(Closure postBuildScriptsClosure) // since 1.31
232233
postBuildTask(Closure closure) // since 1.19
@@ -3826,6 +3827,60 @@ The arguments here are in order:
38263827
* (String) the findbugs-files to parse
38273828
* (boolean) use the findbugs rank for the priority, default to false
38283829
3830+
#### Plot Build Data
3831+
3832+
```groovy
3833+
job {
3834+
publishers {
3835+
plotBuildData {
3836+
plot(String group, String dataStore) {
3837+
style(String style) // defaults to 'line'
3838+
propertiesFile(String fileName) {
3839+
label(String label)
3840+
}
3841+
}
3842+
}
3843+
}
3844+
}
3845+
```
3846+
3847+
Show a number of plots, each containing a single data series. Requires the
3848+
[Plot Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Plot+Plugin).
3849+
3850+
Plot plugin relies on a data store to hold the plot data, this is normally stored in a randomly named CSV file within
3851+
the workspace root. To avoid conflicts this location needs to be set manually relative to the workspace using the
3852+
`dataStore` parameter.
3853+
3854+
The `style` option can be one of `'area'`, `'bar'`, `'bar3d'`, `'line'` (default), `'line3d'`, `'stackedArea'`,
3855+
`'stackedbar'`, `'stackedbar3d'` or `'waterfall'`.
3856+
3857+
```groovy
3858+
job {
3859+
publishers {
3860+
plotBuildData {
3861+
plot('Important Plot', 'my_data_store.csv') {
3862+
propertiesFile('my_data.properties')
3863+
}
3864+
}
3865+
}
3866+
}
3867+
3868+
job {
3869+
publishers {
3870+
plotBuildData {
3871+
plot('Bar Charts', 'bar_chart_data_store.csv') {
3872+
style('bar')
3873+
propertiesFile('my_data.properties') {
3874+
label('My Label')
3875+
}
3876+
}
3877+
}
3878+
}
3879+
}
3880+
```
3881+
3882+
(since 1.31)
3883+
38293884
#### [Pmd](https://wiki.jenkins-ci.org/display/JENKINS/PMD+Plugin)
38303885
```groovy
38313886
publishers {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package javaposse.jobdsl.dsl.helpers.publisher
2+
3+
import com.google.common.base.Strings
4+
import javaposse.jobdsl.dsl.ContextHelper
5+
import javaposse.jobdsl.dsl.Context
6+
7+
import static com.google.common.base.Preconditions.checkArgument
8+
9+
class PlotContext implements Context {
10+
private static final List<String> STYLE = [
11+
'area', 'bar', 'bar3d', 'line', 'line3d', 'stackedArea', 'stackedbar', 'stackedbar3d', 'waterfall'
12+
]
13+
14+
final String group
15+
final String dataStore
16+
final List<PlotSeriesContext> dataSeriesList = []
17+
String style = 'line'
18+
19+
PlotContext(String group, String dataStore) {
20+
this.group = group
21+
this.dataStore = dataStore
22+
}
23+
24+
void style(String style) {
25+
checkArgument(STYLE.contains(style), "style must be one of ${STYLE.join(', ')}")
26+
this.style = style
27+
}
28+
29+
void propertiesFile(String fileName, Closure plotSeriesClosure = null) {
30+
checkArgument(!Strings.isNullOrEmpty(fileName), 'fileName must not be null or empty')
31+
32+
PlotSeriesContext plotSeriesContext = new PlotSeriesContext(fileName)
33+
ContextHelper.executeInContext(plotSeriesClosure, plotSeriesContext)
34+
35+
dataSeriesList << plotSeriesContext
36+
}
37+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package javaposse.jobdsl.dsl.helpers.publisher
2+
3+
import javaposse.jobdsl.dsl.Context
4+
5+
class PlotSeriesContext implements Context {
6+
final String fileName
7+
String label
8+
9+
PlotSeriesContext(String fileName) {
10+
this.fileName = fileName
11+
}
12+
13+
void label(String label) {
14+
this.label = label
15+
}
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package javaposse.jobdsl.dsl.helpers.publisher
2+
3+
import com.google.common.base.Preconditions
4+
import com.google.common.base.Strings
5+
import javaposse.jobdsl.dsl.ContextHelper
6+
import javaposse.jobdsl.dsl.Context
7+
8+
class PlotsContext implements Context {
9+
final List<PlotContext> plots = []
10+
11+
void plot(String group, String dataStore, Closure plotClosure) {
12+
Preconditions.checkArgument(!Strings.isNullOrEmpty(group), 'group must not be null or empty')
13+
Preconditions.checkArgument(!Strings.isNullOrEmpty(dataStore), 'dataStore must not be null or empty')
14+
15+
PlotContext plotContext = new PlotContext(group, dataStore)
16+
ContextHelper.executeInContext(plotClosure, plotContext)
17+
18+
plots << plotContext
19+
}
20+
}

job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/publisher/PublisherContext.groovy

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,64 @@ class PublisherContext implements Context {
336336
publisherNodes << jacocoNode
337337
}
338338

339+
/**
340+
* <hudson.plugins.plot.PlotPublisher>
341+
* <plots>
342+
* <hudson.plugins.plot.Plot>
343+
* <title/>
344+
* <yaxis/>
345+
* <series>
346+
* <hudson.plugins.plot.PropertiesSeries>
347+
* <file>test.properties</file>
348+
* <label>test</label>
349+
* <fileType>properties</fileType>
350+
* </hudson.plugins.plot.PropertiesSeries>
351+
* </series>
352+
* <group>test</group>
353+
* <numBuilds/>
354+
* <csvFileName>744827576.csv</csvFileName>
355+
* <csvLastModification>0</csvLastModification>
356+
* <style>line</style>
357+
* <useDescr>false</useDescr>
358+
* <keepRecords>false</keepRecords>
359+
* <exclZero>false</exclZero>
360+
* </hudson.plugins.plot.Plot>
361+
* </plots>
362+
* </hudson.plugins.plot.PlotPublisher>
363+
*/
364+
void plotBuildData(Closure plotsClosure) {
365+
PlotsContext plotsContext = new PlotsContext()
366+
ContextHelper.executeInContext(plotsClosure, plotsContext)
367+
368+
publisherNodes << NodeBuilder.newInstance().'hudson.plugins.plot.PlotPublisher' {
369+
plots {
370+
plotsContext.plots.each { PlotContext plot ->
371+
'hudson.plugins.plot.Plot' {
372+
title()
373+
yaxis()
374+
series {
375+
plot.dataSeriesList.each { PlotSeriesContext data ->
376+
'hudson.plugins.plot.PropertiesSeries' {
377+
file(data.fileName)
378+
label(data.label ?: '')
379+
fileType('properties')
380+
}
381+
}
382+
}
383+
group(plot.group)
384+
numBuilds()
385+
csvFileName(plot.dataStore)
386+
csvLastModification(0)
387+
style(plot.style)
388+
usrDescr(false)
389+
keepRecords(false)
390+
exclZero(false)
391+
}
392+
}
393+
}
394+
}
395+
}
396+
339397
/**
340398
* <htmlpublisher.HtmlPublisher>
341399
* <reportTargets>

job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/helpers/publisher/PublisherContextSpec.groovy

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,4 +3080,136 @@ class PublisherContextSpec extends Specification {
30803080
triggers[0].envVar[0].value() == 'FOO'
30813081
}
30823082
}
3083+
3084+
def 'call plotPlugin with some basic args'() {
3085+
when:
3086+
context.plotBuildData {
3087+
plot('my group', 'some.csv') {
3088+
propertiesFile('data.prop')
3089+
}
3090+
}
3091+
3092+
then:
3093+
with(context.publisherNodes[0]) {
3094+
name() == 'hudson.plugins.plot.PlotPublisher'
3095+
children().size() == 1
3096+
with(plots.'hudson.plugins.plot.Plot'[0]) {
3097+
children().size() == 11
3098+
title[0].value().empty
3099+
yaxis[0].value().empty
3100+
group[0].value() == 'my group'
3101+
numBuilds[0].value().empty
3102+
csvFileName[0].value() == 'some.csv'
3103+
csvLastModification[0].value() == 0
3104+
style[0].value() == 'line'
3105+
usrDescr[0].value() == false
3106+
keepRecords[0].value() == false
3107+
exclZero[0].value() == false
3108+
with(series[0].'hudson.plugins.plot.PropertiesSeries'[0]) {
3109+
children().size() == 3
3110+
file[0].value() == 'data.prop'
3111+
label[0].value() == ''
3112+
fileType[0].value() == 'properties'
3113+
}
3114+
}
3115+
}
3116+
}
3117+
3118+
def 'call plotPlugin with all chart styles'() {
3119+
when:
3120+
context.plotBuildData {
3121+
plot('my group', 'some.csv') {
3122+
style(chart)
3123+
propertiesFile('data.prop') {
3124+
label('some label')
3125+
}
3126+
}
3127+
}
3128+
3129+
then:
3130+
with(context.publisherNodes[0]) {
3131+
name() == 'hudson.plugins.plot.PlotPublisher'
3132+
children().size() == 1
3133+
with(plots.'hudson.plugins.plot.Plot'[0]) {
3134+
children().size() == 11
3135+
title[0].value().empty
3136+
yaxis[0].value().empty
3137+
group[0].value() == 'my group'
3138+
numBuilds[0].value().empty
3139+
csvFileName[0].value() == 'some.csv'
3140+
csvLastModification[0].value() == 0
3141+
style[0].value() == chart
3142+
usrDescr[0].value() == false
3143+
keepRecords[0].value() == false
3144+
exclZero[0].value() == false
3145+
with(series[0].'hudson.plugins.plot.PropertiesSeries'[0]) {
3146+
children().size() == 3
3147+
file[0].value() == 'data.prop'
3148+
label[0].value() == 'some label'
3149+
fileType[0].value() == 'properties'
3150+
}
3151+
}
3152+
}
3153+
3154+
where:
3155+
chart << ['area', 'bar', 'bar3d', 'line', 'line3d', 'stackedArea', 'stackedbar', 'stackedbar3d', 'waterfall']
3156+
}
3157+
3158+
def 'call plotPlugin without group'() {
3159+
when:
3160+
context.plotBuildData {
3161+
plot(group, 'some.csv') {
3162+
propertiesFile('data.prop')
3163+
}
3164+
}
3165+
3166+
then:
3167+
thrown(IllegalArgumentException)
3168+
3169+
where:
3170+
group << [null, '']
3171+
}
3172+
3173+
def 'call plotPlugin without data store'() {
3174+
when:
3175+
context.plotBuildData {
3176+
plot('my group', dataStore) {
3177+
propertiesFile('data.prop')
3178+
}
3179+
}
3180+
3181+
then:
3182+
thrown(IllegalArgumentException)
3183+
3184+
where:
3185+
dataStore << [null, '']
3186+
}
3187+
3188+
def 'call plotPlugin without file name'() {
3189+
when:
3190+
context.plotBuildData {
3191+
plot('my group', 'test.csv') {
3192+
propertiesFile(fileName)
3193+
}
3194+
}
3195+
3196+
then:
3197+
thrown(IllegalArgumentException)
3198+
3199+
where:
3200+
fileName << [null, '']
3201+
}
3202+
3203+
def 'call plotPlugin with invalid style'() {
3204+
when:
3205+
context.plotBuildData {
3206+
plot('my group', 'test.csv') {
3207+
style('foo')
3208+
propertiesFile('data.prop')
3209+
}
3210+
}
3211+
3212+
then:
3213+
thrown(IllegalArgumentException)
3214+
}
30833215
}

0 commit comments

Comments
 (0)