Use of the library without Jenkins
Introduction
Writing Jenkins DSL code usually also means to write unittests and to mock things because you don't have the Jenkins and its plugins as part of your build process (and you also should not have it).
However there are usecases where it would be awesome when you were able to use your own library code locally (still: without Jenkins):
- testing your library code that it does work as expected (without mocks).
- using your library as a tool to run a Jenkinsfile without Jenkins.
The first use case is more simple since you - usually - don't require too many DSL functions that have to be implemented before you can test one or two of your classes. For the second use case you require quite some DSL because you have to implement all DSL you see in a Jenkinsfile and the few DSL functions used in the classes. Giving you an idea see next section ...
Simple scenario
Consider the duplicate code DSL and the related classes in this library.
That library code does required sh, readFile and writeFile as DSL functions.
The class my.dsl.Jenkinks
does implement all this DSL functions for local use
while the class my.dsl.ScriptExecutor
is capable of running any Groovy code:
import my.dsl.Jenkins
import my.dsl.ScriptExecutor
def executor = new ScriptExecutor(Jenkins)
executor.execute('''
import my.tools.DuplicateCodeFinder
import my.tools.Find
def sourceFiles = new Find(this).files('src', '*.groovy')
sourceFiles.addAll(new Find(this).files('test', '*.groovy'))
def dup = new DuplicateCodeFinder(this)
dup.minimumBlockSize = 8
dup.sourceFiles = sourceFiles
dup.check()
''')
println('done')
Being in the root of this project call it like following:
groovy -cp src examples/xdup.groovy
It works really good. Even the my.dsl.*
code can be easily unittested.
At the end you just need one all in one jar being executable to
pass a script file as parameter which works similar to the example above.
Using the fat jar as tool
$ java -jar build/libs/jenkins-shared-pipeline-all-1.0.jar --help
usage: java -jar jenkins-shared-pipeline.jar [options]
Options:
-h,--help Print this help text and exit.
-s,--script <file> Groovy script file
If you put the code passed to the ScriptExecutor
in last example into a file
you can do following
$ java -jar build/libs/jenkins-shared-pipeline-all-1.0.jar --script /tmp/xdup.groovy
Supported DSL functions
It will constantly be extended but for now following DSL functions are implemented:
Commands: | |||
---|---|---|---|
echo | sh | writeFile | readFile |
withEnv | stage | xparser | xfind |
xpublish | xgit | xgradle | xrender |
xversion | virtualenv | xdup |
Please note: The DSL xpublish does not do anything locally.
Is vars dead code?
At least I have not found a way (yet) how to use it without Jenkins.
The ScriptExecutor expects an abstract class that implements those DSL
code for injecting it into a GroovyShell
instance. The mechanism basically
comes from Groovy itself. Compiling the sources in vars (which is possible)
I need to find a way how those scripts know the DSL they use. Because of this
and the problem that the code cannot easily be tested (yet) you should keep the
code of your own DSL functions very vey small delegating to a class based
implementation using dependency injection under src/**
.