Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-26126, JENKINS-32133] GDSL, DSLD, improved reference docs
Squashed down to one commit. Added GDSL, DSLD and Groovy view-driven
HTML reference docs for Workflow DSL, integrated into the job config
UI, also able to be fetched directly from standard URLs.
  • Loading branch information
abayer committed Jan 15, 2016
1 parent 118b89e commit ccedde4
Show file tree
Hide file tree
Showing 9 changed files with 559 additions and 16 deletions.
Expand Up @@ -28,7 +28,6 @@
import hudson.Functions;
import hudson.model.RootAction;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
Expand All @@ -39,13 +38,11 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.lang.model.SourceVersion;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
import org.jenkinsci.plugins.workflow.structs.DescribableHelper;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.DoNotUse;
import org.kohsuke.accmod.restrictions.NoExternalUse;
Expand Down Expand Up @@ -231,8 +228,9 @@ public HttpResponse doGenerateSnippet(StaplerRequest req, @QueryParameter String
}

@Restricted(NoExternalUse.class)
public static final String STATIC_URL = ACTION_URL + "/static";
public static final String GDSL_URL = ACTION_URL + "/gdsl";

<<<<<<< HEAD
@Restricted(DoNotUse.class)
public void doStatic(StaplerRequest req, StaplerResponse rsp) throws Exception {
rsp.setContentType("text/html;charset=UTF-8");
Expand Down Expand Up @@ -329,6 +327,15 @@ private static void describeType(DescribableHelper.ParameterType type, PrintWrit
}
}

@Restricted(NoExternalUse.class)
public static final String DSLD_URL = ACTION_URL + "/dsld";

@Restricted(NoExternalUse.class)
public static final String DSL_REF_URL = ACTION_URL + "/dslReference";

@Restricted(NoExternalUse.class)
public static final String DSL_HELP_URL = ACTION_URL + "/dslHelp";

private static class StepDescriptorComparator implements Comparator<StepDescriptor>, Serializable {
@Override
public int compare(StepDescriptor o1, StepDescriptor o2) {
Expand Down
Expand Up @@ -50,6 +50,7 @@ THE SOFTWARE.
</j:forEach>
</d:tag>
</d:taglib>
<f:entry title="Workflow DSL Reference" help="/${it.DSL_REF_URL}"/>
<f:optionalBlock name="snippetizer" title="Snippet Generator" help="/${it.HELP_URL}">
<f:section title="Steps"/>
<!-- Similar to f:dropdownDescriptorSelector, but adds fallback content to block, and JENKINS-25130 adds per-selection help: -->
Expand Down
@@ -0,0 +1,33 @@
package org.jenkinsci.plugins.workflow.cps.Snippetizer


def l = namespace(lib.LayoutTagLib)
def st = namespace("jelly:stapler")

st.contentType(value: "text/html;charset=UTF-8")

l.layout(title:_("Jenkins Workflow Reference"),permission:app.READ) {

st.include(page: "sidepanel", it: app)
l.main_panel {
p {
raw("Click ")
a(href: "${app.rootUrl}${my.GDSL_URL}", target: "_blank") {
raw("here for IntelliJ GDSL")
}
raw(".")

}

p {
raw("Click ")
a(href: "${app.rootUrl}${my.DSLD_URL}", target: "_blank") {
raw("here for Eclipse DSLD")
}
raw(".")

}
st.include(page: "dslReferenceContent", it: my)
}
}

@@ -0,0 +1,34 @@
package org.jenkinsci.plugins.workflow.cps.Snippetizer


def st = namespace("jelly:stapler")

p {
raw("Click ")
a(href: "${app.rootUrl}${my.DSL_HELP_URL}", target: "_blank") {
raw("here")
}
raw(" for this doc in a new window.")

}

p {
raw("Click ")
a(href: "${app.rootUrl}${my.GDSL_URL}", target: "_blank") {
raw("here for IntelliJ GDSL")
}
raw(".")

}

p {
raw("Click ")
a(href: "${app.rootUrl}${my.DSLD_URL}", target: "_blank") {
raw("here for Eclipse DSLD")
}
raw(".")

}

st.include(page: "dslReferenceContent", it: my)

@@ -0,0 +1,151 @@
package org.jenkinsci.plugins.workflow.cps.Snippetizer

import org.jenkinsci.plugins.workflow.cps.GlobalVariable
import org.jenkinsci.plugins.workflow.cps.Snippetizer
import org.jenkinsci.plugins.workflow.steps.StepDescriptor
import org.jenkinsci.plugins.workflow.structs.DescribableHelper

import javax.servlet.RequestDispatcher

Snippetizer snippetizer = my;

def l = namespace(lib.LayoutTagLib)
def st = namespace("jelly:stapler")


h1(_("Steps"))
for (StepDescriptor d : snippetizer.getStepDescriptors(false)) {
generateStepHelp(d);
}

h1(_("Advanced/Deprecated Steps"))
for (StepDescriptor d : snippetizer.getStepDescriptors(true)) {
generateStepHelp(d);
}

h1(_("Variables"))

for (GlobalVariable v : snippetizer.getGlobalVariables()) {
h2 {
code(v.getName())
}
RequestDispatcher rd = request.getView(v, "help");
div(class:"help", style:"display: block") {
if (rd != null) {
st.include(page: "help", it: v)
} else {
raw("(no help)")
}
}
}


def generateStepHelp(StepDescriptor d) throws Exception {
return {
h2 {
code(d.getFunctionName())
raw(": ${d.getDisplayName()}")
}
try {
generateHelp(DescribableHelper.schemaFor(d.clazz), 3);
} catch (Exception x) {
pre {
code(x)
}
}
}.call()
}

def generateHelp(DescribableHelper.Schema schema, int headerLevel) throws Exception {
return {
String help = schema.getHelp(null);
if (help != null && !help.equals("")) {
div(class:"help", style:"display: block") {
raw(help)
}
} // TODO else could use RequestDispatcher (as in Descriptor.doHelp) to serve template-based help
for (String attr : schema.mandatoryParameters()) {
"h${headerLevel}" {
code(attr)
}
generateAttrHelp(schema, attr, headerLevel);
}
for (String attr : schema.parameters().keySet()) {
if (schema.mandatoryParameters().contains(attr)) {
continue;
}
"h${headerLevel}" {
code(attr)
raw(" (optional)")
}
generateAttrHelp(schema, attr, headerLevel);
}
}.call()
}

def generateAttrHelp(DescribableHelper.Schema schema, String attr, int headerLevel) throws Exception {
return {
String help = schema.getHelp(attr);
if (help != null && !help.equals("")) {
div(class:"help", style:"display: block") {
raw(help)
}
}
DescribableHelper.ParameterType type = schema.parameters().get(attr);
describeType(type, headerLevel);
}.call()
}

def describeType(DescribableHelper.ParameterType type, int headerLevel) throws Exception {
return {
int nextHeaderLevel = Math.min(6, headerLevel + 1);
if (type instanceof DescribableHelper.AtomicType) {
p {
strong(_("Type:"))
text(type)
}
} else if (type instanceof DescribableHelper.EnumType) {
p {
strong(_("Values:"))
}

ul {
for (String v : ((DescribableHelper.EnumType) type).getValues()) {
li {
code(v)
}
}
}
} else if (type instanceof DescribableHelper.ArrayType) {
p {
strong(_("Array/List"))
}
describeType(((DescribableHelper.ArrayType) type).getElementType(), headerLevel)
} else if (type instanceof DescribableHelper.HomogeneousObjectType) {
p {
strong(_("Nested object"))
}
generateHelp(((DescribableHelper.HomogeneousObjectType) type).getType(), nextHeaderLevel);
} else if (type instanceof DescribableHelper.HeterogeneousObjectType) {
p {
strong(_("Nested choice of objects"))
}

ul {
for (Map.Entry<String, DescribableHelper.Schema> entry : ((DescribableHelper.HeterogeneousObjectType) type).getTypes().entrySet()) {
li {
code(DescribableHelper.CLAZZ + ": '" + entry.getKey() + "'")
}
generateHelp(entry.getValue(), nextHeaderLevel);
}
}
} else if (type instanceof DescribableHelper.ErrorType) {
Exception x = ((DescribableHelper.ErrorType) type).getError();
pre {
code(x)
}
} else {
assert false: type;
}
}.call()
}

0 comments on commit ccedde4

Please sign in to comment.