Skip to content

Commit

Permalink
enhanced support for the Groovy plugin
Browse files Browse the repository at this point in the history
[FIXES JENKINS-44256]
  • Loading branch information
daspilker committed Oct 18, 2017
1 parent b2c93e1 commit ad8a750
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 9 deletions.
2 changes: 2 additions & 0 deletions docs/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Browse the Jenkins issue tracker to see any [open issues](https://issues.jenkins

## Release Notes
* 1.67 (unreleased)
* Enhanced support for the [Groovy Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin)
([JENKINS-44256](https://issues.jenkins-ci.org/browse/JENKINS-44256))
* 1.66 (October 14 2017)
* Enhanced support for the [Notification Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Notification+Plugin)
([#1067](https://github.com/jenkinsci/job-dsl-plugin/pull/1067))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ class StepContext extends AbstractExtensibleContext {
groovy(fileName, false, groovyName, groovyClosure)
}

protected groovyScriptSource(String commandOrFileName, boolean isCommand) {
protected Node groovyScriptSource(String commandOrFileName, boolean isCommand) {
new NodeBuilder().scriptSource(class: "hudson.plugins.groovy.${isCommand ? 'String' : 'File'}ScriptSource") {
if (isCommand) {
command commandOrFileName
Expand Down Expand Up @@ -379,27 +379,62 @@ class StepContext extends AbstractExtensibleContext {
* Executes a system Groovy script.
*/
@RequiresPlugin(id = 'groovy')
void systemGroovyCommand(String command, @DslContext(SystemGroovyContext) Closure systemGroovyClosure = null) {
systemGroovy(command, true, systemGroovyClosure)
void systemGroovyCommand(String command, @DslContext(SystemGroovyCommandContext) Closure closure = null) {
SystemGroovyCommandContext systemGroovyContext = new SystemGroovyCommandContext(jobManagement)
ContextHelper.executeInContext(closure, systemGroovyContext)

Node systemGroovyNode = new NodeBuilder().'hudson.plugins.groovy.SystemGroovy' {
bindings systemGroovyContext.bindings.collect { key, value -> "${key}=${value}" }.join('\n')
if (!jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
classpath systemGroovyContext.classpathEntries.join(File.pathSeparator)
}
}
Node scriptSource
if (jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
scriptSource = new NodeBuilder().source(class: 'hudson.plugins.groovy.StringSystemScriptSource') {
script {
script(command)
sandbox(systemGroovyContext.sandbox)
classpath {
systemGroovyContext.classpathEntries.each { path ->
entry {
url(path)
}
}
}
}
}
} else {
scriptSource = groovyScriptSource(command, true)
}
systemGroovyNode.append(scriptSource)

stepNodes << systemGroovyNode
}

/**
* Executes a system Groovy script.
*/
@RequiresPlugin(id = 'groovy')
void systemGroovyScriptFile(String fileName, @DslContext(SystemGroovyContext) Closure systemGroovyClosure = null) {
systemGroovy(fileName, false, systemGroovyClosure)
}

protected systemGroovy(String commandOrFileName, boolean isCommand, Closure systemGroovyClosure) {
SystemGroovyContext systemGroovyContext = new SystemGroovyContext()
ContextHelper.executeInContext(systemGroovyClosure, systemGroovyContext)

Node systemGroovyNode = new NodeBuilder().'hudson.plugins.groovy.SystemGroovy' {
bindings systemGroovyContext.bindings.collect { key, value -> "${key}=${value}" }.join('\n')
classpath systemGroovyContext.classpathEntries.join(File.pathSeparator)
if (!jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
classpath systemGroovyContext.classpathEntries.join(File.pathSeparator)
}
}
Node scriptSource
if (jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
scriptSource = new NodeBuilder().source(class: 'hudson.plugins.groovy.FileSystemScriptSource') {
scriptFile fileName
}
} else {
scriptSource = groovyScriptSource(fileName, false)
}
systemGroovyNode.append(groovyScriptSource(commandOrFileName, isCommand))
systemGroovyNode.append(scriptSource)

stepNodes << systemGroovyNode
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package javaposse.jobdsl.dsl.helpers.step

import javaposse.jobdsl.dsl.DslScriptException
import javaposse.jobdsl.dsl.JobManagement
import javaposse.jobdsl.dsl.RequiresPlugin

class SystemGroovyCommandContext extends SystemGroovyContext {
private final JobManagement jobManagement

boolean sandbox

SystemGroovyCommandContext(JobManagement jobManagement) {
this.jobManagement = jobManagement
}

/**
* If set, run the Groovy script in a sandbox with limited abilities. Defaults to {@code false}.
*
* @since 1.67
*/
@RequiresPlugin(id = 'groovy', minimumVersion = '2.0')
void sandbox(boolean sandbox = true) {
this.sandbox = sandbox
}

@Override
void classpath(String classpath) {
if (jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0')) {
try {
new URL(classpath)
} catch (MalformedURLException e) {
throw new DslScriptException("classpath must be a valid URL: ${e.message}")
}
}
super.classpath(classpath)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,122 @@ class StepContextSpec extends Specification {
1 * jobManagement.requirePlugin('groovy')
}

def 'call systemGroovyCommand methods with plugin version 2.0'() {
setup:
jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0') >> true

when:
context.systemGroovyCommand("println 'Hello World!'")

then:
context.stepNodes.size() == 1
with(context.stepNodes[0]) {
name() == 'hudson.plugins.groovy.SystemGroovy'
children().size() == 2
bindings[0].value() == ''
source.size() == 1
with(source[0]) {
attribute('class') == 'hudson.plugins.groovy.StringSystemScriptSource'
children().size() == 1
script[0].children().size() == 3
script[0].script[0].value() == "println 'Hello World!'"
script[0].sandbox[0].value() == false
script[0].classpath[0].children().size() == 0
}
}
1 * jobManagement.requirePlugin('groovy')

when:
context.systemGroovyCommand('acme.Acme.doSomething()') {
binding('foo', 'bar')
binding('test', '0815')
classpath('file:/foo/acme.jar')
classpath('file:/foo/test.jar')
sandbox()
}

then:
context.stepNodes.size() == 2
with (context.stepNodes[1]) {
name() == 'hudson.plugins.groovy.SystemGroovy'
children().size() == 2
bindings[0].value() == 'foo=bar\ntest=0815'
with(source[0]) {
attribute('class') == 'hudson.plugins.groovy.StringSystemScriptSource'
children().size() == 1
script[0].children().size() == 3
script[0].script[0].value() == 'acme.Acme.doSomething()'
script[0].sandbox[0].value() == true
script[0].classpath[0].children().size() == 2
script[0].classpath[0].entry[0].children().size() == 1
script[0].classpath[0].entry[0].url[0].value() == 'file:/foo/acme.jar'
script[0].classpath[0].entry[1].children().size() == 1
script[0].classpath[0].entry[1].url[0].value() == 'file:/foo/test.jar'
}
}
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.requireMinimumPluginVersion('groovy', '2.0')
}

def 'call systemGroovyCommand with invalid classpath and plugin version 2.0'() {
setup:
jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0') >> true

when:
context.systemGroovyCommand('acme.Acme.doSomething()') {
classpath('/foo/acme.jar')
}

then:
thrown(DslScriptException)
}

def 'call systemGroovyScriptFile methods with plugin version 2.0'() {
setup:
jobManagement.isMinimumPluginVersionInstalled('groovy', '2.0') >> true

when:
context.systemGroovyScriptFile('scripts/hello.groovy')

then:
context.stepNodes.size() == 1
with(context.stepNodes[0]) {
name() == 'hudson.plugins.groovy.SystemGroovy'
bindings.size() == 1
bindings[0].value() == ''
source.size() == 1
with(source[0]) {
attribute('class') == 'hudson.plugins.groovy.FileSystemScriptSource'
scriptFile.size() == 1
scriptFile[0].value() == 'scripts/hello.groovy'
}
}
1 * jobManagement.requirePlugin('groovy')

when:
context.systemGroovyScriptFile('acme.groovy') {
binding('foo', 'bar')
binding('test', '0815')
classpath('/foo/acme.jar')
classpath('/foo/test.jar')
}

then:
context.stepNodes.size() == 2
with(context.stepNodes[1]) {
name() == 'hudson.plugins.groovy.SystemGroovy'
bindings.size() == 1
bindings[0].value() == 'foo=bar\ntest=0815'
source.size() == 1
with(source[0]) {
attribute('class') == 'hudson.plugins.groovy.FileSystemScriptSource'
scriptFile.size() == 1
scriptFile[0].value() == 'acme.groovy'
}
}
1 * jobManagement.requirePlugin('groovy')
}

def 'call copyArtifacts selector variants'() {
when:
context.copyArtifacts('upstream') {
Expand Down

0 comments on commit ad8a750

Please sign in to comment.