Skip to content
Permalink
Browse files

Merge pull request #36 from abayer/jenkins-37823-mk2

[FIXED JENKINS-37823] Added "wrappers" section.
  • Loading branch information
abayer committed Nov 1, 2016
2 parents 8939d47 + daff915 commit 91f0ec0f5283f0f163378773ee8cdbf74953fa71
Showing with 920 additions and 61 deletions.
  1. +29 −2 ...del-api/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTPipelineDef.java
  2. +1 −1 ...line-model-api/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTStep.java
  3. +54 −0 ...e-model-api/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTWrapper.java
  4. +120 −0 ...-model-api/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTWrappers.java
  5. +6 −0 ...el-api/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/validator/ModelValidator.java
  6. +9 −0 ...model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Root.groovy
  7. +60 −0 ...l-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/Wrappers.groovy
  8. +33 −0 ...inition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/WrappersToMap.groovy
  9. +19 −0 ...efinition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/parser/JSONParser.groovy
  10. +50 −0 ...finition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/parser/ModelParser.groovy
  11. +33 −0 ...rc/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/validator/ModelValidatorImpl.groovy
  12. +17 −0 pipeline-model-definition/src/main/resources/ast-schema.json
  13. +6 −0 ...n/src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/ClosureModelTranslator.groovy
  14. +95 −54 ...inition/src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/ModelInterpreter.groovy
  15. +82 −0 .../src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/WrappersToMapTranslator.groovy
  16. +5 −4 ...definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/AbstractModelDefTest.java
  17. +8 −0 ...-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/ValidatorTest.java
  18. +61 −0 ...e-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/WrappersTest.java
  19. +40 −0 pipeline-model-definition/src/test/resources/errors/invalidWrapperType.groovy
  20. +26 −0 pipeline-model-definition/src/test/resources/json/errors/invalidWrapperType.json
  21. +47 −0 pipeline-model-definition/src/test/resources/json/multipleWrappers.json
  22. +38 −0 pipeline-model-definition/src/test/resources/json/simpleWrapper.json
  23. +41 −0 pipeline-model-definition/src/test/resources/multipleWrappers.groovy
  24. +40 −0 pipeline-model-definition/src/test/resources/simpleWrapper.groovy
@@ -20,6 +20,7 @@
private ModelASTJobProperties jobProperties;
private ModelASTBuildParameters parameters;
private ModelASTTriggers triggers;
private ModelASTWrappers wrappers;

public ModelASTPipelineDef(Object sourceLocation) {
super(sourceLocation);
@@ -49,6 +50,11 @@ public JSONObject toJSON() {
} else {
a.put("triggers", null);
}
if (wrappers != null && !wrappers.getWrappers().isEmpty()) {
a.put("wrappers", wrappers.toJSON());
} else {
a.put("wrappers", null);
}
return new JSONObject().accumulate("pipeline", a);
}

@@ -83,6 +89,9 @@ public void validate(ModelValidator validator) {
if (triggers != null) {
triggers.validate(validator);
}
if (wrappers != null) {
wrappers.validate(validator);
}
}

@Override
@@ -116,7 +125,9 @@ public String toGroovy() {
if (triggers != null && !triggers.getTriggers().isEmpty()) {
result.append(triggers.toGroovy()).append('\n');
}

if (wrappers != null && !wrappers.getWrappers().isEmpty()) {
result.append(wrappers.toGroovy()).append('\n');
}

result.append("}\n");
return result.toString();
@@ -191,6 +202,9 @@ public void removeSourceLocation() {
if (triggers != null) {
triggers.removeSourceLocation();
}
if (wrappers != null) {
wrappers.removeSourceLocation();
}
}

private String indent(int count) {
@@ -269,6 +283,14 @@ public void setTriggers(ModelASTTriggers triggers) {
this.triggers = triggers;
}

public ModelASTWrappers getWrappers() {
return wrappers;
}

public void setWrappers(ModelASTWrappers wrappers) {
this.wrappers = wrappers;
}

@Override
public String toString() {
return "ModelASTPipelineDef{" +
@@ -281,6 +303,7 @@ public String toString() {
", jobProperties=" + jobProperties +
", parameters=" + parameters +
", triggers=" + triggers +
", wrappers=" + wrappers +
"}";
}

@@ -328,7 +351,10 @@ public boolean equals(Object o) {
if (getParameters() != null ? !getParameters().equals(that.getParameters()) : that.getParameters() != null) {
return false;
}
return getTriggers() != null ? getTriggers().equals(that.getTriggers()) : that.getTriggers() == null;
if (getTriggers() != null ? !getTriggers().equals(that.getTriggers()) : that.getTriggers() != null) {
return false;
}
return getWrappers() != null ? getWrappers().equals(that.getWrappers()) : that.getWrappers() == null;

}

@@ -344,6 +370,7 @@ public int hashCode() {
result = 31 * result + (getJobProperties() != null ? getJobProperties().hashCode() : 0);
result = 31 * result + (getParameters() != null ? getParameters().hashCode() : 0);
result = 31 * result + (getTriggers() != null ? getTriggers().hashCode() : 0);
result = 31 * result + (getWrappers() != null ? getWrappers().hashCode() : 0);
return result;
}
}
@@ -20,7 +20,7 @@
private ModelASTArgumentList args;

public static Map<String, String> blockedStepsBase() {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(3);
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("stage", "The stage step cannot be used in Declarative Pipelines");
map.put("properties", "The properties step cannot be used in Declarative Pipelines");
map.put("parallel", "The parallel step can only be used as the only top-level step in a stage's step block");
@@ -0,0 +1,54 @@
/*
* 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 org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator;

/**
* A block scoped step to wrap the entire build within.
*
* @author Andrew Bayer
*/
public class ModelASTWrapper extends ModelASTMethodCall {
public ModelASTWrapper(Object sourceLocation) {
super(sourceLocation);
}

@Override
public void validate(final ModelValidator validator) {
validator.validateElement(this);
for (ModelASTMethodArg arg : getArgs()) {
arg.validate(validator);
}
}

@Override
public String toString() {
return "ModelASTWrapper{" +
"name='" + getName() + '\'' +
", args=" + getArgs() +
"}";
}
}
@@ -0,0 +1,120 @@
/*
* 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 net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator;

import java.util.ArrayList;
import java.util.List;

/**
* A container for one or more {@link ModelASTTrigger}s.
*
* @author Andrew Bayer
*/
public final class ModelASTWrappers extends ModelASTElement {
private List<ModelASTWrapper> wrappers = new ArrayList<ModelASTWrapper>();

public ModelASTWrappers(Object sourceLocation) {
super(sourceLocation);
}

@Override
public JSONObject toJSON() {
final JSONArray a = new JSONArray();
for (ModelASTWrapper wrapper: wrappers) {
a.add(wrapper.toJSON());
}
return new JSONObject().accumulate("wrappers", a);
}

@Override
public void validate(final ModelValidator validator) {
validator.validateElement(this);
for (ModelASTWrapper wrapper : wrappers) {
wrapper.validate(validator);
}
}

@Override
public String toGroovy() {
StringBuilder result = new StringBuilder("wrappers {\n");
for (ModelASTWrapper wrapper : wrappers) {
result.append(wrapper.toGroovy()).append('\n');
}
result.append("}\n");
return result.toString();
}

@Override
public void removeSourceLocation() {
super.removeSourceLocation();
for (ModelASTWrapper wrapper: wrappers) {
wrapper.removeSourceLocation();
}
}

public List<ModelASTWrapper> getWrappers() {
return wrappers;
}

public void setWrappers(List<ModelASTWrapper> wrappers) {
this.wrappers = wrappers;
}

@Override
public String toString() {
return "ModelASTWrappers{" +
"wrappers=" + wrappers +
"}";
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}

ModelASTWrappers that = (ModelASTWrappers) o;

return getWrappers() != null ? getWrappers().equals(that.getWrappers()) : that.getWrappers() == null;

}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (getWrappers() != null ? getWrappers().hashCode() : 0);
return result;
}
}
@@ -45,6 +45,8 @@
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTools;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTrigger;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTriggers;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTWrapper;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTWrappers;


public interface ModelValidator {
@@ -87,4 +89,8 @@
boolean validateElement(ModelASTStage stage);

boolean validateElement(ModelASTStages stages);

boolean validateElement(ModelASTWrapper wrapper);

boolean validateElement(ModelASTWrappers wrappers);
}
@@ -66,6 +66,9 @@ public class Root implements NestedModel, Serializable {
@Whitelisted
Parameters parameters

@Whitelisted
Wrappers wrappers

@Whitelisted
Root stages(Stages s) {
this.stages = s
@@ -126,6 +129,12 @@ public class Root implements NestedModel, Serializable {
return this
}

@Whitelisted
Root wrappers(Wrappers w) {
this.wrappers = w
return this
}

/**
* Helper method for translating the key/value pairs in the {@link Environment} into a list of "key=value" strings
* suitable for use with the withEnv step.
@@ -0,0 +1,60 @@
/*
* 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.model

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import hudson.ExtensionList
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStep
import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.Whitelisted
import org.jenkinsci.plugins.workflow.steps.StepDescriptor

/**
* A container for lists of wrappers to execute.
*
* @author Andrew Bayer
*/
@ToString
@EqualsAndHashCode
@SuppressFBWarnings(value="SE_NO_SERIALVERSIONID")
public class Wrappers extends MappedClosure<String, Wrappers> implements WrappersToMap {
@Whitelisted
public static List<String> getEligibleSteps() {
List<String> stepNames = []

// TODO: Figure out if we want to support metasteps? Don't think so.
ExtensionList.lookup(StepDescriptor.class).each { s ->
if (s.takesImplicitBlockArgument()
&& !(s.getFunctionName() in ModelASTStep.blockedSteps.keySet())
&& s.getRequiredContext().isEmpty()) {
stepNames.add(s.getFunctionName())
}
}

return stepNames.sort()
}
}

0 comments on commit 91f0ec0

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