Skip to content
Permalink
Browse files

[FIXED JENKINS-37824] Adding job property-related functionality

More specifically, added "jobProperties", "parameters" and "triggers"
section and related functionality.

This required some fairly complex logic for translating something like
"buildDiscarder(logRotator(numToKeepStr:'1'))" in the config into
something that can do what we need at runtime. Hooray complexity!
  • Loading branch information
abayer committed Oct 5, 2016
1 parent 366510a commit f533ef99e31ce44cbe999653e538ea39fdf772dc
Showing with 2,021 additions and 50 deletions.
  1. +6 −1 pom.xml
  2. +95 −15 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/Utils.groovy
  3. +39 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTBuildParameter.groovy
  4. +73 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTBuildParameters.groovy
  5. +1 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTElement.groovy
  6. +73 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTJobProperties.groovy
  7. +39 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTJobProperty.groovy
  8. +77 −0 ...groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTKeyValueOrMethodCallPair.groovy
  9. +39 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTMethodArg.groovy
  10. +76 −0 .../groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTMethodCallFromArguments.groovy
  11. +24 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTPipelineDef.groovy
  12. +0 −1 ...n/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTPositionalArgumentList.groovy
  13. +39 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTTrigger.groovy
  14. +73 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTTriggers.groovy
  15. +1 −1 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTValue.groovy
  16. +94 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/JobProperties.groovy
  17. +35 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/MethodsToList.groovy
  18. +74 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Parameters.groovy
  19. +27 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Root.groovy
  20. +2 −29 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Tools.groovy
  21. +74 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Triggers.groovy
  22. +120 −0 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/parser/JSONParser.groovy
  23. +177 −1 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/parser/ModelParser.groovy
  24. +151 −1 src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/validator/ModelValidator.groovy
  25. +1 −0 src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/ModelStepLoader.java
  26. +102 −0 src/main/resources/ast-schema.json
  27. +6 −0 src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/ClosureModelTranslator.groovy
  28. +77 −0 src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/MethodsToListTranslator.groovy
  29. +15 −0 src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy
  30. +4 −1 src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/AbstractModelDefTest.java
  31. +61 −0 src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/JobPropertiesTest.java
  32. +64 −0 src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/ParametersTest.java
  33. +65 −0 src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/TriggersTest.java
  34. +32 −0 src/test/resources/json/simpleJobProperties.json
  35. +45 −0 src/test/resources/json/simpleParameters.json
  36. +26 −0 src/test/resources/json/simpleTriggers.json
  37. +38 −0 src/test/resources/simpleJobProperties.groovy
  38. +38 −0 src/test/resources/simpleParameters.groovy
  39. +38 −0 src/test/resources/simpleTriggers.groovy
@@ -104,7 +104,12 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.15</version>
<version>2.18</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
@@ -22,31 +22,30 @@
* THE SOFTWARE.
*/

package org.jenkinsci.plugins.pipeline.modeldefinition;

package org.jenkinsci.plugins.pipeline.modeldefinition

import com.google.common.cache.CacheBuilder
import com.google.common.cache.CacheLoader
import com.google.common.cache.LoadingCache;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import hudson.ExtensionList
import hudson.model.Describable
import hudson.model.Descriptor
import hudson.triggers.TriggerDescriptor
import org.jenkinsci.plugins.pipeline.modeldefinition.actions.ExecutionModelAction
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTArgumentList
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBranch
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTKey
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTNamedArgumentList
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPipelineDef
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPositionalArgumentList
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTSingleArgument
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStage
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStages
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStep
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTreeStep
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTValue
import org.jenkinsci.plugins.pipeline.modeldefinition.model.NestedModel
import org.jenkinsci.plugins.pipeline.modeldefinition.model.StepBlockWithOtherArgs
import org.jenkinsci.plugins.pipeline.modeldefinition.model.MethodsToList
import org.jenkinsci.plugins.pipeline.modeldefinition.parser.Converter
import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.Whitelisted
import org.jenkinsci.plugins.structs.SymbolLookup
import org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable
import org.jenkinsci.plugins.workflow.cps.CpsScript
import org.jenkinsci.plugins.workflow.job.WorkflowRun

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.util.concurrent.TimeUnit;

// TODO: Prune like mad once we have step-in-groovy and don't need these static whitelisted wrapper methods.
/**
@@ -126,6 +125,33 @@ public class Utils {

}

@Whitelisted
public static Class<Describable> getMethodstoListType(Class c) {
Class retClass
c.genericInterfaces.each { Type t ->
if (t instanceof ParameterizedType) {
if (t.rawType.equals(MethodsToList.class)) {
retClass = t.actualTypeArguments.first()
}
}
}

return retClass
}
/*
@Whitelisted
public static Class<Describable> getMethodsToListDescribable(Class c) {
Class<Describable> returnClass
if (c instanceof MethodsToList) {
c.genericInterfaces.each { Type t ->
if (t instanceof ParameterizedType) {
if (t.rawType)
}
}
}
}
*/
/**
* Simple wrapper for isInstance to avoid whitelisting issues.
*
@@ -180,4 +206,58 @@ public class Utils {
}


@Whitelisted
static Map<String,Object> mapForDescribable(UninstantiatedDescribable ud) {
Map<String,Object> args = [:]

ud.arguments.each { k, v ->
if (k == UninstantiatedDescribable.ANONYMOUS_KEY &&
(v instanceof List || v instanceof Object[]) &&
v[0] instanceof Map) {
args.putAll((Map) v[0])
} else if (v instanceof UninstantiatedDescribable) {
args.putAll(mapForDescribable((UninstantiatedDescribable)v))
} else {
args[k] = v
}
}
if (ud.klass != null) {
args['$class'] = ud.klass
} else {
Descriptor d = SymbolLookup.get().findDescriptor(Object.class, ud.symbol)
if (d != null) {
args['$class'] = d.clazz.simpleName
}
}

return args
}

static generateTypeCache(Class<? extends Descriptor> type, List<String> excludedSymbols = []) {
return CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<Object, Map<String, String>>() {
@Override
Map<String, String> load(Object key) throws Exception {
return populateTypeCache(type, excludedSymbols)
}
})
}

private static Map<String,String> populateTypeCache(Class<? extends Descriptor> type, List<String> excludedSymbols = []) {
Map<String,String> knownTypes = [:]

ExtensionList.lookup(type).each { t ->
Set<String> symbolValue = SymbolLookup.getSymbolValue(t)
if (!symbolValue.isEmpty() && !symbolValue.any { excludedSymbols.contains(it) }) {
knownTypes.put(symbolValue.iterator().next(), t.clazz.getName())
}

// Add the class name mapping even if we also found the symbol, for backwards compatibility reasons.
knownTypes.put(t.clazz.getName(), t.clazz.getName())
}

return knownTypes
}

}
@@ -0,0 +1,39 @@
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


package org.jenkinsci.plugins.pipeline.modeldefinition.ast

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@ToString(includeSuper = true, includeSuperProperties = true)
@EqualsAndHashCode(callSuper = true)
@SuppressFBWarnings(value="SE_NO_SERIALVERSIONID")
public class ModelASTBuildParameter extends ModelASTMethodCallFromArguments {
ModelASTBuildParameter(Object sourceLocation) {
super(sourceLocation)
}
}
@@ -0,0 +1,73 @@
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.jenkinsci.plugins.pipeline.modeldefinition.ast

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import net.sf.json.JSONArray
import net.sf.json.JSONObject
import org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator

@ToString(includeSuper = true, includeSuperProperties = true)
@EqualsAndHashCode(callSuper = true)
@SuppressFBWarnings(value="SE_NO_SERIALVERSIONID")
public final class ModelASTBuildParameters extends ModelASTElement {
List<ModelASTBuildParameter> parameters = []

public ModelASTBuildParameters(Object sourceLocation) {
super(sourceLocation)
}

@Override
public JSONObject toJSON() {
JSONArray a = new JSONArray()
parameters.each { s ->
a.add(s.toJSON())
}

return new JSONObject()
.accumulate("parameters",a)
}

@Override
public void validate(ModelValidator validator) {
validator.validateElement(this)
parameters.each { s ->
s?.validate(validator)
}
}

@Override
public String toGroovy() {
return "parameters {\n${parameters.collect { it.toGroovy() }.join("\n") }\n"
}

@Override
public void removeSourceLocation() {
super.removeSourceLocation()
parameters.each { it.removeSourceLocation() }
}
}
@@ -82,3 +82,4 @@ public abstract class ModelASTElement {
}

}

@@ -0,0 +1,73 @@
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.jenkinsci.plugins.pipeline.modeldefinition.ast

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import net.sf.json.JSONArray
import net.sf.json.JSONObject
import org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator

@ToString(includeSuper = true, includeSuperProperties = true)
@EqualsAndHashCode(callSuper = true)
@SuppressFBWarnings(value="SE_NO_SERIALVERSIONID")
public final class ModelASTJobProperties extends ModelASTElement {
List<ModelASTJobProperty> properties = []

public ModelASTJobProperties(Object sourceLocation) {
super(sourceLocation)
}

@Override
public JSONObject toJSON() {
JSONArray a = new JSONArray()
properties.each { s ->
a.add(s.toJSON())
}

return new JSONObject()
.accumulate("properties",a)
}

@Override
public void validate(ModelValidator validator) {
validator.validateElement(this)
properties.each { s ->
s?.validate(validator)
}
}

@Override
public String toGroovy() {
return "jobProperties {\n${properties.collect { it.toGroovy() }.join("\n") }\n"
}

@Override
public void removeSourceLocation() {
super.removeSourceLocation()
properties.each { it.removeSourceLocation() }
}
}
@@ -0,0 +1,39 @@
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


package org.jenkinsci.plugins.pipeline.modeldefinition.ast

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@ToString(includeSuper = true, includeSuperProperties = true)
@EqualsAndHashCode(callSuper = true)
@SuppressFBWarnings(value="SE_NO_SERIALVERSIONID")
public class ModelASTJobProperty extends ModelASTMethodCallFromArguments {
ModelASTJobProperty(Object sourceLocation) {
super(sourceLocation)
}
}

0 comments on commit f533ef9

Please sign in to comment.
You can’t perform that action at this time.