Skip to content

Commit

Permalink
Simplify class interception
Browse files Browse the repository at this point in the history
  • Loading branch information
Willem1987 committed Jun 7, 2021
1 parent 3ec1c0a commit e7360c8
Show file tree
Hide file tree
Showing 20 changed files with 262 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class InterceptingGCL extends GroovyClassLoader {
metaClazz.static.invokeMethod = helper.getMethodInterceptor()
metaClazz.methodMissing = helper.getMethodMissingInterceptor()
metaClazz.propertyMissing = helper.getPropertyMissingInterceptor()
metaClazz.getEnv = {return binding.env}
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 @@ -67,10 +67,7 @@ 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;
}
Expand Down
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import com.lesfurets.jenkins.unit.declarative.agent.DockerAgentDeclaration
import com.lesfurets.jenkins.unit.declarative.agent.KubernetesAgentDeclaration
import groovy.transform.ToString

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

@ToString(includePackage = false, includeNames = true, ignoreNulls = true)
class AgentDeclaration {
Expand All @@ -23,7 +21,7 @@ class AgentDeclaration {
this.label = label
}

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

Expand All @@ -36,34 +34,37 @@ class AgentDeclaration {
}

def docker(String image) {
this.docker({ -> this.image = image })
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 execute(Object delegate) {
def execute(Script script) {
def agentDesc = null

if (label) {
Expand All @@ -84,6 +85,6 @@ class AgentDeclaration {
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(delegate, it, Closure.DELEGATE_FIRST) }.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,7 +1,5 @@
package com.lesfurets.jenkins.unit.declarative

import static groovy.lang.Closure.*

class DeclarativePipeline extends GenericPipelineDeclaration {

def properties = [:]
Expand All @@ -24,33 +22,37 @@ class DeclarativePipeline extends GenericPipelineDeclaration {
}
}

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.parameters = new ParametersDeclaration().with { it.label = o; it }
}

def parameters(@DelegatesTo(strategy=DELEGATE_FIRST, value=ParametersDeclaration) Closure closure) {
this.parameters = 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 {
executeWith(delegate, it)
executeWith(script, it)
}
this.agent?.execute(script)
if (this.triggers) {
executeWith(script, this.triggers)
}
this.agent?.execute(delegate)
executeWith(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

0 comments on commit e7360c8

Please sign in to comment.