Skip to content

Add DeclarativeDirective extension point for adding directives #260

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

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pipeline-model-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<parent>
<groupId>org.jenkinsci.plugins</groupId>
<artifactId>pipeline-model-parent</artifactId>
<version>1.3.2-SNAPSHOT</version>
<version>1.3.2-directive-extension-SNAPSHOT</version>
</parent>

<groupId>org.jenkinsci.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,23 @@

import hudson.Extension;
import hudson.model.RootAction;
import org.jenkinsci.plugins.pipeline.modeldefinition.model.DeclarativeDirectiveDescriptor;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.fasterxml.jackson.databind.JsonNode;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.fasterxml.jackson.databind.ObjectMapper;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.fasterxml.jackson.databind.node.ObjectNode;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.github.fge.jsonschema.exceptions.ProcessingException;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.github.fge.jsonschema.load.URIManager;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.github.fge.jsonschema.main.JsonSchema;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.github.fge.jsonschema.main.JsonSchemaFactory;
import org.jenkinsci.plugins.pipeline.modeldefinition.shaded.com.github.fge.jsonschema.util.JsonLoader;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;

/**
* Endpoint for exposing the AST JSON schema.
Expand All @@ -60,8 +69,31 @@ public String getDisplayName() {
}

@SuppressWarnings("unused")
public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
rsp.serveFile(req, getClass().getResource("/ast-schema.json"));
public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException {
rsp.setContentType("application/json;charset=UTF-8");
try (OutputStream os = rsp.getOutputStream()) {
ObjectMapper mapper = new ObjectMapper();
Object json = mapper.readValue(getSchemaAsJSON().toString(), Object.class);
mapper.writeValue(os, json);
os.flush();
}
}

private static JsonNode getSchemaAsJSON() throws IOException {
JsonNode baseSchema = JsonLoader.fromResource("/ast-schema.json");

if (baseSchema != null && baseSchema.get("definitions").isObject()) {
JsonNode definitions = baseSchema.get("definitions");
if (definitions.isObject()) {
for (DeclarativeDirectiveDescriptor desc : DeclarativeDirectiveDescriptor.all()) {
((ObjectNode)definitions).put(desc.getName(), desc.getSchema());
}
}
if (!(baseSchema.get("definitions").equals(definitions))) {
((ObjectNode)baseSchema).put("definitions", definitions);
}
}
return baseSchema;
}

/**
Expand All @@ -70,9 +102,9 @@ public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException,
* @return the schema in {@link JsonSchema} form.
* @throws ProcessingException if there are issues reading the schema
*/
public static JsonSchema getJSONSchema() throws ProcessingException {
public static JsonSchema getJSONSchema() throws ProcessingException, IOException {
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
return factory.getJsonSchema("resource:/ast-schema.json");
return factory.getJsonSchema(getSchemaAsJSON());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTAgent extends ModelASTElement {
public class ModelASTAgent extends ModelASTElement {
private ModelASTMethodArg variables;
private ModelASTKey agentType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @author Andrew Bayer
* @see ModelASTStage#branches
*/
public final class ModelASTBranch extends ModelASTElement {
public class ModelASTBranch extends ModelASTElement {
private String name;
private List<ModelASTStep> steps = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTBuildCondition extends ModelASTElement {
public class ModelASTBuildCondition extends ModelASTElement {
private String condition;
private ModelASTBranch branch;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTBuildParameters extends ModelASTElement {
public class ModelASTBuildParameters extends ModelASTElement {
private List<ModelASTBuildParameter> parameters = new ArrayList<>();

public ModelASTBuildParameters(Object sourceLocation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTClosureMap extends ModelASTElement implements ModelASTMethodArg {
public class ModelASTClosureMap extends ModelASTElement implements ModelASTMethodArg {
private Map<ModelASTKey, ModelASTMethodArg> variables = new LinkedHashMap<>();

public ModelASTClosureMap(Object sourceLocation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
import org.codehaus.groovy.ast.ASTNode;
import org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator;

public abstract class ModelASTElement {
public abstract class ModelASTElement implements ModelASTMarkerInterface {
/**
* The sourceLocation is a reference to whatever section of the original source we're parsed from corresponds to this
* element. When parsed from Pipeline Script, it's an {@link ASTNode}, and when parsed from JSON, it's a {@link JSONObject}.
*/
private Object sourceLocation;

ModelASTElement(Object sourceLocation) {
protected ModelASTElement(Object sourceLocation) {
this.sourceLocation = sourceLocation;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTEnvironment extends ModelASTElement {
public class ModelASTEnvironment extends ModelASTElement {
private Map<ModelASTKey, ModelASTEnvironmentValue> variables = new LinkedHashMap<>();

public ModelASTEnvironment(Object sourceLocation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTKeyValueOrMethodCallPair extends ModelASTElement implements ModelASTMethodArg {
public class ModelASTKeyValueOrMethodCallPair extends ModelASTElement implements ModelASTMethodArg {
private ModelASTKey key;
private ModelASTMethodArg value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTLibraries extends ModelASTElement {
public class ModelASTLibraries extends ModelASTElement {
private List<ModelASTValue> libs = new ArrayList<>();

public ModelASTLibraries(Object sourceLocation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,9 @@ public interface ModelASTMarkerInterface {

void validate(@Nonnull ModelValidator validator);

Object getSourceLocation();

void removeSourceLocation();

void setSourceLocation(Object sourceLocation);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @author Andrew Bayer
*/
@SuppressFBWarnings(value = "SE_NO_SERIALVERSIONID")
public final class ModelASTNamedArgumentList extends ModelASTArgumentList {
public class ModelASTNamedArgumentList extends ModelASTArgumentList {
private Map<ModelASTKey, ModelASTValue> arguments = new LinkedHashMap<>();

public ModelASTNamedArgumentList(Object sourceLocation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTOptions extends ModelASTElement {
public class ModelASTOptions extends ModelASTElement {
private List<ModelASTOption> options = new ArrayList<>();
private boolean inStage = false;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package org.jenkinsci.plugins.pipeline.modeldefinition.ast;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.pipeline.modeldefinition.model.DeclarativeDirective;
import org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;

/**
* Represents the parsed pipeline definition for visual pipeline editor. Corresponds to {@code Root}.
*
* @author Kohsuke Kawaguchi
* @author Andrew Bayer
*/
public final class ModelASTPipelineDef extends ModelASTElement {
public class ModelASTPipelineDef extends ModelASTElement {
private ModelASTStages stages;
private ModelASTPostBuild postBuild;
private ModelASTEnvironment environment;
Expand All @@ -22,6 +26,7 @@ public final class ModelASTPipelineDef extends ModelASTElement {
private ModelASTBuildParameters parameters;
private ModelASTTriggers triggers;
private ModelASTLibraries libraries;
private List<DeclarativeDirective> additionalDirectives = new ArrayList<>();

public ModelASTPipelineDef(Object sourceLocation) {
super(sourceLocation);
Expand Down Expand Up @@ -55,6 +60,13 @@ public JSONObject toJSON() {
} else {
a.put("libraries", null);
}
if (!additionalDirectives.isEmpty()) {
JSONObject directives = new JSONObject();
for (DeclarativeDirective d : additionalDirectives) {
directives.put(d.getDescriptor().getName(), d.toJSON());
}
a.put("additionalDirectives", directives);
}
return new JSONObject().accumulate("pipeline", a);
}

Expand Down Expand Up @@ -89,6 +101,9 @@ public void validate(@Nonnull ModelValidator validator) {
if (libraries != null) {
libraries.validate(validator);
}
for (DeclarativeDirective d : additionalDirectives) {
d.validate(validator);
}
}

@Override
Expand Down Expand Up @@ -124,6 +139,9 @@ public String toGroovy() {
if (triggers != null && !triggers.getTriggers().isEmpty()) {
result.append(triggers.toGroovy());
}
for (DeclarativeDirective d : additionalDirectives) {
result.append(d.toGroovy());
}

result.append("}\n");
return result.toString();
Expand Down Expand Up @@ -202,6 +220,12 @@ public void removeSourceLocation() {
if (triggers != null) {
triggers.removeSourceLocation();
}
if (agent != null) {
agent.removeSourceLocation();
}
for (DeclarativeDirective d : additionalDirectives) {
d.removeSourceLocation();
}
}

private static String indent(int count) {
Expand Down Expand Up @@ -280,6 +304,14 @@ public void setTriggers(ModelASTTriggers triggers) {
this.triggers = triggers;
}

@Nonnull
public List<DeclarativeDirective> getAdditionalDirectives() {
return additionalDirectives;
}

public void setAdditionalDirectives(@Nonnull List<DeclarativeDirective> additionalDirectives) {
this.additionalDirectives.addAll(additionalDirectives);
}

@Override
public String toString() {
Expand All @@ -293,6 +325,7 @@ public String toString() {
", parameters=" + parameters +
", triggers=" + triggers +
", libraries=" + libraries +
", additionalDirectives=" + additionalDirectives +
"}";
}

Expand Down Expand Up @@ -338,8 +371,11 @@ public boolean equals(Object o) {
if (getLibraries() != null ? !getLibraries().equals(that.getLibraries()) : that.getLibraries() != 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 getAdditionalDirectives().equals(that.getAdditionalDirectives());
}

@Override
Expand All @@ -354,6 +390,7 @@ public int hashCode() {
result = 31 * result + (getParameters() != null ? getParameters().hashCode() : 0);
result = 31 * result + (getTriggers() != null ? getTriggers().hashCode() : 0);
result = 31 * result + (getLibraries() != null ? getLibraries().hashCode() : 0);
result = 31 * result + getAdditionalDirectives().hashCode();
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @author Kohsuke Kawaguchi
* @author Andrew Bayer
*/
public final class ModelASTPositionalArgumentList extends ModelASTArgumentList {
public class ModelASTPositionalArgumentList extends ModelASTArgumentList {
private List<ModelASTValue> arguments = new ArrayList<>();

public ModelASTPositionalArgumentList(Object sourceLocation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* @author Andrew Bayer
*/
public final class ModelASTPostBuild extends ModelASTBuildConditionsContainer {
public class ModelASTPostBuild extends ModelASTBuildConditionsContainer {
public ModelASTPostBuild(Object sourceLocation) {
super(sourceLocation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* @author Robert Sandell &lt;rsandell@cloudbees.com&gt;.
*/
public final class ModelASTPostStage extends ModelASTBuildConditionsContainer {
public class ModelASTPostStage extends ModelASTBuildConditionsContainer {
public ModelASTPostStage(java.lang.Object sourceLocation) {
super(sourceLocation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* @author Kohsuke Kawaguchi
* @author Andrew Bayer
*/
public final class ModelASTSingleArgument extends ModelASTArgumentList {
public class ModelASTSingleArgument extends ModelASTArgumentList {
private ModelASTValue value;

public ModelASTSingleArgument(Object sourceLocation) {
Expand Down
Loading