Add support for in_parallel sub-properties
See: https://github.com/spring-projects/sts4/issues/345 Signed-off-by: Kris De Volder <kdevolder@pivotal.io>
This commit is contained in:
@@ -19,6 +19,7 @@ import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.yaml.snakeyaml.nodes.MappingNode;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
import org.yaml.snakeyaml.nodes.ScalarNode;
|
||||
import org.yaml.snakeyaml.nodes.SequenceNode;
|
||||
|
||||
/**
|
||||
* Adapts a SnakeYaml ast node as a {@link DynamicSchemaContext} (so it
|
||||
@@ -77,4 +78,8 @@ public class ASTDynamicSchemaContext extends CachingSchemaContext {
|
||||
public boolean isMap() {
|
||||
return mapNode!=null;
|
||||
}
|
||||
@Override
|
||||
public boolean isSequence() {
|
||||
return node instanceof SequenceNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,11 @@ public interface DynamicSchemaContext {
|
||||
public boolean isMap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSequence() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -98,5 +103,10 @@ public interface DynamicSchemaContext {
|
||||
* Returns true if the current node is a Mapping node
|
||||
*/
|
||||
boolean isMap();
|
||||
|
||||
/**
|
||||
* Returns true if the current node is a Sequence node
|
||||
*/
|
||||
boolean isSequence();
|
||||
|
||||
}
|
||||
|
||||
@@ -81,6 +81,11 @@ public class SNodeDynamicSchemaContext extends CachingSchemaContext {
|
||||
|
||||
@Override
|
||||
public boolean isMap() {
|
||||
return !computeDefinedProperties().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSequence() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YBeanAndSequenceUnion;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraints;
|
||||
import org.springframework.ide.vscode.commons.yaml.snippet.TypeBasedSnippetProvider;
|
||||
@@ -168,19 +169,27 @@ public class YTypeFactory {
|
||||
}
|
||||
return new YBeanUnionType(name, beanTypes);
|
||||
}
|
||||
ArrayList<YBeanType> beans = new ArrayList<>(types.length);
|
||||
ArrayList<YMapType> maps = new ArrayList<>(types.length);
|
||||
ArrayList<YAtomicType> atoms = new ArrayList<>(types.length);
|
||||
ArrayList<YSeqType> arrays = new ArrayList<>(types.length);
|
||||
for (YType t : types) {
|
||||
if (t instanceof YMapType) {
|
||||
maps.add((YMapType) t);
|
||||
} else if (t instanceof YAtomicType) {
|
||||
atoms.add((YAtomicType) t);
|
||||
} else if (t instanceof YSeqType) {
|
||||
arrays.add((YSeqType) t);
|
||||
} else if (t instanceof YBeanType) {
|
||||
beans.add((YBeanType) t);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Union of this kind of types is not (yet) supported: "+t);
|
||||
}
|
||||
}
|
||||
if (atoms.size()==1 && maps.size()==1) {
|
||||
if (atoms.size()==1 && maps.size()==1 && arrays.size()==0 && beans.size()==0) {
|
||||
return new YAtomAndMapUnion(name, atoms.get(0), maps.get(0));
|
||||
} else if (atoms.size()==0 && maps.size()==0 && arrays.size()==1 && beans.size()==1) {
|
||||
return new YBeanAndSequenceUnion(name, beans.get(0), arrays.get(0));
|
||||
}
|
||||
throw new IllegalArgumentException("Union of this kind of types is not (yet) supported: "+types);
|
||||
}
|
||||
@@ -544,7 +553,6 @@ public class YTypeFactory {
|
||||
this.isSeq = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -836,6 +844,49 @@ public class YTypeFactory {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class YBeanAndSequenceUnion extends AbstractType {
|
||||
|
||||
private String name;
|
||||
private YBeanType bean;
|
||||
private YSeqType seq;
|
||||
|
||||
public YBeanAndSequenceUnion(String name, YBeanType yBeanType, YSeqType ySeqType) {
|
||||
this.name = name;
|
||||
this.bean = yBeanType;
|
||||
this.seq = ySeqType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public YType inferMoreSpecificType(DynamicSchemaContext dc) {
|
||||
if (dc.isMap()) {
|
||||
return bean;
|
||||
} else if (dc.isSequence()) {
|
||||
return seq;
|
||||
}
|
||||
return super.inferMoreSpecificType(dc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (name!=null) {
|
||||
return name;
|
||||
} else {
|
||||
return "(" + bean +" | " + seq + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBean() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSequenceable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class YTypedPropertyImpl implements YTypedProperty, Cloneable {
|
||||
|
||||
|
||||
@@ -377,9 +377,18 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
doStep,
|
||||
tryStep
|
||||
};
|
||||
|
||||
|
||||
YBeanUnionType step = f.yBeanUnion("Step", stepTypes);
|
||||
addProp(aggregateStep, "aggregate", f.yseq(step));
|
||||
addProp(inParallelStep, "in_parallel", f.yseq(step));
|
||||
YBeanType inParallelStepOptions = f.ybean("InParallelStepOptions");
|
||||
addProp(inParallelStepOptions, "steps", f.yseq(step));
|
||||
addProp(inParallelStepOptions, "limit", t_pos_integer);
|
||||
addProp(inParallelStepOptions, "fail_fast", t_boolean);
|
||||
addProp(inParallelStep, "in_parallel", f.yunion(null,
|
||||
f.yseq(step),
|
||||
inParallelStepOptions
|
||||
));
|
||||
addProp(doStep, "do", f.yseq(step));
|
||||
addProp(tryStep, "try", step);
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
*Optional*. Default is *false*. When enabled the parallel step will fail fast by returning as soon as any
|
||||
sub-step fails. This means that running steps will be interrupted and pending steps will no longer be
|
||||
scheduled.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
*Optional. Default is no limit*. A sempahore which limits the parallelism when executing the steps in a
|
||||
`in_parallel` step. When set, the number of running steps will not exceed the limit.
|
||||
|
||||
When not specified `in_parallel` will execute all steps immediately, making the default behavior
|
||||
identical to [aggregate](https://concourse-ci.org/aggregate-step.html).
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
*Optional*. The steps to perform in parallel.
|
||||
@@ -315,7 +315,7 @@ public class ConcourseEditorTest {
|
||||
"get: <*>"
|
||||
, // ==============
|
||||
"in_parallel:\n" +
|
||||
" - <*>"
|
||||
" <*>"
|
||||
, // ==============
|
||||
"put: <*>"
|
||||
, // ==============
|
||||
@@ -551,12 +551,68 @@ public class ConcourseEditorTest {
|
||||
"- name: some-job\n" +
|
||||
" plan:\n" +
|
||||
" - in_parallel:\n" +
|
||||
" - get: some-resource\n"
|
||||
" limit: 2\n" +
|
||||
" fail_fast: true\n" +
|
||||
" steps:\n" +
|
||||
" - get: some-resource\n"
|
||||
);
|
||||
|
||||
editor.assertHoverContains("in_parallel", "Performs the given steps in parallel");
|
||||
editor.assertHoverContains("limit", "sempahore which limits the parallelism");
|
||||
editor.assertHoverContains("fail_fast", "step will fail fast");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inParallelStepReconcile() throws Exception {
|
||||
Editor editor;
|
||||
|
||||
//old style... just a sequence of steps
|
||||
editor = harness.newEditor(
|
||||
"jobs:\n" +
|
||||
"- name: some-job\n" +
|
||||
" plan:\n" +
|
||||
" - in_parallel:\n" +
|
||||
" - get: some-resource\n"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"some-resource|does not exist"
|
||||
);
|
||||
|
||||
//new style... object with a 'steps' property
|
||||
editor = harness.newEditor(
|
||||
"jobs:\n" +
|
||||
"- name: some-job\n" +
|
||||
" plan:\n" +
|
||||
" - in_parallel:\n" +
|
||||
" limit: not-a-number\n" +
|
||||
" fail_fast: not-a-bool\n"+
|
||||
" steps:\n" +
|
||||
" - get: some-resource\n"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"not-a-number|NumberFormatException",
|
||||
"not-a-bool|boolean",
|
||||
"some-resource|does not exist"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inParallelStepCompletion() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"jobs:\n" +
|
||||
"- name: some-job\n" +
|
||||
" plan:\n" +
|
||||
" - <*>"
|
||||
);
|
||||
editor.assertCompletionWithLabel("in_parallel",
|
||||
"jobs:\n" +
|
||||
"- name: some-job\n" +
|
||||
" plan:\n" +
|
||||
" - in_parallel:\n" +
|
||||
" <*>"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reconcileSimpleTypes() throws Exception {
|
||||
Editor editor;
|
||||
@@ -4232,14 +4288,6 @@ public class ConcourseEditorTest {
|
||||
" plan:\n" +
|
||||
" in_"
|
||||
);
|
||||
editor.assertCompletionWithLabel("- in_parallel",
|
||||
"jobs:\n" +
|
||||
"- name: build-docker-image\n" +
|
||||
" serial: true\n" +
|
||||
" plan:\n" +
|
||||
" - in_parallel:\n" +
|
||||
" - <*>"
|
||||
);
|
||||
}
|
||||
|
||||
@Test public void relaxedContentAssist_primary_properties() throws Exception{
|
||||
|
||||
Reference in New Issue
Block a user