From 30022ab257de19bb858b63cb450f0a7f8ecd338c Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Thu, 14 Apr 2022 16:24:48 +0200 Subject: [PATCH] Allow using classes not supported by `structs` for `DescribableContext` (#1202) * Check actual type This allows for types that are not directly supported by structs to be used in Job DSL. An example for this is hudson.util.Secret, that's used by by the ssh-credentials plugin. See JENKINS-57435 for details. * Add test case for fallback to actual type * Address CodeNarc issues in tests --- .../jobdsl/plugin/structs/DescribableContext.groovy | 2 ++ .../jobdsl/plugin/fixtures/DummyTrigger.groovy | 9 +++++++++ .../plugin/structs/DescribableContextSpec.groovy | 13 +++++++++++++ 3 files changed, 24 insertions(+) diff --git a/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/structs/DescribableContext.groovy b/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/structs/DescribableContext.groovy index f38362ba8..1c874528d 100644 --- a/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/structs/DescribableContext.groovy +++ b/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/structs/DescribableContext.groovy @@ -94,6 +94,8 @@ class DescribableContext implements Context { return value instanceof Closure || value == null } else if (parameterType instanceof HeterogeneousObjectType) { return value instanceof Closure || value == null || parameterType.actualType == Object + } else if (parameterType.actualType instanceof Class) { + return value == null || ((Class) parameterType.actualType).isInstance(value) } false } diff --git a/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/fixtures/DummyTrigger.groovy b/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/fixtures/DummyTrigger.groovy index d42f1964f..06da29be8 100644 --- a/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/fixtures/DummyTrigger.groovy +++ b/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/fixtures/DummyTrigger.groovy @@ -12,6 +12,12 @@ import org.kohsuke.stapler.DataBoundConstructor import org.kohsuke.stapler.DataBoundSetter class DummyTrigger extends Trigger { + + @SuppressWarnings('EmptyClass') + static class UnsupportedByStructs { + // We are not supported. + } + @DataBoundSetter String aString @@ -48,6 +54,9 @@ class DummyTrigger extends Trigger { @DataBoundSetter List enumList + @DataBoundSetter + UnsupportedByStructs unsupportedByStructs + @DataBoundConstructor DummyTrigger() throws ANTLRException { } diff --git a/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/structs/DescribableContextSpec.groovy b/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/structs/DescribableContextSpec.groovy index 05bbe8b4e..abe0229f0 100644 --- a/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/structs/DescribableContextSpec.groovy +++ b/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/structs/DescribableContextSpec.groovy @@ -907,6 +907,19 @@ class DescribableContextSpec extends Specification { instance.enumList.empty } + def 'falls back to plain Class if type is not supported by structs'() { + setup: + DescribableContext context = new DescribableContext(new DescribableModel(DummyTrigger), jobManagement) + + when: + context.unsupportedByStructs(new DummyTrigger.UnsupportedByStructs()) + def instance = context.createInstance() + + then: + instance instanceof DummyTrigger + instance.unsupportedByStructs instanceof DummyTrigger.UnsupportedByStructs + } + def 'required parameter missing'() { setup: DescribableContext context = new DescribableContext(new DescribableModel(ADuplicateBuilder), jobManagement)