Skip to content

Commit

Permalink
Merge pull request #1075 from daspilker/JENKINS-44256
Browse files Browse the repository at this point in the history
[JENKINS-44256] enhanced support for the Groovy plugin
  • Loading branch information
daspilker committed Oct 19, 2017
2 parents b2c93e1 + 099b8f8 commit b3a34b5
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ 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))
* Support for the older versions of the [Groovy Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin) is
deprecated, see [Migration](Migration#migrating-to-167)
* 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
7 changes: 7 additions & 0 deletions docs/Migration.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## Migrating to 1.67

### Groovy Plugin

Support for versions older than 2.0 of the [Groovy Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin) is
[[deprecated|Deprecation-Policy]] and will be removed.

## Migrating to 1.66

### Notification
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 All @@ -359,6 +359,8 @@ class StepContext extends AbstractExtensibleContext {
}

protected groovy(String commandOrFileName, boolean isCommand, String groovyInstallation, Closure groovyClosure) {
jobManagement.logPluginDeprecationWarning('groovy', '2.0')

GroovyContext groovyContext = new GroovyContext()
ContextHelper.executeInContext(groovyClosure, groovyContext)

Expand All @@ -379,27 +381,66 @@ 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) {
jobManagement.logPluginDeprecationWarning('groovy', '2.0')

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)
}
jobManagement.logPluginDeprecationWarning('groovy', '2.0')

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 @@ -780,6 +780,7 @@ class StepContextSpec extends Specification {
scriptSourceNode.command.size() == 1
scriptSourceNode.command[0].value() == "println 'Hello World!'"
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')

when:
context.groovyCommand('acme.Acme.doSomething()', 'Groovy 2.0') {
Expand Down Expand Up @@ -817,6 +818,7 @@ class StepContextSpec extends Specification {
acmeScriptSourceNode.command.size() == 1
acmeScriptSourceNode.command[0].value() == 'acme.Acme.doSomething()'
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')
}

def 'call groovyScriptFile methods'() {
Expand Down Expand Up @@ -845,6 +847,7 @@ class StepContextSpec extends Specification {
scriptSourceNode.scriptFile.size() == 1
scriptSourceNode.scriptFile[0].value() == 'scripts/hello.groovy'
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')

when:
context.groovyScriptFile('acme.groovy', 'Groovy 2.0') {
Expand Down Expand Up @@ -894,6 +897,7 @@ class StepContextSpec extends Specification {
groovy21Node.groovyName.size() == 1
groovy21Node.groovyName[0].value() == 'Groovy 2.1'
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')
}

def 'call systemGroovyCommand methods'() {
Expand All @@ -914,6 +918,7 @@ class StepContextSpec extends Specification {
scriptSourceNode.command.size() == 1
scriptSourceNode.command[0].value() == "println 'Hello World!'"
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')

when:
context.systemGroovyCommand('acme.Acme.doSomething()') {
Expand All @@ -937,6 +942,7 @@ class StepContextSpec extends Specification {
acmeScriptSourceNode.command.size() == 1
acmeScriptSourceNode.command[0].value() == 'acme.Acme.doSomething()'
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')
}

def 'call systemGroovyScriptFile methods'() {
Expand All @@ -957,6 +963,7 @@ class StepContextSpec extends Specification {
scriptSourceNode.scriptFile.size() == 1
scriptSourceNode.scriptFile[0].value() == 'scripts/hello.groovy'
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')

when:
context.systemGroovyScriptFile('acme.groovy') {
Expand All @@ -980,6 +987,127 @@ class StepContextSpec extends Specification {
acmeScriptSourceNode.scriptFile.size() == 1
acmeScriptSourceNode.scriptFile[0].value() == 'acme.groovy'
1 * jobManagement.requirePlugin('groovy')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')
}

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')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')

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')
1 * jobManagement.logPluginDeprecationWarning('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')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')

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')
1 * jobManagement.logPluginDeprecationWarning('groovy', '2.0')
}

def 'call copyArtifacts selector variants'() {
Expand Down

0 comments on commit b3a34b5

Please sign in to comment.