diff --git a/src/main/groovy/com/lesfurets/jenkins/unit/declarative/AgentDeclaration.groovy b/src/main/groovy/com/lesfurets/jenkins/unit/declarative/AgentDeclaration.groovy index 23c6137b..5dc75d1f 100644 --- a/src/main/groovy/com/lesfurets/jenkins/unit/declarative/AgentDeclaration.groovy +++ b/src/main/groovy/com/lesfurets/jenkins/unit/declarative/AgentDeclaration.groovy @@ -35,7 +35,7 @@ class AgentDeclaration extends GenericPipelineDeclaration { } def docker(String image) { - this.docker = new DockerAgentDeclaration().with { it.image = image; it } + this.docker({ -> owner.image = image }) } def docker(@DelegatesTo(strategy = DELEGATE_FIRST, value = DockerAgentDeclaration) Closure closure) { diff --git a/src/main/groovy/com/lesfurets/jenkins/unit/declarative/GenericPipelineDeclaration.groovy b/src/main/groovy/com/lesfurets/jenkins/unit/declarative/GenericPipelineDeclaration.groovy index 4300935c..9991fec2 100644 --- a/src/main/groovy/com/lesfurets/jenkins/unit/declarative/GenericPipelineDeclaration.groovy +++ b/src/main/groovy/com/lesfurets/jenkins/unit/declarative/GenericPipelineDeclaration.groovy @@ -14,7 +14,7 @@ abstract class GenericPipelineDeclaration { static T createComponent(Class componentType, @DelegatesTo(strategy = DELEGATE_FIRST) Closure closure) { // declare componentInstance as final to prevent any multithreaded issues, since it is used inside closure final def componentInstance = componentType.newInstance() - def rehydrate = closure.rehydrate(componentInstance, closure, componentInstance) + def rehydrate = closure.rehydrate(closure, componentInstance, closure.thisObject) if (binding && componentInstance.hasProperty('binding') && componentInstance.binding != binding) { componentInstance.binding = binding } @@ -24,20 +24,15 @@ abstract class GenericPipelineDeclaration { static T executeOn(@DelegatesTo.Target Object delegate, @DelegatesTo(strategy = DELEGATE_FIRST) Closure closure) { - if (closure) { - def cl = closure.rehydrate(delegate, delegate, delegate) - cl.resolveStrategy = DELEGATE_FIRST - return cl.call() - } - return null + return executeWith(delegate, closure) } static T executeWith(@DelegatesTo.Target Object delegate, @DelegatesTo(strategy = DELEGATE_FIRST) Closure closure) { if (closure) { - def cl = closure.rehydrate(delegate, delegate, delegate) - cl.resolveStrategy = DELEGATE_FIRST - return cl.call() + def rehydratedClosure = closure.rehydrate(closure, delegate, closure.thisObject) + rehydratedClosure.resolveStrategy = DELEGATE_FIRST + return rehydratedClosure.call() } return null } @@ -102,9 +97,9 @@ abstract class GenericPipelineDeclaration { env.env = env env.currentBuild = delegate.binding.currentBuild - def cl = this.environment.rehydrate(env, delegate, this) - cl.resolveStrategy = DELEGATE_FIRST - cl.call() + def rehydratedEnvClosure = this.environment.rehydrate(env, delegate, delegate) + rehydratedEnvClosure.resolveStrategy = DELEGATE_FIRST + rehydratedEnvClosure.call() } } diff --git a/src/main/groovy/com/lesfurets/jenkins/unit/declarative/StageDeclaration.groovy b/src/main/groovy/com/lesfurets/jenkins/unit/declarative/StageDeclaration.groovy index f3a38fd1..c27770f8 100644 --- a/src/main/groovy/com/lesfurets/jenkins/unit/declarative/StageDeclaration.groovy +++ b/src/main/groovy/com/lesfurets/jenkins/unit/declarative/StageDeclaration.groovy @@ -61,7 +61,7 @@ class StageDeclaration extends GenericPipelineDeclaration { e.value.execute(delegate) } if(steps) { - Closure stageBody = { agent?.execute(delegate) } >> steps.rehydrate(delegate, this, this) + Closure stageBody = { agent?.execute(delegate) } >> steps.rehydrate(delegate, this, delegate) Closure cl = { stage("$name", stageBody) } executeWith(delegate, cl) } diff --git a/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestDeclarativePipeline.groovy b/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestDeclarativePipeline.groovy index 6be725d7..f838b860 100644 --- a/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestDeclarativePipeline.groovy +++ b/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestDeclarativePipeline.groovy @@ -23,6 +23,14 @@ class TestDeclarativePipeline extends DeclarativePipelineTest { assertJobStatusSuccess() } + @Test void jenkinsfile_thisObject() throws Exception { + def script = runScript('Declarative_thisObject_JenkinsFile') + printCallStack() + assertJobStatusSuccess() + assertCallStack().doesNotContain("This is a script?: false") + assertCallStack().contains("This is a script?: true") + } + @Test void jenkinsfile_failure() throws Exception { helper.registerAllowedMethod('sh', [String.class], { String cmd -> updateBuildStatus('FAILURE') diff --git a/src/test/jenkins/jenkinsfiles/Declarative_thisObject_JenkinsFile b/src/test/jenkins/jenkinsfiles/Declarative_thisObject_JenkinsFile new file mode 100644 index 00000000..34c28762 --- /dev/null +++ b/src/test/jenkins/jenkinsfiles/Declarative_thisObject_JenkinsFile @@ -0,0 +1,50 @@ +pipeline { + + agent any + + environment { + CC = testThis(this, 'gcc') + } + + options { + buildDiscarder(logRotator(numToKeepStr: testThis(this, '10'))) + } + + triggers { + pollSCM(testThis(this, '*/5 * * * *')) + } + + stages { + stage('Checkout') { + when { + environment name: 'CC', value: testThis(this, 'clang') + } + steps { + echo testThis(this, "Steps") + } + } + + stage('build') { + agent { docker testThis(this, 'maven:3-alpine') } + options { + timeout(time: 20, unit: 'MINUTES') + } + steps { + withEnv(["GRADLE_HOME=${tool name: 'GRADLE_3', type: 'hudson.plugins.gradle.GradleInstallation'}"]) { + echo testThis(this, "In env") + } + } + } + } + + post { + always { + echo testThis(this, 'pipeline unit tests completed') + } + + } +} + +String testThis(Script scriptRef, String text){ + return "$text: This is a script?: ${this == scriptRef}" +} \ No newline at end of file