Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class InterceptingGCL extends GroovyClassLoader {
metaClazz.invokeMethod = helper.getMethodInterceptor()
metaClazz.static.invokeMethod = helper.getMethodInterceptor()
metaClazz.methodMissing = helper.getMethodMissingInterceptor()
metaClazz.getEnv = {return binding.env}
metaClazz.propertyMissing = helper.getPropertyMissingInterceptor()
metaClazz.getEnv = { return binding.env }
// find and replace script method closure with any matching allowed method closure
metaClazz.methods.forEach { scriptMethod ->
def signature = method(scriptMethod.name, scriptMethod.nativeParameterTypes)
Expand Down Expand Up @@ -66,11 +67,8 @@ class InterceptingGCL extends GroovyClassLoader {
return super.loadClass(name)
}

// Copy from this.parseClass(GroovyCodeSource, boolean)
cls.metaClass.invokeMethod = helper.getMethodInterceptor()
cls.metaClass.static.invokeMethod = helper.getMethodInterceptor()
cls.metaClass.methodMissing = helper.getMethodMissingInterceptor()
interceptClassMethods(cls.metaClass, helper, binding)

return cls;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ class PipelineTestHelper {
return callClosure(intercepted.value, args)
}
// if not search for the method declaration
MetaMethod m = delegate.metaClass.getMetaMethod(name, args)
MetaMethod metaMethod = delegate.metaClass.getMetaMethod(name, args)
// ...and call it. If we cannot find it, delegate call to methodMissing
def result = (m ? this.callMethod(m, delegate, args) : delegate.metaClass.invokeMissingMethod(delegate, name, args))
def result = (metaMethod ? this.callMethod(metaMethod, delegate, args) : delegate.metaClass.invokeMissingMethod(delegate, name, args))
return result
}

Expand Down Expand Up @@ -234,6 +234,20 @@ class PipelineTestHelper {
return methodMissingInterceptor
}

def propertyMissingInterceptor = { String propertyName ->
if (binding.hasVariable("params") && (binding.getVariable("params") as Map).containsKey(propertyName)) {
return (binding.getVariable("params") as Map).get(propertyName)
}
if (binding.getVariable("env") && (binding.getVariable("env") as Map).containsKey(propertyName)) {
return (binding.getVariable("env") as Map).get(propertyName)
}
throw new MissingPropertyException(propertyName)
}

def getPropertyMissingInterceptor() {
return propertyMissingInterceptor
}

def callIfClosure(Object closure, Object currentResult) {
if (closure instanceof Closure) {
currentResult = callClosure(closure)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import com.lesfurets.jenkins.unit.declarative.agent.DockerAgentDeclaration
import com.lesfurets.jenkins.unit.declarative.agent.KubernetesAgentDeclaration
import groovy.transform.ToString

import static groovy.lang.Closure.DELEGATE_FIRST
import static com.lesfurets.jenkins.unit.declarative.GenericPipelineDeclaration.executeWith

@ToString(includePackage = false, includeNames = true, ignoreNulls = true)
class AgentDeclaration extends GenericPipelineDeclaration {
class AgentDeclaration {

String label
DockerAgentDeclaration docker
Expand All @@ -16,13 +16,12 @@ class AgentDeclaration extends GenericPipelineDeclaration {
String dockerfileDir
Boolean reuseNode = null
String customWorkspace
def binding = null

def label(String label) {
this.label = label
}

def node(@DelegatesTo(AgentDeclaration) Closure closure) {
def node(Closure closure) {
closure.call()
}

Expand All @@ -35,46 +34,37 @@ class AgentDeclaration extends GenericPipelineDeclaration {
}

def docker(String image) {
this.docker = new DockerAgentDeclaration().with { it.image = image; it }
this.docker = new DockerAgentDeclaration().with{ da -> da.image = image; da }
}

def docker(@DelegatesTo(strategy = DELEGATE_FIRST, value = DockerAgentDeclaration) Closure closure) {
this.docker = createComponent(DockerAgentDeclaration, closure)
def docker(Closure closure) {
this.docker = new DockerAgentDeclaration();
executeWith(this.docker, closure);
}

def kubernetes(Object kubernetesAgent) {
this.@kubernetes = kubernetesAgent as KubernetesAgentDeclaration
}

def kubernetes(@DelegatesTo(strategy = DELEGATE_FIRST, value = KubernetesAgentDeclaration) Closure closure) {
this.@kubernetes = createComponent(KubernetesAgentDeclaration, closure)
def kubernetes(Closure closure) {
this.@kubernetes = new KubernetesAgentDeclaration();
def kubernetesDecl = this.@kubernetes
executeWith(kubernetesDecl, closure, Closure.DELEGATE_FIRST)
}

def dockerfile(boolean dockerfile) {
this.dockerfile = dockerfile
}

def dockerfile(@DelegatesTo(AgentDeclaration) Closure closure) {
def dockerfile(Closure closure) {
closure.call()
}

def dir(String dir) {
this.dockerfileDir = dir
}

def getCurrentBuild() {
return binding?.currentBuild
}

def getEnv() {
return binding?.env
}

def getParams() {
return binding?.params
}

def execute(Object delegate) {
def execute(Script script) {
def agentDesc = null

if (label) {
Expand All @@ -95,6 +85,6 @@ class AgentDeclaration extends GenericPipelineDeclaration {
else {
throw new IllegalStateException("No agent description found")
}
executeWith(delegate, { echo "Executing on agent $agentDesc" })
executeWith(script, { echo "Executing on agent $agentDesc" })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package com.lesfurets.jenkins.unit.declarative

import org.springframework.util.AntPathMatcher

import static groovy.lang.Closure.DELEGATE_FIRST
import static com.lesfurets.jenkins.unit.declarative.GenericPipelineDeclaration.executeWith

class AllOfDeclaration extends WhenDeclaration {

List<String> branches = []
List<Boolean> expressions = []
List<Closure> expressions = []
List<AnyOfDeclaration> anyOfs = []

def branch(String name) {
Expand All @@ -18,35 +18,29 @@ class AllOfDeclaration extends WhenDeclaration {
this.expressions.add(closure)
}

def anyOf(@DelegatesTo(strategy = DELEGATE_FIRST, value = AnyOfDeclaration) Closure closure) {
this.anyOfs.add(createComponent(AnyOfDeclaration, closure))
def anyOf(Closure closure) {
AnyOfDeclaration anyOfDeclaration = new AnyOfDeclaration();
this.anyOfs.add(anyOfDeclaration)
executeWith(anyOfDeclaration, closure, Closure.DELEGATE_FIRST)
}

def expressions(Object delegate) {
return this.expressions.collect {executeWith(delegate, it)}.every()
}

def anyOf(Object delegate) {
return this.anyOfs.collect {it.execute(delegate)}
}

Boolean execute(Object delegate) {
def results = []
Boolean execute(Script script) {
List<Boolean> results = []

AntPathMatcher antPathMatcher = new AntPathMatcher()

if (this.branches.size() > 0) {
branches.each { branch ->
results.add(antPathMatcher.match(branch, delegate.env.BRANCH_NAME))
results.add(antPathMatcher.match(branch, script.env.BRANCH_NAME))
}
}

if (this.expressions.size() > 0) {
results.add(expressions(delegate))
results.add(this.expressions.collect { executeWith(script, it) }.every())
}

if (this.anyOfs.size() > 0) {
results.addAll(anyOf(delegate))
results.addAll(this.anyOfs.collect {it.execute(script)})
}

return results.every()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package com.lesfurets.jenkins.unit.declarative

import static com.lesfurets.jenkins.unit.declarative.GenericPipelineDeclaration.executeWith
import org.springframework.util.AntPathMatcher

import static groovy.lang.Closure.DELEGATE_FIRST

import static com.lesfurets.jenkins.unit.declarative.GenericPipelineDeclaration.executeWith

class AnyOfDeclaration extends WhenDeclaration {

List<String> tags = []
List<String> branches = []
List<Boolean> expressions = []
List<Closure> expressions = []
List<AllOfDeclaration> allOfs = []

def tag(String name) {
Expand All @@ -25,41 +23,35 @@ class AnyOfDeclaration extends WhenDeclaration {
this.expressions.add(closure)
}

def allOf(@DelegatesTo(strategy = DELEGATE_FIRST, value = AllOfDeclaration) Closure closure) {
this.allOfs.add(createComponent(AllOfDeclaration, closure))
}

def allOf(Object delegate) {
return this.allOfs.collect {it.execute(delegate)}
}

def expressions(Object delegate) {
return this.expressions.collect {executeWith(delegate, it)}.any()
def allOf(Closure closure) {
AllOfDeclaration allOfDeclaration = new AllOfDeclaration();
this.allOfs.add(allOfDeclaration)
executeWith(allOfDeclaration, closure, Closure.DELEGATE_FIRST)
}

Boolean execute(Object delegate) {
Boolean execute(Script script) {
def results = []

AntPathMatcher antPathMatcher = new AntPathMatcher()

if (this.tags.size() > 0) {
tags.each { tag ->
results.add(antPathMatcher.match(tag, delegate.env.TAG_NAME))
results.add(antPathMatcher.match(tag, script.env.TAG_NAME))
}
}

if (this.branches.size() > 0) {
branches.each { branch ->
results.add(antPathMatcher.match(branch, delegate.env.BRANCH_NAME))
results.add(antPathMatcher.match(branch, script.env.BRANCH_NAME))
}
}

if (this.expressions.size() > 0) {
results.add(expressions(delegate))
results.add(this.expressions.collect {executeWith(delegate, it)}.any())
}

if (this.allOfs.size() > 0) {
results.addAll(allOf(delegate))
results.addAll(this.allOfs.collect {it.execute(script)})
}

return results.any()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.lesfurets.jenkins.unit.declarative

import static groovy.lang.Closure.*

class DeclarativePipeline extends GenericPipelineDeclaration {

def properties = [:]
List<Closure> options = []

Closure triggers
ParametersDeclaration params = null
ParametersDeclaration parameters = null

DeclarativePipeline() {
properties.put('any', 'any')
Expand All @@ -24,37 +22,37 @@ class DeclarativePipeline extends GenericPipelineDeclaration {
}
}

def propertyMissing(String name, arg) {

}

def options(@DelegatesTo(DeclarativePipeline) Closure closure) {
def options(Closure closure) {
options.add(closure)
}

def triggers(@DelegatesTo(DeclarativePipeline) Closure closure) {
def triggers(Closure closure) {
this.triggers = closure
}

def parameters(Object o) {
this.params = new ParametersDeclaration().with { it.label = o; it }
this.parameters = new ParametersDeclaration().with { it.label = o; it }
}

def parameters(@DelegatesTo(strategy=DELEGATE_FIRST, value=ParametersDeclaration) Closure closure) {
this.params = createComponent(ParametersDeclaration, closure)
def parameters(Closure closure) {
this.parameters = new ParametersDeclaration()
this.parameters.binding = closure.binding;
executeWith(this.parameters, closure)
}

def execute(Object delegate) {
super.execute(delegate)
def execute(Script script) {
super.execute(script)
this.options.forEach {
executeOn(delegate, it)
executeWith(script, it)
}
this.agent?.execute(script)
if (this.triggers) {
executeWith(script, this.triggers)
}
this.agent?.execute(delegate)
executeOn(delegate, this.triggers)
this.stages.entrySet().forEach { e ->
e.value.execute(delegate)
e.value.execute(script)
}
this.post?.execute(delegate)
this.post?.execute(script)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ import static com.lesfurets.jenkins.unit.MethodSignature.method
abstract class DeclarativePipelineTest extends BasePipelineTest {

def pipelineInterceptor = { Closure closure ->
GenericPipelineDeclaration.binding = binding
GenericPipelineDeclaration.createComponent(DeclarativePipeline, closure).execute(delegate)
def declarativePipeline = new DeclarativePipeline()
def rehydratedPipelineCl = closure.rehydrate(declarativePipeline, closure.owner, closure)
rehydratedPipelineCl.resolveStrategy
rehydratedPipelineCl.call();
declarativePipeline.execute(closure.owner)
}

def paramInterceptor = { Map desc ->
addParam(desc.name, desc.defaultValue, false)
}

def stringInterceptor = { Map desc->
def stringInterceptor = { Map desc ->
if (desc) {
// we are in context of parameters { string(...)}
if (desc.name) {
Expand Down
Loading