Skip to content

Commit ad8a750

Browse files
committed
enhanced support for the Groovy plugin
[FIXES JENKINS-44256]
1 parent b2c93e1 commit ad8a750

File tree

4 files changed

+199
-9
lines changed

4 files changed

+199
-9
lines changed

docs/Home.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Browse the Jenkins issue tracker to see any [open issues](https://issues.jenkins
2929

3030
## Release Notes
3131
* 1.67 (unreleased)
32+
* Enhanced support for the [Groovy Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin)
33+
([JENKINS-44256](https://issues.jenkins-ci.org/browse/JENKINS-44256))
3234
* 1.66 (October 14 2017)
3335
* Enhanced support for the [Notification Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Notification+Plugin)
3436
([#1067](https://github.com/jenkinsci/job-dsl-plugin/pull/1067))

job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/step/StepContext.groovy

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ class StepContext extends AbstractExtensibleContext {
348348
groovy(fileName, false, groovyName, groovyClosure)
349349
}
350350

351-
protected groovyScriptSource(String commandOrFileName, boolean isCommand) {
351+
protected Node groovyScriptSource(String commandOrFileName, boolean isCommand) {
352352
new NodeBuilder().scriptSource(class: "hudson.plugins.groovy.${isCommand ? 'String' : 'File'}ScriptSource") {
353353
if (isCommand) {
354354
command commandOrFileName
@@ -379,27 +379,62 @@ class StepContext extends AbstractExtensibleContext {
379379
* Executes a system Groovy script.
380380
*/
381381
@RequiresPlugin(id = 'groovy')
382-
void systemGroovyCommand(String command, @DslContext(SystemGroovyContext) Closure systemGroovyClosure = null) {
383-
systemGroovy(command, true, systemGroovyClosure)
382+
void systemGroovyCommand(String command, @DslContext(SystemGroovyCommandContext) Closure closure = null) {
383+
SystemGroovyCommandContext systemGroovyContext = new SystemGroovyCommandContext(jobManagement)
384+
ContextHelper.executeInContext(closure, systemGroovyContext)
385+
386+
Node systemGroovyNode = new NodeBuilder().'hudson.plugins.groovy.SystemGroovy' {
387+
bindings systemGroovyContext.bindings.collect { key, value -> "${key}=${value}" }.join('\n')
388+
if (!jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
389+
classpath systemGroovyContext.classpathEntries.join(File.pathSeparator)
390+
}
391+
}
392+
Node scriptSource
393+
if (jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
394+
scriptSource = new NodeBuilder().source(class: 'hudson.plugins.groovy.StringSystemScriptSource') {
395+
script {
396+
script(command)
397+
sandbox(systemGroovyContext.sandbox)
398+
classpath {
399+
systemGroovyContext.classpathEntries.each { path ->
400+
entry {
401+
url(path)
402+
}
403+
}
404+
}
405+
}
406+
}
407+
} else {
408+
scriptSource = groovyScriptSource(command, true)
409+
}
410+
systemGroovyNode.append(scriptSource)
411+
412+
stepNodes << systemGroovyNode
384413
}
385414

386415
/**
387416
* Executes a system Groovy script.
388417
*/
389418
@RequiresPlugin(id = 'groovy')
390419
void systemGroovyScriptFile(String fileName, @DslContext(SystemGroovyContext) Closure systemGroovyClosure = null) {
391-
systemGroovy(fileName, false, systemGroovyClosure)
392-
}
393-
394-
protected systemGroovy(String commandOrFileName, boolean isCommand, Closure systemGroovyClosure) {
395420
SystemGroovyContext systemGroovyContext = new SystemGroovyContext()
396421
ContextHelper.executeInContext(systemGroovyClosure, systemGroovyContext)
397422

398423
Node systemGroovyNode = new NodeBuilder().'hudson.plugins.groovy.SystemGroovy' {
399424
bindings systemGroovyContext.bindings.collect { key, value -> "${key}=${value}" }.join('\n')
400-
classpath systemGroovyContext.classpathEntries.join(File.pathSeparator)
425+
if (!jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
426+
classpath systemGroovyContext.classpathEntries.join(File.pathSeparator)
427+
}
428+
}
429+
Node scriptSource
430+
if (jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
431+
scriptSource = new NodeBuilder().source(class: 'hudson.plugins.groovy.FileSystemScriptSource') {
432+
scriptFile fileName
433+
}
434+
} else {
435+
scriptSource = groovyScriptSource(fileName, false)
401436
}
402-
systemGroovyNode.append(groovyScriptSource(commandOrFileName, isCommand))
437+
systemGroovyNode.append(scriptSource)
403438

404439
stepNodes << systemGroovyNode
405440
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package javaposse.jobdsl.dsl.helpers.step
2+
3+
import javaposse.jobdsl.dsl.DslScriptException
4+
import javaposse.jobdsl.dsl.JobManagement
5+
import javaposse.jobdsl.dsl.RequiresPlugin
6+
7+
class SystemGroovyCommandContext extends SystemGroovyContext {
8+
private final JobManagement jobManagement
9+
10+
boolean sandbox
11+
12+
SystemGroovyCommandContext(JobManagement jobManagement) {
13+
this.jobManagement = jobManagement
14+
}
15+
16+
/**
17+
* If set, run the Groovy script in a sandbox with limited abilities. Defaults to {@code false}.
18+
*
19+
* @since 1.67
20+
*/
21+
@RequiresPlugin(id = 'groovy', minimumVersion = '2.0')
22+
void sandbox(boolean sandbox = true) {
23+
this.sandbox = sandbox
24+
}
25+
26+
@Override
27+
void classpath(String classpath) {
28+
if (jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
29+
try {
30+
new URL(classpath)
31+
} catch (MalformedURLException e) {
32+
throw new DslScriptException("classpath must be a valid URL: ${e.message}")
33+
}
34+
}
35+
super.classpath(classpath)
36+
}
37+
}

job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/helpers/step/StepContextSpec.groovy

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,122 @@ class StepContextSpec extends Specification {
982982
1 * jobManagement.requirePlugin('groovy')
983983
}
984984

985+
def 'call systemGroovyCommand methods with plugin version 2.0'() {
986+
setup:
987+
jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0') >> true
988+
989+
when:
990+
context.systemGroovyCommand("println 'Hello World!'")
991+
992+
then:
993+
context.stepNodes.size() == 1
994+
with(context.stepNodes[0]) {
995+
name() == 'hudson.plugins.groovy.SystemGroovy'
996+
children().size() == 2
997+
bindings[0].value() == ''
998+
source.size() == 1
999+
with(source[0]) {
1000+
attribute('class') == 'hudson.plugins.groovy.StringSystemScriptSource'
1001+
children().size() == 1
1002+
script[0].children().size() == 3
1003+
script[0].script[0].value() == "println 'Hello World!'"
1004+
script[0].sandbox[0].value() == false
1005+
script[0].classpath[0].children().size() == 0
1006+
}
1007+
}
1008+
1 * jobManagement.requirePlugin('groovy')
1009+
1010+
when:
1011+
context.systemGroovyCommand('acme.Acme.doSomething()') {
1012+
binding('foo', 'bar')
1013+
binding('test', '0815')
1014+
classpath('file:/foo/acme.jar')
1015+
classpath('file:/foo/test.jar')
1016+
sandbox()
1017+
}
1018+
1019+
then:
1020+
context.stepNodes.size() == 2
1021+
with (context.stepNodes[1]) {
1022+
name() == 'hudson.plugins.groovy.SystemGroovy'
1023+
children().size() == 2
1024+
bindings[0].value() == 'foo=bar\ntest=0815'
1025+
with(source[0]) {
1026+
attribute('class') == 'hudson.plugins.groovy.StringSystemScriptSource'
1027+
children().size() == 1
1028+
script[0].children().size() == 3
1029+
script[0].script[0].value() == 'acme.Acme.doSomething()'
1030+
script[0].sandbox[0].value() == true
1031+
script[0].classpath[0].children().size() == 2
1032+
script[0].classpath[0].entry[0].children().size() == 1
1033+
script[0].classpath[0].entry[0].url[0].value() == 'file:/foo/acme.jar'
1034+
script[0].classpath[0].entry[1].children().size() == 1
1035+
script[0].classpath[0].entry[1].url[0].value() == 'file:/foo/test.jar'
1036+
}
1037+
}
1038+
1 * jobManagement.requirePlugin('groovy')
1039+
1 * jobManagement.requireMinimumPluginVersion('groovy', '2.0')
1040+
}
1041+
1042+
def 'call systemGroovyCommand with invalid classpath and plugin version 2.0'() {
1043+
setup:
1044+
jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0') >> true
1045+
1046+
when:
1047+
context.systemGroovyCommand('acme.Acme.doSomething()') {
1048+
classpath('/foo/acme.jar')
1049+
}
1050+
1051+
then:
1052+
thrown(DslScriptException)
1053+
}
1054+
1055+
def 'call systemGroovyScriptFile methods with plugin version 2.0'() {
1056+
setup:
1057+
jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0') >> true
1058+
1059+
when:
1060+
context.systemGroovyScriptFile('scripts/hello.groovy')
1061+
1062+
then:
1063+
context.stepNodes.size() == 1
1064+
with(context.stepNodes[0]) {
1065+
name() == 'hudson.plugins.groovy.SystemGroovy'
1066+
bindings.size() == 1
1067+
bindings[0].value() == ''
1068+
source.size() == 1
1069+
with(source[0]) {
1070+
attribute('class') == 'hudson.plugins.groovy.FileSystemScriptSource'
1071+
scriptFile.size() == 1
1072+
scriptFile[0].value() == 'scripts/hello.groovy'
1073+
}
1074+
}
1075+
1 * jobManagement.requirePlugin('groovy')
1076+
1077+
when:
1078+
context.systemGroovyScriptFile('acme.groovy') {
1079+
binding('foo', 'bar')
1080+
binding('test', '0815')
1081+
classpath('/foo/acme.jar')
1082+
classpath('/foo/test.jar')
1083+
}
1084+
1085+
then:
1086+
context.stepNodes.size() == 2
1087+
with(context.stepNodes[1]) {
1088+
name() == 'hudson.plugins.groovy.SystemGroovy'
1089+
bindings.size() == 1
1090+
bindings[0].value() == 'foo=bar\ntest=0815'
1091+
source.size() == 1
1092+
with(source[0]) {
1093+
attribute('class') == 'hudson.plugins.groovy.FileSystemScriptSource'
1094+
scriptFile.size() == 1
1095+
scriptFile[0].value() == 'acme.groovy'
1096+
}
1097+
}
1098+
1 * jobManagement.requirePlugin('groovy')
1099+
}
1100+
9851101
def 'call copyArtifacts selector variants'() {
9861102
when:
9871103
context.copyArtifacts('upstream') {

0 commit comments

Comments
 (0)