Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradle example #22

Open
rpocase opened this issue Jan 9, 2019 · 39 comments
Open

Gradle example #22

rpocase opened this issue Jan 9, 2019 · 39 comments
Labels
help wanted Extra attention is needed

Comments

@rpocase
Copy link

rpocase commented Jan 9, 2019

Desired Behavior

I'd like to have an example implementation using gradle (specifically gradlew) over maven.

Benefits

Gradle is generally much more flexible and easier to consume for users. Maven is much harder to integrate with these days. A major benefit we have seen with gradle is to provide foundational plugins that provide good default config - one benefit of this could be to provide a plugin that specifies the recommended dependencies (e.g. jenkins core version) for a wide set of pipeline libraries.

@matthew-bovolotto
Copy link

Agreed. I have spent some time attempting to create a build.gradle file to get this working however I keep running into roadblocks and do not have time to invest on this anymore. I uploaded my example so far if anyone has any time to continue working on it.

https://github.com/matthew-bovolotto/jenkins-spock-gradle

@awittha awittha added the help wanted Extra attention is needed label Apr 19, 2019
@kamilszymanski
Copy link

You can find working examples at https://github.com/kamilszymanski/jenkins-pipeline-automation-starter.
The repository contains jenkins-pipeline-unit based examples in addition to jenkins-spock, but they are kept separate and can be easily removed.
@awittha if you want I can link the repository to the working example section of a README file or in any other suitable place.

@awittha
Copy link
Contributor

awittha commented Dec 4, 2019

@kamilszymanski , thank you! I have not had a chance to look yet, but it's on my radar and I'll let you know when I have.

@awittha
Copy link
Contributor

awittha commented Jan 15, 2020

I took a look! Oh boy, what fun!

https://github.com/homeaway/jenkins-spock/tree/issue-22/examples/shared-library-gradle

Transitive Dependency JARs from Jenkins Plugins

There is a problem that hopefully someone with Gradle experience can help me solve.

The problem is that the default extension for Jenkins plugin dependencies is .hpi, which is basically a Java WAR. Adding a dependency on a Jenkins plugin like so:

testImplementation(
	group: 'org.jenkins-ci.plugins.workflow',
	name: 'workflow-step-api',
	version: '2.21' )

finds the hpi dependency, not the JAR, and the plugin's classes aren't actually available on the classpath.

Explicitly asking for the JAR like so:

testImplementation 'org.jenkins-ci.plugins.workflow:workflow-cps-global-lib:2.10@jar'

does correctly pull the JAR onto the classpath, but this notation causes Gradle to fail to resolve transitive dependencies when used on a Maven artifact. See gradle/gradle#1487

The result is that every last transitive dependency from the whole dependency tree rooted at that Jenkins plugin, must be added to the build.gradle dependencies { ... block, or else there will be various NoClassDefFound exceptions when the JVM tries to actually load the classes.

This form has the same issue:

testImplementation(
	group: 'org.jenkins-ci.plugins.workflow',
	name: 'workflow-step-api',
	version: '2.21',
	ext: 'jar' )

What I Think We Need

Looking at the Gradle hooks for dependency resolution and substitution, I think something like this:

configurations.all {
	resolutionStrategy.eachDependency { DependencyResolveDetails details ->
		if( details.requested.ext == 'hpi' ) {
			details.useExt 'jar'
			details.because 'jenkins-spock needs JAR dependencies for Jenkins plugins, not HPIs'
		}
	}
}

to transform all hpi-resolved artifacts to use the extension jar instead, would solve the problem.

However, neither the DependencyResolveDetails nor the DependencySubstitution classes expose artifact extensions - only group, name, and version. I am not very familiar with Gradle, and am currently stuck here. I was working off of the "Customizing resolution of a dependency directly" Gradle documentation page.

At this time, I must kick the ball back into the open-source community's court and hope someone knows more about this than I. We're very close, though! I did get partial test-runs with that branch, just, once I started having to add a billion dependencies that the Maven/pom.xml-powered tests didn't, I dug and discovered this pretty-fundamental problem.

@corporate-gadfly
Copy link

At this time, I must kick the ball back into the open-source community's court and hope someone knows more about this than I.

@awittha I don't know much of jenkins-spock or spock or shared libraries, but I do have a need for a testable shared library in gradle (since I'm in the process of creating new shared libraries) for my organization.

Building on the work of @matthew-bovolotto, @kamilszymanski and the work described in #59, I was able to come up with a very minimal gradle project in pull request #67 .

Feedback is most welcome. Hope that helps and hopefully this can lead to a full shared-library-gradle example.

commit 14d008de7333a63ce1dddaa02ce470135aa00a5f (HEAD -> master, origin/master, origin/HEAD)
Date:   Tue Apr 7 13:52:47 2020 -0400

    minimal example for jenkins-spock used from gradle

examples/helper-script-gradle/.gitignore
examples/helper-script-gradle/.keep
examples/helper-script-gradle/build.gradle
examples/helper-script-gradle/gradle/wrapper/gradle-wrapper.jar
examples/helper-script-gradle/gradle/wrapper/gradle-wrapper.properties
examples/helper-script-gradle/gradlew
examples/helper-script-gradle/gradlew.bat
examples/helper-script-gradle/src/.keep
examples/helper-script-gradle/test/ExecTest.groovy
examples/helper-script-gradle/vars/exec.groovy

You can run it by issuing from the examples/helper-script-gradle directory:

./gradlew clean build

or more verbosely:

./gradlew clean build --info

@corporate-gadfly
Copy link

corporate-gadfly commented Apr 8, 2020

I admit it. I'm a noob.

My PR is so simplistic that it doesn't deal with transitive dependencies. When dealing with more complex tests, the original issue of .hpi and lack of transitive dependencies in gradle still remains.

...more progress in next comment...

@corporate-gadfly
Copy link

  • More progress.
  • gradle-jpi-plugin to the rescue.
  • PR jenkins-spock when used with gradle #67 has now been updated to include examples/shared-library-gradle directory.
  • 2 out of 5 tests fail. Failing tests from DefaultPipelineSpec have the following failure message:
java.lang.IllegalStateException: There is no pipeline step mock for [Deployer.call].
	1. Is the name correct?
	2. Does the pipeline step have a descriptor with that name?
	3. Does that step come from a plugin? If so, is that plugin listed as a dependency in your pom.xml?
	4. If not, you may need to call explicitlyMockPipelineStep('Deployer.call') in your test's setup: block.
	at com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification.getPipelineMock(JenkinsPipelineSpecification.groovy:752)

@corporate-gadfly
Copy link

@awittha Any interest in pushing this along further?

@corporate-gadfly
Copy link

corporate-gadfly commented Apr 21, 2020

  • PR jenkins-spock when used with gradle #67 updated with 100% tests passing.
  • basically getSharedLibraryVariables() was looking for .groovy files under vars, so I manually copied them borrowing technique from @kamilszymanski (similar to how the maven setup was doing any way) :
task cleanSharedLibraries(type: Delete) {
    delete "$buildDir/classes/groovy/test/vars"
}

task prepareSharedLibraries(type: Copy) {
    dependsOn tasks.cleanSharedLibraries
    from 'vars'
    include '*'
    into "$buildDir/classes/groovy/test/vars"
}

test {
    dependsOn tasks.prepareSharedLibraries
}

@corporate-gadfly
Copy link

PR #67 updated to include whole-pipeline-gradle.

@corporate-gadfly
Copy link

@awittha : anything I can do on my end to move this further along?

@awittha
Copy link
Contributor

awittha commented Apr 30, 2020

I haven't had time to look over the updates yet; until I find that time I won't know if there's anything I need from you.

@deblaci
Copy link

deblaci commented May 12, 2020

I tried shared-library-gradle, it seems working with my very simple test.
@corporate-gadfly thank you your work!

What I noticed the maven is more informative when one test failed than gradle, e.g.:

`./gradlew test

Task :test FAILED

TestClassSpec > [TestClass] getDirName non service dir FAILED
org.spockframework.runtime.ConditionNotSatisfiedError at TestClassSpec.groovy:34

3 tests completed, 1 failed

FAILURE: Build failed with an exception.

mvn test
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running TestClassSpec
[ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 6.075 s <<< FAILURE! - in TestClassSpec
[ERROR] [TestClass] getDirName non service dir(TestClassSpec) Time elapsed: 0.171 s <<< FAILURE!
org.spockframework.runtime.ConditionNotSatisfiedError:
Condition not satisfied:

"apple" != path
| |
| apple
false

    at TestClassSpec.[TestClass] getDirName non service dir(TestClassSpec.groovy:34)

[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] TestClassSpec.[TestClass] getDirName non service dir:34 Condition not satisfied:

"apple" != path
| |
| apple
false

[INFO]
[ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0`

@corporate-gadfly
Copy link

@deblaci 👍 Thanks for the kind words.

You can increase verbosity by running gradle with INFO logging level on the command line:

./gradlew test --info

Does that make the output any better?

@deblaci
Copy link

deblaci commented May 13, 2020

@corporate-gadfly Yes, it is very similar to maven :) Thanks.

@corporate-gadfly
Copy link

I found another implementation of testing via jenkins-spock and gradle in sdp-libraries.

@corporate-gadfly
Copy link

corporate-gadfly commented May 14, 2020

Perhaps @ernestojeda could chime in on his experience using jenkins-spock and gradle as well.

@shadycuz
Copy link

This PR/Issue should have more visibility.

With 0 Gradle experience I was able to get https://github.com/jenkinsci/JenkinsPipelineUnit up and running in a single day. I have been trying to add jenkins-spock for about 20+ hours across multiple weeks and still can't get it to run.

I have had the most success since finding this issue but still not able to get things to work correctly.

I get

 groovy.util.ResourceException: Cannot open URL: file:/home/shadycuz/repos/x/my-shared-lib/target/test-classes/varslog.groovy

for

def setup() {
    log = loadPipelineScriptForTest("vars/log.groovy")
  }

adding

def setup() {
    script_class_path = ["."]
    log = loadPipelineScriptForTest("vars/log.groovy")
  }

results in

groovy.lang.MissingPropertyException: No such property: script_class_path for class: IntLogSpec
        at IntLogSpec.setup(bashTest.groovy:8)

@corporate-gadfly
Copy link

@shadycuz Hard to comment without looking at a minimal, but complete, example.

If your build.gradle is identical to the ones from my pull request, then, typically, the setup() looks like:

def setup() {
    script_class_path = ["vars"]
    DefaultPipeline = loadPipelineScriptForTest("/DefaultPipeline.groovy")
}

or, in some cases:

def setup() {
    script_class_path = ["vars", "build/classes/groovy/main"]
    Deployer = loadPipelineScriptForTest("/Deployer.groovy")
}

Hope that helps. If you're able to share a minimal example, then more help could be forthcoming.

Also make sure IntLogSpec is extending from the correct groovy class:

extends JenkinsPipelineSpecification

@shadycuz
Copy link

@soda480
Copy link

soda480 commented Jul 30, 2020

We ported our project from maven to gradle (docker-based) earlier this year:
https://github.com/edgexfoundry/edgex-global-pipelines

Readme under the src/test/groovy folder has basic instructions on how to execute

@corporate-gadfly
Copy link

gradle version upped to 6.6.1 in #67.

@mlasevich
Copy link

mlasevich commented Oct 27, 2020

Hmm, trying to follow @corporate-gadfly example, and it works until I try to use jenkins-spock (and not just spock) features - at which point I get the oddest error:

vars.MySpec > classMethod FAILED
  java.lang.RuntimeException at FastClasspathScanner.java:1441
    Caused by: java.util.concurrent.ExecutionException at InterruptionChecker.java:74
      Caused by: java.lang.RuntimeException at ClassfileBinaryParser.java:621

and inside the test

java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unknown constant pool tag 60 in classfile com/ibm/icu/impl/data/LocaleElements_zh__PINYIN.class (element size unknown, cannot continue reading class. Please report this on the FastClasspathScanner GitHub page.
	at io.github.lukehutch.fastclasspathscanner.FastClasspathScanner.scan(FastClasspathScanner.java:1441)
	at io.github.lukehutch.fastclasspathscanner.FastClasspathScanner.scan(FastClasspathScanner.java:1472)
	at io.github.lukehutch.fastclasspathscanner.FastClasspathScanner.scan(FastClasspathScanner.java:1495)
	at com.homeaway.devtools.jenkins.testing.WholeClasspathPipelineExtensionDetector.getClassesWithAnnotationOfTypeInPackage(WholeClasspathPipelineExtensionDetector.java:97)
	at com.homeaway.devtools.jenkins.testing.APipelineExtensionDetector.getPipelineSteps(APipelineExtensionDetector.java:81)
	at com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification.setupSpec(JenkinsPipelineSpecification.groovy:1109)

.... while writing this up, I started looking at examples by others and found a solution workaround by blocking icu4j jar globally. I figure to leave this comment up here for others to find:

Workaround was to add this to the build.gradle - not sure what the consequences of this are, but it seems to work

configurations.all {
    exclude group: 'com.ibm.icu', module: 'icu4j'
}

@corporate-gadfly
Copy link

Thanks for the comment @mlasevich . In all of the sample projects, I have a section as follows:

    testImplementation 'org.jenkins-ci.main:jenkins-core:2.190.2', {
        exclude group: 'com.ibm.icu', module: 'icu4j'
    }

Hope that helps.

@mlasevich
Copy link

In all of the sample projects, I have a section as follows:

    testImplementation 'org.jenkins-ci.main:jenkins-core:2.190.2', {
        exclude group: 'com.ibm.icu', module: 'icu4j'
    }

FWIW, I had that copied just like that, but for whatever reason it just did not work - it was still appearing in the dependency tree and breaking the tests. I even added that section to any dependency related to jenkins. It was not until I globally blocked it that it worked.

@ernestojeda
Copy link

@mlasevich Same thing for use. We had to apply a broad brush to that icu dependency:

https://github.com/edgexfoundry/edgex-global-pipelines/blob/master/build.gradle#L69-L89

@corporate-gadfly
Copy link

I appreciate your comments @ernestojeda and @mlasevich . From my experience, with gradle 6.6.1:

./gradlew --version

------------------------------------------------------------
Gradle 6.6.1
------------------------------------------------------------

Build time:   2020-08-25 16:29:12 UTC
Revision:     f2d1fb54a951d8b11d25748e4711bec8d128d7e3

Kotlin:       1.3.72
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM:          1.8.0_241 (Oracle Corporation 25.241-b07)
OS:           Mac OS X 10.15.7 x86_64

and the shared-library-gradle project, here are the test dependencies. Let me know if you spot something untoward (I don't see icu4j anywhere):

./gradlew -q dependencies --configuration testRuntimeClasspath

------------------------------------------------------------
Root project
------------------------------------------------------------

testRuntimeClasspath - Runtime classpath of source set 'test'.
+--- org.codehaus.groovy:groovy-all:2.5.12
|    +--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-ant:2.5.12
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    +--- org.apache.ant:ant:1.9.15
|    |    |    \--- org.apache.ant:ant-launcher:1.9.15
|    |    +--- org.codehaus.groovy:groovy-groovydoc:2.5.12
|    |    |    +--- org.codehaus.groovy:groovy-templates:2.5.12
|    |    |    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    |    |    \--- org.codehaus.groovy:groovy-xml:2.5.12
|    |    |    |         \--- org.codehaus.groovy:groovy:2.5.12
|    |    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    |    +--- org.codehaus.groovy:groovy-cli-picocli:2.5.12
|    |    |    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    |    |    \--- info.picocli:picocli:4.3.2
|    |    |    \--- org.codehaus.groovy:groovy-docgenerator:2.5.12
|    |    |         +--- org.codehaus.groovy:groovy-templates:2.5.12 (*)
|    |    |         +--- org.codehaus.groovy:groovy:2.5.12
|    |    |         +--- org.codehaus.groovy:groovy-cli-picocli:2.5.12 (*)
|    |    |         \--- com.thoughtworks.qdox:qdox:1.12.1
|    |    +--- org.apache.ant:ant-junit:1.9.15
|    |    |    \--- org.apache.ant:ant:1.9.15 (*)
|    |    +--- org.apache.ant:ant-launcher:1.9.15
|    |    \--- org.apache.ant:ant-antlr:1.9.15
|    +--- org.codehaus.groovy:groovy-cli-commons:2.5.12
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    \--- commons-cli:commons-cli:1.4
|    +--- org.codehaus.groovy:groovy-cli-picocli:2.5.12 (*)
|    +--- org.codehaus.groovy:groovy-console:2.5.12
|    |    +--- org.codehaus.groovy:groovy-templates:2.5.12 (*)
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    +--- org.codehaus.groovy:groovy-cli-picocli:2.5.12 (*)
|    |    \--- org.codehaus.groovy:groovy-swing:2.5.12
|    |         \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-datetime:2.5.12
|    |    \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-docgenerator:2.5.12 (*)
|    +--- org.codehaus.groovy:groovy-groovydoc:2.5.12 (*)
|    +--- org.codehaus.groovy:groovy-groovysh:2.5.12
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    +--- org.codehaus.groovy:groovy-cli-picocli:2.5.12 (*)
|    |    +--- org.codehaus.groovy:groovy-console:2.5.12 (*)
|    |    \--- jline:jline:2.14.6
|    +--- org.codehaus.groovy:groovy-jmx:2.5.12
|    |    \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-json:2.5.12
|    |    \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-jsr223:2.5.12
|    |    \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-macro:2.5.12
|    |    \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-nio:2.5.12
|    |    \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-servlet:2.5.12
|    |    +--- org.codehaus.groovy:groovy-templates:2.5.12 (*)
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    \--- org.codehaus.groovy:groovy-xml:2.5.12 (*)
|    +--- org.codehaus.groovy:groovy-sql:2.5.12
|    |    \--- org.codehaus.groovy:groovy:2.5.12
|    +--- org.codehaus.groovy:groovy-swing:2.5.12 (*)
|    +--- org.codehaus.groovy:groovy-templates:2.5.12 (*)
|    +--- org.codehaus.groovy:groovy-test:2.5.12
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    \--- junit:junit:4.12
|    |         \--- org.hamcrest:hamcrest-core:1.3
|    +--- org.codehaus.groovy:groovy-test-junit5:2.5.12
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    +--- org.junit.platform:junit-platform-launcher:1.4.0
|    |    |    +--- org.apiguardian:apiguardian-api:1.0.0
|    |    |    \--- org.junit.platform:junit-platform-engine:1.4.0
|    |    |         +--- org.apiguardian:apiguardian-api:1.0.0
|    |    |         +--- org.opentest4j:opentest4j:1.1.1
|    |    |         \--- org.junit.platform:junit-platform-commons:1.4.0
|    |    |              \--- org.apiguardian:apiguardian-api:1.0.0
|    |    \--- org.junit.jupiter:junit-jupiter-engine:5.4.0
|    |         +--- org.apiguardian:apiguardian-api:1.0.0
|    |         +--- org.junit.platform:junit-platform-engine:1.4.0 (*)
|    |         \--- org.junit.jupiter:junit-jupiter-api:5.4.0
|    |              +--- org.apiguardian:apiguardian-api:1.0.0
|    |              +--- org.opentest4j:opentest4j:1.1.1
|    |              \--- org.junit.platform:junit-platform-commons:1.4.0 (*)
|    +--- org.codehaus.groovy:groovy-testng:2.5.12
|    |    +--- org.codehaus.groovy:groovy:2.5.12
|    |    \--- org.testng:testng:6.13.1
|    |         \--- com.beust:jcommander:1.72
|    \--- org.codehaus.groovy:groovy-xml:2.5.12 (*)
+--- com.homeaway.devtools.jenkins:jenkins-spock:2.1.4
|    +--- org.spockframework:spock-core:1.1-groovy-2.4
|    |    +--- org.codehaus.groovy:groovy-all:2.4.9 -> 2.5.12 (*)
|    |    \--- junit:junit:4.12 (*)
|    +--- cglib:cglib-nodep:3.2.7
|    +--- org.objenesis:objenesis:2.6
|    +--- org.reflections:reflections:0.9.12
|    |    \--- org.javassist:javassist:3.26.0-GA
|    +--- io.github.lukehutch:fast-classpath-scanner:2.8.2
|    +--- org.codehaus.groovy:groovy-all:2.4.11 -> 2.5.12 (*)
|    +--- org.slf4j:log4j-over-slf4j:1.7.25 -> 1.7.26
|    |    \--- org.slf4j:slf4j-api:1.7.26
|    +--- org.slf4j:jcl-over-slf4j:1.7.25 -> 1.7.26
|    |    \--- org.slf4j:slf4j-api:1.7.26
|    +--- ch.qos.logback:logback-core:1.2.3
|    +--- ch.qos.logback:logback-classic:1.2.3
|    |    +--- ch.qos.logback:logback-core:1.2.3
|    |    \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
|    \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
+--- ch.qos.logback:logback-core:1.2.3
+--- ch.qos.logback:logback-classic:1.2.3 (*)
+--- javax.servlet:javax.servlet-api:3.1.0
+--- org.jenkins-ci.main:jenkins-core:2.190.2
|    +--- org.jenkins-ci.plugins.icon-shim:icon-set:1.0.5
|    +--- org.jenkins-ci.main:remoting:3.33
|    |    \--- org.jenkins-ci:constant-pool-scanner:1.2
|    +--- org.jenkins-ci.main:cli:2.190.2
|    |    +--- org.kohsuke:access-modifier-annotation:1.14
|    |    |    \--- org.jenkins-ci:annotation-indexer:1.4 -> 1.12
|    |    +--- org.jenkins-ci:annotation-indexer:1.12
|    |    +--- commons-codec:commons-codec:1.12
|    |    +--- commons-io:commons-io:2.6
|    |    +--- org.jenkins-ci.main:remoting:3.33 (*)
|    |    +--- org.jvnet.localizer:localizer:1.26
|    |    +--- net.i2p.crypto:eddsa:0.3.0
|    |    \--- commons-lang:commons-lang:2.6
|    +--- org.jenkins-ci:version-number:1.6
|    |    \--- com.google.code.findbugs:annotations:3.0.0
|    +--- org.jenkins-ci:crypto-util:1.1
|    |    \--- commons-io:commons-io:1.4 -> 2.6
|    +--- org.jvnet.hudson:jtidy:4aug2000r7-dev-hudson-1
|    +--- com.google.inject:guice:4.0
|    |    +--- javax.inject:javax.inject:1
|    |    \--- aopalliance:aopalliance:1.0
|    +--- org.connectbot.jbcrypt:jbcrypt:1.0.0
|    +--- org.jruby.ext.posix:jna-posix:1.0.3-jenkins-1
|    +--- com.github.jnr:jnr-posix:3.0.45
|    |    +--- com.github.jnr:jnr-ffi:2.1.8
|    |    |    +--- com.github.jnr:jffi:1.2.17
|    |    |    +--- com.github.jnr:jffi:1.2.16 -> 1.2.17
|    |    |    +--- org.ow2.asm:asm:5.0.3
|    |    |    +--- org.ow2.asm:asm-commons:5.0.3
|    |    |    |    \--- org.ow2.asm:asm-tree:5.0.3
|    |    |    |         \--- org.ow2.asm:asm:5.0.3
|    |    |    +--- org.ow2.asm:asm-analysis:5.0.3
|    |    |    |    \--- org.ow2.asm:asm-tree:5.0.3 (*)
|    |    |    +--- org.ow2.asm:asm-tree:5.0.3 (*)
|    |    |    +--- org.ow2.asm:asm-util:5.0.3
|    |    |    |    \--- org.ow2.asm:asm-tree:5.0.3 (*)
|    |    |    \--- com.github.jnr:jnr-x86asm:1.0.2
|    |    \--- com.github.jnr:jnr-constants:0.9.9
|    +--- org.kohsuke.stapler:stapler-groovy:1.257.2
|    |    +--- org.kohsuke.stapler:stapler-jelly:1.257.2
|    |    |    +--- org.kohsuke.stapler:stapler:1.257.2
|    |    |    |    +--- javax.annotation:javax.annotation-api:1.2
|    |    |    |    +--- commons-discovery:commons-discovery:0.4
|    |    |    |    |    \--- commons-logging:commons-logging:1.0.4 -> 1.2
|    |    |    |    +--- commons-beanutils:commons-beanutils:1.8.3 -> 1.9.3
|    |    |    |    |    +--- commons-logging:commons-logging:1.2
|    |    |    |    |    \--- commons-collections:commons-collections:3.2.2
|    |    |    |    +--- commons-io:commons-io:2.4 -> 2.6
|    |    |    |    +--- commons-logging:commons-logging:1.2
|    |    |    |    +--- commons-codec:commons-codec:1.9 -> 1.12
|    |    |    |    +--- org.jvnet.localizer:localizer:1.7 -> 1.26
|    |    |    |    +--- org.kohsuke.stapler:json-lib:2.4-jenkins-2
|    |    |    |    |    +--- commons-beanutils:commons-beanutils:1.8.0 -> 1.9.3 (*)
|    |    |    |    |    +--- commons-collections:commons-collections:3.2.1 -> 3.2.2
|    |    |    |    |    +--- commons-lang:commons-lang:2.5 -> 2.6
|    |    |    |    |    +--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |    |    |    |    \--- net.sf.ezmorph:ezmorph:1.0.6
|    |    |    |    |         \--- commons-lang:commons-lang:2.3 -> 2.6
|    |    |    |    +--- org.jvnet:tiger-types:2.2
|    |    |    |    +--- com.google.guava:guava:11.0.1
|    |    |    |    |    \--- com.google.code.findbugs:jsr305:1.3.9 -> 2.0.1
|    |    |    |    +--- org.kohsuke:asm5:5.0.1
|    |    |    |    +--- commons-fileupload:commons-fileupload:1.2.1 -> 1.3.1-jenkins-2
|    |    |    |    |    \--- commons-io:commons-io:2.2 -> 2.6
|    |    |    |    +--- com.google.code.findbugs:jsr305:2.0.1
|    |    |    |    \--- com.jcraft:jzlib:1.1.3
|    |    |    +--- org.jenkins-ci:commons-jelly:1.1-jenkins-20120928
|    |    |    |    +--- org.jenkins-ci:commons-jexl:1.1-jenkins-20111212
|    |    |    |    |    \--- commons-logging:commons-logging:1.0.3 -> 1.2
|    |    |    |    +--- commons-beanutils:commons-beanutils:1.7.0 -> 1.9.3 (*)
|    |    |    |    \--- commons-collections:commons-collections:3.2 -> 3.2.2
|    |    |    +--- commons-collections:commons-collections:3.2.2
|    |    |    \--- org.jenkins-ci.dom4j:dom4j:1.6.1-jenkins-4
|    |    \--- org.codehaus.groovy:groovy-all:2.4.11 -> 2.5.12 (*)
|    +--- org.kohsuke.stapler:stapler-jrebel:1.257.2
|    |    \--- org.kohsuke.stapler:stapler:1.257.2 (*)
|    +--- org.kohsuke:windows-package-checker:1.2
|    +--- org.kohsuke.stapler:stapler-adjunct-zeroclipboard:1.3.5-1
|    |    \--- org.kohsuke.stapler:stapler:1.140 -> 1.257.2 (*)
|    +--- org.kohsuke.stapler:stapler-adjunct-timeline:1.5
|    |    \--- org.kohsuke.stapler:stapler:1.140 -> 1.257.2 (*)
|    +--- org.kohsuke.stapler:stapler-adjunct-codemirror:1.3
|    |    \--- org.kohsuke.stapler:stapler:1.140 -> 1.257.2 (*)
|    +--- io.jenkins.stapler:jenkins-stapler-support:1.1
|    +--- com.infradna.tool:bridge-method-annotation:1.13
|    |    \--- org.jenkins-ci:annotation-indexer:1.4 -> 1.12
|    +--- org.kohsuke.stapler:json-lib:2.4-jenkins-2 (*)
|    +--- commons-httpclient:commons-httpclient:3.1-jenkins-1
|    |    +--- commons-logging:commons-logging:1.2
|    |    +--- commons-codec:commons-codec:1.8 -> 1.12
|    |    \--- junit:junit:4.12 (*)
|    +--- args4j:args4j:2.33
|    +--- org.jenkins-ci:annotation-indexer:1.12
|    +--- org.jenkins-ci:bytecode-compatibility-transformer:2.0-beta-2
|    |    +--- org.jenkins-ci:annotation-indexer:1.4 -> 1.12
|    |    +--- org.kohsuke:asm6:6.2
|    |    +--- org.jenkins-ci:constant-pool-scanner:1.2
|    |    \--- commons-io:commons-io:2.4 -> 2.6
|    +--- org.jenkins-ci:task-reactor:1.5
|    +--- org.jvnet.localizer:localizer:1.26
|    +--- antlr:antlr:2.7.6
|    +--- org.jvnet.hudson:xstream:1.4.7-jenkins-1
|    +--- xpp3:xpp3:1.1.4c
|    +--- net.sf.kxml:kxml2:2.3.0
|    +--- jfree:jfreechart:1.0.9
|    |    \--- jfree:jcommon:1.0.12
|    +--- org.apache.ant:ant:1.9.14 -> 1.9.15 (*)
|    +--- commons-io:commons-io:2.6
|    +--- commons-lang:commons-lang:2.6
|    +--- commons-digester:commons-digester:2.1
|    |    +--- commons-beanutils:commons-beanutils:1.8.3 -> 1.9.3 (*)
|    |    \--- commons-logging:commons-logging:1.1.1 -> 1.2
|    +--- commons-beanutils:commons-beanutils:1.9.3 (*)
|    +--- org.apache.commons:commons-compress:1.10
|    +--- javax.mail:mail:1.4.4
|    +--- org.jvnet.hudson:activation:1.1.1-hudson-1
|    +--- jaxen:jaxen:1.1-beta-11
|    |    +--- jdom:jdom:1.0
|    |    \--- xom:xom:1.0b3
|    |         +--- xerces:xmlParserAPIs:2.6.1
|    |         +--- xalan:xalan:2.6.0
|    |         \--- org.ccil.cowan.tagsoup:tagsoup:0.9.7
|    +--- commons-jelly:commons-jelly-tags-fmt:1.0
|    +--- commons-jelly:commons-jelly-tags-xml:1.1
|    |    +--- commons-beanutils:commons-beanutils:1.6 -> 1.9.3 (*)
|    |    +--- commons-collections:commons-collections:2.1 -> 3.2.2
|    |    +--- commons-logging:commons-logging:1.0.3 -> 1.2
|    |    +--- jaxen:jaxen:1.1-beta-2 -> 1.1-beta-11 (*)
|    |    \--- xerces:xerces:2.2.1
|    +--- org.jvnet.hudson:commons-jelly-tags-define:1.0.1-hudson-20071021
|    +--- org.jenkins-ci:commons-jexl:1.1-jenkins-20111212 (*)
|    +--- org.acegisecurity:acegi-security:1.0.7
|    |    +--- org.springframework:spring-core:1.2.9 -> 2.5.6.SEC03
|    |    |    \--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |    +--- org.springframework:spring-jdbc:1.2.9
|    |    |    +--- commons-logging:commons-logging:1.0.4 -> 1.2
|    |    |    +--- org.springframework:spring-beans:1.2.9 -> 2.5.6.SEC03
|    |    |    |    +--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |    |    |    \--- org.springframework:spring-core:2.5.6.SEC03 (*)
|    |    |    +--- org.springframework:spring-core:1.2.9 -> 2.5.6.SEC03 (*)
|    |    |    \--- org.springframework:spring-dao:1.2.9
|    |    |         +--- commons-logging:commons-logging:1.0.4 -> 1.2
|    |    |         +--- org.springframework:spring-beans:1.2.9 -> 2.5.6.SEC03 (*)
|    |    |         +--- org.springframework:spring-context:1.2.9 -> 2.5.6.SEC03
|    |    |         |    +--- aopalliance:aopalliance:1.0
|    |    |         |    +--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |    |         |    +--- org.springframework:spring-beans:2.5.6.SEC03 (*)
|    |    |         |    \--- org.springframework:spring-core:2.5.6.SEC03 (*)
|    |    |         \--- org.springframework:spring-core:1.2.9 -> 2.5.6.SEC03 (*)
|    |    +--- commons-lang:commons-lang:2.1 -> 2.6
|    |    +--- commons-logging:commons-logging:1.0.4 -> 1.2
|    |    +--- commons-codec:commons-codec:1.3 -> 1.12
|    |    +--- oro:oro:2.0.8
|    |    +--- commons-collections:commons-collections:3.1 -> 3.2.2
|    |    \--- log4j:log4j:1.2.9
|    +--- org.codehaus.groovy:groovy-all:2.4.12 -> 2.5.12 (*)
|    +--- jline:jline:2.12 -> 2.14.6
|    +--- org.fusesource.jansi:jansi:1.11
|    +--- org.springframework:spring-webmvc:2.5.6.SEC03
|    |    +--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |    +--- org.springframework:spring-beans:2.5.6.SEC03 (*)
|    |    +--- org.springframework:spring-context:2.5.6.SEC03 (*)
|    |    +--- org.springframework:spring-context-support:2.5.6.SEC03
|    |    |    +--- aopalliance:aopalliance:1.0
|    |    |    +--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |    |    +--- org.springframework:spring-beans:2.5.6.SEC03 (*)
|    |    |    +--- org.springframework:spring-context:2.5.6.SEC03 (*)
|    |    |    \--- org.springframework:spring-core:2.5.6.SEC03 (*)
|    |    +--- org.springframework:spring-core:2.5.6.SEC03 (*)
|    |    \--- org.springframework:spring-web:2.5.6.SEC03
|    |         +--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |         +--- org.springframework:spring-beans:2.5.6.SEC03 (*)
|    |         +--- org.springframework:spring-context:2.5.6.SEC03 (*)
|    |         \--- org.springframework:spring-core:2.5.6.SEC03 (*)
|    +--- org.springframework:spring-core:2.5.6.SEC03 (*)
|    +--- org.springframework:spring-aop:2.5.6.SEC03
|    |    +--- aopalliance:aopalliance:1.0
|    |    +--- commons-logging:commons-logging:1.1.1 -> 1.2
|    |    +--- org.springframework:spring-beans:2.5.6.SEC03 (*)
|    |    \--- org.springframework:spring-core:2.5.6.SEC03 (*)
|    +--- javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1
|    +--- org.slf4j:jcl-over-slf4j:1.7.26 (*)
|    +--- org.slf4j:log4j-over-slf4j:1.7.26 (*)
|    +--- com.sun.xml.txw2:txw2:20110809
|    |    +--- javax.xml.stream:stax-api:1.0-2
|    |    \--- relaxngDatatype:relaxngDatatype:20020414
|    +--- commons-collections:commons-collections:3.2.2
|    +--- org.jvnet.winp:winp:1.28
|    +--- org.jenkins-ci:memory-monitor:1.9
|    |    \--- net.java.dev.jna:jna:4.1.0 -> 5.3.1
|    +--- org.codehaus.woodstox:wstx-asl:3.2.9
|    |    \--- stax:stax-api:1.0.1
|    +--- org.jmdns:jmdns:3.5.5
|    |    \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
|    +--- net.java.dev.jna:jna:5.3.1
|    +--- org.kohsuke:akuma:1.10
|    |    \--- net.java.dev.jna:jna:4.1.0 -> 5.3.1
|    +--- org.kohsuke:libpam4j:1.11
|    |    \--- net.java.dev.jna:jna:4.5.2 -> 5.3.1
|    +--- org.kohsuke:libzfs:0.8
|    |    \--- net.java.dev.jna:jna:3.5.2 -> 5.3.1
|    +--- com.sun.solaris:embedded_su4j:1.1
|    +--- net.java.sezpoz:sezpoz:1.13
|    +--- org.kohsuke.jinterop:j-interop:2.0.6-kohsuke-1
|    |    \--- org.kohsuke.jinterop:j-interopdeps:2.0.6-kohsuke-1
|    |         \--- org.samba.jcifs:jcifs:1.2.19
|    +--- org.jvnet.robust-http-client:robust-http-client:1.2
|    +--- org.jenkins-ci:symbol-annotation:1.1 -> 1.18
|    +--- commons-codec:commons-codec:1.12
|    +--- org.kohsuke:access-modifier-annotation:1.14 (*)
|    +--- commons-fileupload:commons-fileupload:1.3.1-jenkins-2 (*)
|    +--- com.google.guava:guava:11.0.1 (*)
|    \--- com.jcraft:jzlib:1.1.3-kohsuke-1 -> 1.1.3
+--- org.jenkins-ci.plugins:pipeline-stage-step:2.3
|    +--- org.jenkins-ci.plugins.workflow:workflow-api:2.15 -> 2.34
|    |    +--- org.jenkins-ci.plugins.workflow:workflow-step-api:2.16 -> 2.20
|    |    |    \--- org.jenkins-ci.plugins:structs:1.18
|    |    |         \--- org.jenkins-ci:symbol-annotation:1.18
|    |    +--- org.jenkins-ci.plugins:scm-api:2.2.6
|    |    |    \--- org.jenkins-ci.plugins:structs:1.9 -> 1.18 (*)
|    |    \--- org.jenkins-ci.plugins:structs:1.17 -> 1.18 (*)
|    +--- org.jenkins-ci.plugins:structs:1.6 -> 1.18 (*)
|    +--- org.jenkins-ci.plugins:scm-api:2.0.7 -> 2.2.6 (*)
|    \--- org.jenkins-ci.plugins.workflow:workflow-step-api:2.11 -> 2.20 (*)
+--- org.jenkins-ci.plugins.workflow:workflow-basic-steps:2.16
|    +--- org.jenkins-ci.plugins.workflow:workflow-step-api:2.18 -> 2.20 (*)
|    +--- org.jenkins-ci.plugins:mailer:1.18
|    |    \--- org.jenkins-ci.plugins:display-url-api:0.2 -> 0.4
|    |         \--- org.jenkins-ci.plugins:junit:1.3
|    +--- org.jenkins-ci.plugins.workflow:workflow-api:2.34 (*)
|    +--- org.jenkins-ci.plugins:structs:1.17 -> 1.18 (*)
|    \--- org.jenkins-ci.plugins:apache-httpcomponents-client-4-api:4.5.5-3.0
|         +--- org.apache.httpcomponents:httpclient:4.5.5
|         |    +--- org.apache.httpcomponents:httpcore:4.4.9
|         |    +--- commons-logging:commons-logging:1.2
|         |    \--- commons-codec:commons-codec:1.10 -> 1.12
|         +--- org.apache.httpcomponents:httpmime:4.5.5
|         |    \--- org.apache.httpcomponents:httpclient:4.5.5 (*)
|         +--- org.apache.httpcomponents:fluent-hc:4.5.5
|         |    +--- org.apache.httpcomponents:httpclient:4.5.5 (*)
|         |    \--- commons-logging:commons-logging:1.2
|         +--- org.apache.httpcomponents:httpclient-cache:4.5.5
|         |    +--- org.apache.httpcomponents:httpclient:4.5.5 (*)
|         |    \--- commons-logging:commons-logging:1.2
|         +--- org.apache.httpcomponents:httpasyncclient:4.1.3
|         |    +--- org.apache.httpcomponents:httpcore:4.4.6 -> 4.4.9
|         |    +--- org.apache.httpcomponents:httpcore-nio:4.4.6
|         |    |    \--- org.apache.httpcomponents:httpcore:4.4.6 -> 4.4.9
|         |    +--- org.apache.httpcomponents:httpclient:4.5.3 -> 4.5.5 (*)
|         |    \--- commons-logging:commons-logging:1.2
|         \--- org.apache.httpcomponents:httpasyncclient-cache:4.1.3
|              +--- org.apache.httpcomponents:httpasyncclient:4.1.3 (*)
|              \--- org.apache.httpcomponents:httpclient-cache:4.5.3 -> 4.5.5 (*)
+--- org.jenkins-ci.plugins.workflow:workflow-durable-task-step:2.35
|    +--- org.jenkins-ci.plugins.workflow:workflow-step-api:2.20 (*)
|    +--- org.jenkins-ci.plugins:durable-task:1.33
|    +--- org.jenkins-ci.plugins.workflow:workflow-api:2.33 -> 2.34 (*)
|    +--- org.jenkins-ci.plugins.workflow:workflow-support:3.3
|    |    +--- org.jenkins-ci.plugins.workflow:workflow-step-api:2.19 -> 2.20 (*)
|    |    +--- org.jenkins-ci.plugins.workflow:workflow-api:2.30 -> 2.34 (*)
|    |    +--- org.jenkins-ci.plugins:scm-api:2.2.6 (*)
|    |    +--- org.jenkins-ci.plugins:script-security:1.39 -> 1.58
|    |    |    \--- org.kohsuke:groovy-sandbox:1.21
|    |    \--- org.jboss.marshalling:jboss-marshalling-river:2.0.6.Final
|    |         \--- org.jboss.marshalling:jboss-marshalling:2.0.6.Final
|    +--- org.jenkins-ci.plugins:script-security:1.58 (*)
|    +--- org.jenkins-ci.plugins:structs:1.18 (*)
|    \--- org.jenkins-ci.plugins:scm-api:2.2.6 (*)
+--- org.jenkins-ci.plugins.workflow:workflow-cps-global-lib:2.10
|    +--- org.jenkins-ci.plugins.workflow:workflow-cps:2.39
|    |    +--- org.jenkins-ci.plugins.workflow:workflow-step-api:2.10 -> 2.20 (*)
|    |    +--- org.jenkins-ci.plugins.workflow:workflow-api:2.18 -> 2.34 (*)
|    |    +--- org.jenkins-ci.plugins.workflow:workflow-support:2.14 -> 3.3 (*)
|    |    +--- org.jenkins-ci.plugins.workflow:workflow-scm-step:2.4
|    |    |    \--- org.jenkins-ci.plugins.workflow:workflow-step-api:1.15 -> 2.20 (*)
|    |    +--- org.jenkins-ci.plugins:script-security:1.31 -> 1.58 (*)
|    |    +--- org.jenkins-ci.plugins:scm-api:2.0.8 -> 2.2.6 (*)
|    |    +--- org.jenkins-ci.plugins:structs:1.7 -> 1.18 (*)
|    |    +--- com.cloudbees:groovy-cps:1.18 -> 1.31
|    |    |    \--- com.google.guava:guava:11.0.1 (*)
|    |    +--- org.jenkins-ci.ui:jquery-detached:1.2.1
|    |    +--- org.jenkins-ci.ui:ace-editor:1.0.1
|    |    \--- com.cloudbees:diff4j:1.2
|    +--- org.jenkins-ci.plugins:git-server:1.7
|    |    \--- org.jenkins-ci.plugins:git-client:1.11.0 -> 2.6.0
|    |         +--- org.eclipse.jgit:org.eclipse.jgit:4.5.3.201708160445-r
|    |         |    +--- com.jcraft:jsch:0.1.53 -> 0.1.54
|    |         |    +--- com.googlecode.javaewah:JavaEWAH:0.7.9
|    |         |    +--- org.apache.httpcomponents:httpclient:4.3.6 -> 4.5.5 (*)
|    |         |    \--- org.slf4j:slf4j-api:1.7.2 -> 1.7.26
|    |         +--- org.eclipse.jgit:org.eclipse.jgit.http.server:4.5.3.201708160445-r
|    |         |    \--- org.eclipse.jgit:org.eclipse.jgit:4.5.3.201708160445-r (*)
|    |         +--- org.eclipse.jgit:org.eclipse.jgit.http.apache:4.5.3.201708160445-r
|    |         |    \--- org.eclipse.jgit:org.eclipse.jgit:4.5.3.201708160445-r (*)
|    |         +--- org.jenkins-ci.plugins:structs:1.9 -> 1.18 (*)
|    |         +--- org.jenkins-ci.plugins:ssh-credentials:1.13 -> 1.14
|    |         |    \--- org.jenkins-ci.plugins:credentials:2.1.17
|    |         |         +--- org.jenkins-ci.plugins:structs:1.7 -> 1.18 (*)
|    |         |         \--- org.antlr:antlr4-runtime:4.5
|    |         |              \--- org.abego.treelayout:org.abego.treelayout.core:1.0.1
|    |         +--- org.jenkins-ci.plugins:jsch:0.1.54.1
|    |         |    +--- com.jcraft:jsch:0.1.54
|    |         |    \--- org.jenkins-ci.plugins:ssh-credentials:1.12 -> 1.14 (*)
|    |         +--- org.jenkins-ci.plugins:apache-httpcomponents-client-4-api:4.5.3-2.0 -> 4.5.5-3.0 (*)
|    |         \--- org.jenkins-ci.plugins:credentials:2.1.13 -> 2.1.17 (*)
|    +--- org.jenkins-ci.plugins:git-client:2.6.0 (*)
|    +--- org.jenkins-ci.plugins:scm-api:2.2.5 -> 2.2.6 (*)
|    +--- org.jenkins-ci.plugins:cloudbees-folder:5.16
|    +--- org.jenkins-ci.plugins.workflow:workflow-scm-step:2.4 (*)
|    +--- org.jenkins-ci.plugins:script-security:1.33 -> 1.58 (*)
|    +--- org.jenkins-ci.plugins:structs:1.10 -> 1.18 (*)
|    +--- org.jenkins-ci.plugins:credentials:2.1.14 -> 2.1.17 (*)
|    +--- org.apache.ivy:ivy:2.4.0
|    \--- org.apache.commons:commons-lang3:3.5
+--- org.jenkins-ci.plugins:slack:2.3
|    +--- org.jenkins-ci.plugins:display-url-api:0.4 (*)
|    +--- org.jenkins-ci.plugins:junit:1.3
|    +--- com.fasterxml.jackson.core:jackson-databind:2.4.4
|    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.4.0
|    |    \--- com.fasterxml.jackson.core:jackson-core:2.4.4
|    +--- org.apache.httpcomponents:httpclient:4.3.2 -> 4.5.5 (*)
|    +--- org.json:json:20131018
|    +--- org.jenkins-ci.plugins:credentials:1.25 -> 2.1.17 (*)
|    +--- org.jenkins-ci.plugins:plain-credentials:1.1
|    |    \--- org.jenkins-ci.plugins:credentials:1.21 -> 2.1.17 (*)
|    +--- net.java.dev.jna:jna:3.2.2 -> 5.3.1
|    \--- org.jenkins-ci.plugins.workflow:workflow-step-api:1.11 -> 2.20 (*)
+--- org.jenkins-ci.plugins:ssh-agent:1.16
|    +--- org.apache.sshd:sshd-core:1.0.0
|    |    \--- org.slf4j:slf4j-api:1.7.12 -> 1.7.26
|    +--- tomcat:tomcat-apr:5.5.23
|    +--- com.cloudbees.util:jnr-unixsocket-nodep:0.3.1
|    +--- org.jenkins-ci.plugins.workflow:workflow-step-api:2.16 -> 2.20 (*)
|    +--- org.jenkins-ci.plugins:credentials:2.1.17 (*)
|    +--- org.jenkins-ci.plugins:ssh-credentials:1.14 (*)
|    \--- org.jenkins-ci.plugins:bouncycastle-api:2.16.3
|         \--- org.bouncycastle:bcpkix-jdk15on:1.59
|              \--- org.bouncycastle:bcprov-jdk15on:1.59
\--- com.cloudbees:groovy-cps:1.31 (*)

(*) - dependencies omitted (listed previously)

A web-based, searchable dependency report is available by adding the --scan option.

@corporate-gadfly
Copy link

gradle version bump to 6.7 in #67 .

@mlasevich
Copy link

@corporate-gadfly I tested, and sure enough, your version seems to work. Upon comparing our setups I traced it down to version of org.jenkins-ci.jpi plugin. You had 0.39.0 and I had 0.40.0-rc.2 - it looks like 0.40 adds its own dependency for jenkins-core and ignores one in the dependencies

@corporate-gadfly
Copy link

thx for the feedback. With latest commits in #67, I ended up using the latest jenkins-core and the following as an exclusion:

testImplementation 'org.jenkins-ci.main:jenkins-core:2.266', {
    // exclude following to avoid errors from FastClasspathScanner
    //      Unknown constant pool tag 60 in classfile
    //      com/ibm/icu/impl/data/LocaleElements_zh__PINYIN.class
    exclude group: 'jaxen', module: 'jaxen'
}

YMMV.

@corporate-gadfly
Copy link

jpi plugin bumped to 0.42.0. With latest commit in #67, I'm using maskClasses in the plugin configuration to exclude jaxen.

YMMV.

@corporate-gadfly
Copy link

@corporate-gadfly I tested, and sure enough, your version seems to work. Upon comparing our setups I traced it down to version of org.jenkins-ci.jpi plugin. You had 0.39.0 and I had 0.40.0-rc.2 - it looks like 0.40 adds its own dependency for jenkins-core and ignores one in the dependencies

@mlasevich : JPI plugin bumped to 0.42.0, in #67, FYI.

@corporate-gadfly
Copy link

@corporate-gadfly

https://github.com/DontShaveTheYak/jenkins-std-lib/tree/spock

@shadycuz : Sorry this slipped through the cracks. With the following diff, your IntLogSpec specification class goes further now. I did the bare minimum, including explicitly mocking pipeline steps, to get it going.

diff --git a/build.gradle b/build.gradle
index b4bfb2b..bb54a21 100644
--- a/build.gradle
+++ b/build.gradle
@@ -53,7 +53,7 @@ dependencies {
 
     // Test Frameworks
     testImplementation('junit:junit:4.12')
-    testImplementation('com.homeaway.devtools.jenkins:jenkins-spock:2.0.1')
+    testImplementation('com.homeaway.devtools.jenkins:jenkins-spock:2.1.4')
     testImplementation('org.spockframework:spock-core:1.3-groovy-2.4')
     testImplementation('com.lesfurets:jenkins-pipeline-unit:1.5')
 
diff --git a/test/integration/var/bashTest.groovy b/test/integration/var/bashTest.groovy
index e4ccf11..5bddcb6 100644
--- a/test/integration/var/bashTest.groovy
+++ b/test/integration/var/bashTest.groovy
@@ -2,11 +2,13 @@
 import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
 
 class IntLogSpec extends JenkinsPipelineSpecification {
-  def bash = null
+  def log = null
   
   def setup() {
     script_class_path = ["."]
     log = loadPipelineScriptForTest("vars/log.groovy")
+    explicitlyMockPipelineStep('ansiColor')
+    explicitlyMockPipelineVariable('out')
   }
   
   def "[buildJavascriptApp] will run npm publish if deploy is true"() {

script_class_path was not introduced in jenkins-spock until 2.1.0.

@shadycuz
Copy link

@corporate-gadfly

Thanks for getting back to me. I kinda stopped development on my public shared-lib because I wasn't happy with the level of testing I was able to accomplish. I felt like most testing was aimed at the jobs and I was more concerned with the library. Will definitely give it another shot soon.

It's probably because I'm not experienced with java, if I was I would probably just publish a couple of plugins instead of a shared_lib lol.

@reinholdfuereder
Copy link

@shadycuz I am personally not sure that developing plugins instead of a shared pipeline library is (in general) preferable. You then may enter Jenkins plugins hell, or have other/additional challenges like release/deployment/update. As always: it depends. ;-)

@awittha
Copy link
Contributor

awittha commented Mar 8, 2021

I would probably just publish a couple of plugins instead of a shared_lib

I prefer this myself!

@sdoeringNew
Copy link

Instead of doing this:

def setup() {
    script_class_path = ["vars"]
    DefaultPipeline = loadPipelineScriptForTest("/DefaultPipeline.groovy")
}

in every test class I simply created a folder called target and created a symlink pointing to vars/

vars/
target/classes ---> vars/

Anyways, I think that's an issue that shall be solved in jenkins-spock.

@EnsuingRequiem
Copy link

EnsuingRequiem commented Oct 29, 2021

Instead of doing this:

def setup() {
    script_class_path = ["vars"]
    DefaultPipeline = loadPipelineScriptForTest("/DefaultPipeline.groovy")
}

in every test class I simply created a folder called target and created a symlink pointing to vars/

vars/
target/classes ---> vars/

Anyways, I think that's an issue that shall be solved in jenkins-spock.

Why not implement something such as

// Needed for all the vars source to be found by spock
project.buildDir = 'target'

task cleanSharedLibraries(type: Delete) {
    delete "$buildDir/classes/groovy/test/vars"
    delete "$buildDir/resources/test/vars"
}

task copyGlobalLibVars (type: Copy) {
    dependsOn tasks.cleanSharedLibraries
    from "$rootDir/vars"
    include '**/*.groovy'
    into "$buildDir/classes/vars"
}

task copyVarsToResource (type: Copy) {
    dependsOn tasks.copyGlobalLibVars
    from "$rootDir/vars"
    include '**/*.groovy'
    into "$buildDir/resources/test/vars"
}

compileTestGroovy {
    options.incremental = true
    options.fork        = true
    options.failOnError = false
}
compileTestGroovy.dependsOn(copyVarsToResource)

Which is based on #22 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Development

No branches or pull requests