Hi.
I understand how you feel. I had no Groovy knowledge at the time I first wanted to get into JobDSL, and even now it's fairly cursory.
When you say 'the application', I guess that corresponds to your example class
MyApplication1. To give your application the wherewithal to apply configuration defined outside, you can pass it a closure and have that closure executed if/as appropriate:
class MyApplication1 {
static createDeploymentJob(dslFactory, arg1, arg2, externalConfiguration) {
def job = dslFactory.job {
name arg1
// etc
}
// Maybe do the following only if some condition holds...
job.with externalConfiguration
}
}and at the call site:
MyApplication1.createDeploymentJob(this, "some-name", "bla") {
description "description provided by call site"
}The latter snippet uses the fact that when the last parameter of a
method is a closure, you can provide its value using the syntax shown
above, with the closure outside the argument list brackets.
You could of course make
createDeploymentJob return a job, and assign that return value to a variable, then use
thatVariable.with - but you said you wanted
MyApplication1 to make the decision whether or not to apply config.
You could also use syntax more familiar to Java devs, and maybe define the closure elsewhere:
def commonConfiguration = {
description "description from closure defined separately near call site"
}MyApplication1.createDeploymentJob(this, "bla", "bla", commonConfiguration)
You can use the fact that JobDSL scripts are real Groovy in many other ways. For example, we define our jobs then iterate over a collection of them and apply a common configuration:
[job1, job2, job3].each { it->
it.with {
// ...
}
}As you refine your JobDSL script, you may find it gets quite hacky, with all sorts of tricks used to contribute the right configuration to the right job. I'd definitely encourage you to use helper methods to separate out common configuration, but also to look for a more declarative style. We're moving towards defining our own job metadata - 'requires virtual backends', 'should deploy the app', 'has configuration <from here>' - and then our scripts examine that metadata and apply JobDSL magic as appropriate.
When dealing with a Groovy DSL like JobDSL, I think there's one main concept to get into your head. Speaking from personal experience, if you can do that before mucking around too much with JobDSL, it will save a fair bit of time and frustration. The concept is that of closures and their execution contexts, ie the contexts in which symbols are evaluated. I found these helpful:
http://groovy.codehaus.org/Closureshttps://namingcrisis.net/weblog/2009/08/17/groovy-closure-and-its-execution-context/Even then, in a DSL like JobDSL you can't always tell from the documentation what kind of execution context you'll have been given - see the comment on the first page re delegates and builders - and it also depends on how the DSL script is itself being evaluated. But at least you'll know more about how to experiment.
And you should experiment with tiny snippets of code, not the full pipeline you're trying to define. You should also look to unit-testing your job defs, runnable from your IDE and in your pipeline and not just by mucking around at the Jenkins UI. We rolled our own means of doing this, but I think there's probably support within JobDSL itself nowadays... I must do some research.
Jon