diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/ast/NodeUtil.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/ast/NodeUtil.java
index 0b686c596..ef99875a6 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/ast/NodeUtil.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/ast/NodeUtil.java
@@ -54,7 +54,7 @@ public class NodeUtil {
* @return String value or null if node is not a Scalar node.
*/
public static String asScalar(Node node) {
- if (node.getNodeId()==NodeId.scalar) {
+ if (node!=null && node.getNodeId()==NodeId.scalar) {
return ((ScalarNode)node).getValue();
}
return null;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/ASTCursor.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/ASTCursor.java
new file mode 100644
index 000000000..26a667af9
--- /dev/null
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/ASTCursor.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Pivotal, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Pivotal, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.springframework.ide.vscode.commons.yaml.path;
+
+import java.util.stream.Stream;
+
+import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
+import org.yaml.snakeyaml.nodes.Node;
+
+/**
+ * Pointer to a specific node in Snake yaml parse tree. Supports navigation
+ * using {@link YamlPath}s, including support for 'ambiguous' steps like
+ * {@link YamlPathSegment}.anyChild()
+ *
+ * Because the 'root node' of a parsed Yaml file is not actually {@link Node}
+ * in snake yaml. A cursor pointing at the root of a tree is implemented
+ * differently than a pointer to a node inside the tree. Therefore
+ * this class is abstract and has two concrete subclasses.
+ *
+ * @author Kris De Volder
+ */
+public abstract class ASTCursor implements YamlNavigable {
+
+ public abstract Stream traverseAmbiguously(YamlPathSegment s);
+
+ /**
+ * Return the node this cursor is pointing to. This is either a {@link Node} or
+ * a {@link YamlFileAST}.
+ */
+ public abstract Object getNode();
+
+}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/ASTRootCursor.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/ASTRootCursor.java
new file mode 100644
index 000000000..22e58e8bf
--- /dev/null
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/ASTRootCursor.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Pivotal, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Pivotal, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.springframework.ide.vscode.commons.yaml.path;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.springframework.ide.vscode.commons.util.Assert;
+import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
+import org.yaml.snakeyaml.nodes.Node;
+
+public class ASTRootCursor extends ASTCursor {
+
+ private final YamlFileAST currentNode;
+
+ public ASTRootCursor(YamlFileAST astRoot) {
+ Assert.isNotNull(astRoot);
+ this.currentNode = astRoot;
+ }
+
+ @Override
+ public YamlFileAST getNode() {
+ return currentNode;
+ }
+
+ @Override
+ public Stream traverseAmbiguously(YamlPathSegment s) {
+ switch (s.getType()) {
+ case KEY_AT_KEY: {
+ return Stream.empty();
+ }
+ case ANY_CHILD: {
+ return getNode().getNodes().stream().map(NodeCursor::new);
+ }
+ case VAL_AT_INDEX: {
+ List nodes = getNode().getNodes();
+ int index = s.toIndex();
+ int size = nodes.size();
+ if (index= 0) {
+ return Stream.of(new NodeCursor(nodes.get(index)));
+ }
+ return Stream.empty();
+ }
+ case VAL_AT_KEY: {
+ return Stream.empty();
+ }
+ default:
+ Assert.isLegal(false, "Bug? Missing switch case?");
+ return Stream.empty();
+ }
+ }
+
+}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/NodeCursor.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/NodeCursor.java
index 732d1eeec..d9975245c 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/NodeCursor.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/NodeCursor.java
@@ -14,8 +14,6 @@ import java.util.stream.Stream;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
-import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment.KeyAtKey;
-import org.yaml.snakeyaml.nodes.CollectionNode;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.SequenceNode;
@@ -27,7 +25,7 @@ import org.yaml.snakeyaml.nodes.SequenceNode;
*
* @author Kris De Volder
*/
-public class NodeCursor implements YamlNavigable {
+public class NodeCursor extends ASTCursor {
private final Node currentNode;
@@ -35,9 +33,11 @@ public class NodeCursor implements YamlNavigable {
Assert.isNotNull(node);
this.currentNode = node;
}
+
+
@Override
- public Stream traverseAmbiguously(YamlPathSegment s) {
+ public Stream traverseAmbiguously(YamlPathSegment s) {
switch (s.getType()) {
case KEY_AT_KEY: {
String key = s.toPropString();
@@ -87,6 +87,7 @@ public class NodeCursor implements YamlNavigable {
}
}
+ @Override
public Node getNode() {
return currentNode;
}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java
index 9c601d744..98076aefa 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java
@@ -17,6 +17,7 @@ import java.util.stream.Stream;
import org.springframework.ide.vscode.commons.yaml.ast.NodeRef;
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
+import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
import org.springframework.ide.vscode.commons.yaml.ast.NodeRef.RootRef;
import org.springframework.ide.vscode.commons.yaml.ast.NodeRef.SeqRef;
import org.springframework.ide.vscode.commons.yaml.ast.NodeRef.TupleValueRef;
@@ -121,6 +122,14 @@ public class YamlPath {
newPath[segments.length] = s;
return new YamlPath(newPath);
}
+
+ public Node traverseToNode(YamlFileAST root) {
+ ASTCursor cursor = traverse(new ASTRootCursor(root));
+ if (cursor instanceof NodeCursor) {
+ return ((NodeCursor)cursor).getNode();
+ }
+ return null;
+ }
public > T traverse(T startNode) {
return traverseAmbiguously(startNode).findFirst().orElse(null);
@@ -129,8 +138,7 @@ public class YamlPath {
public Stream traverseAmbiguously(Node startNode) {
if (startNode!=null) {
return traverseAmbiguously(new NodeCursor(startNode))
- .map(NodeCursor::getNode);
-
+ .map((ASTCursor cursor) -> (Node)cursor.getNode());
}
return Stream.empty();
}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/SchemaBasedYamlASTReconciler.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/SchemaBasedYamlASTReconciler.java
index 32532108a..38879041e 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/SchemaBasedYamlASTReconciler.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/reconcile/SchemaBasedYamlASTReconciler.java
@@ -26,6 +26,8 @@ import org.springframework.ide.vscode.commons.util.ValueParser;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
+import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
+import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
import org.springframework.ide.vscode.commons.yaml.schema.ASTDynamicSchemaContext;
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
@@ -54,23 +56,26 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
public void reconcile(YamlFileAST ast) {
List nodes = ast.getNodes();
if (nodes!=null && !nodes.isEmpty()) {
- for (Node node : nodes) {
- reconcile(ast.getDocument(), node, schema.getTopLevelType());
+ for (int i = 0; i < nodes.size(); i++) {
+ Node node = nodes.get(i);
+ reconcile(ast.getDocument(), new YamlPath(YamlPathSegment.valueAt(i)), node, schema.getTopLevelType());
}
}
}
- private void reconcile(IDocument doc, Node node, YType type) {
+ private void reconcile(IDocument doc, YamlPath path, Node node, YType type) {
if (type!=null) {
- DynamicSchemaContext schemaContext = new ASTDynamicSchemaContext(doc, node);
+ DynamicSchemaContext schemaContext = new ASTDynamicSchemaContext(doc, path, node);
+ type = typeUtil.inferMoreSpecificType(type, schemaContext);
switch (node.getNodeId()) {
case mapping:
MappingNode map = (MappingNode) node;
checkForDuplicateKeys(map);
if (typeUtil.isMap(type)) {
for (NodeTuple entry : map.getValue()) {
- reconcile(doc, entry.getKeyNode(), typeUtil.getKeyType(type));
- reconcile(doc, entry.getValueNode(), typeUtil.getDomainType(type));
+ String key = NodeUtil.asScalar(entry.getKeyNode());
+ reconcile(doc, keyAt(path, key), entry.getKeyNode(), typeUtil.getKeyType(type));
+ reconcile(doc, valueAt(path, key), entry.getValueNode(), typeUtil.getDomainType(type));
}
} else if (typeUtil.isBean(type)) {
Map beanProperties = typeUtil.getPropertiesMap(type, schemaContext);
@@ -82,10 +87,9 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
} else {
YTypedProperty prop = beanProperties.get(key);
if (prop==null) {
- type = typeUtil.inferMoreSpecificType(type, schemaContext);
unknownBeanProperty(keyNode, type, key);
} else {
- reconcile(doc, entry.getValueNode(), prop.getType());
+ reconcile(doc, valueAt(path, key), entry.getValueNode(), prop.getType());
}
}
}
@@ -96,8 +100,9 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
case sequence:
SequenceNode seq = (SequenceNode) node;
if (typeUtil.isSequencable(type)) {
- for (Node el : seq.getValue()) {
- reconcile(doc, el, typeUtil.getDomainType(type));
+ for (int i = 0; i < seq.getValue().size(); i++) {
+ Node el = seq.getValue().get(i);
+ reconcile(doc, valueAt(path, i), el, typeUtil.getDomainType(type));
}
} else {
expectTypeButFoundSequence(type, node);
@@ -124,6 +129,27 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
}
}
+ private YamlPath keyAt(YamlPath path, String key) {
+ if (path!=null && key!=null) {
+ return path.append(YamlPathSegment.keyAt(key));
+ }
+ return null;
+ }
+
+ private YamlPath valueAt(YamlPath path, int index) {
+ if (path!=null) {
+ return path.append(YamlPathSegment.valueAt(index));
+ }
+ return null;
+ }
+
+ private YamlPath valueAt(YamlPath path, String key) {
+ if (path!=null && key!=null) {
+ return path.append(YamlPathSegment.valueAt(key));
+ }
+ return null;
+ }
+
private void checkForDuplicateKeys(MappingNode node) {
Set duplicateKeys = new HashSet<>();
Set seenKeys = new HashSet<>();
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/ASTDynamicSchemaContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/ASTDynamicSchemaContext.java
index d6b7aed09..f2508fa3e 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/ASTDynamicSchemaContext.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/ASTDynamicSchemaContext.java
@@ -15,6 +15,7 @@ import java.util.Set;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
+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.NodeTuple;
@@ -31,9 +32,11 @@ public class ASTDynamicSchemaContext extends CachingSchemaContext {
private MappingNode mapNode;
private IDocument doc;
+ private YamlPath path;
- public ASTDynamicSchemaContext(IDocument doc, Node node) {
+ public ASTDynamicSchemaContext(IDocument doc, YamlPath path, Node node) {
this.doc = doc;
+ this.path = path;
this.mapNode = as(MappingNode.class, node);
}
@@ -64,4 +67,9 @@ public class ASTDynamicSchemaContext extends CachingSchemaContext {
public IDocument getDocument() {
return doc;
}
+
+ @Override
+ public YamlPath getPath() {
+ return path;
+ }
}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/DynamicSchemaContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/DynamicSchemaContext.java
index fcf5450a9..211e93f41 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/DynamicSchemaContext.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/DynamicSchemaContext.java
@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.commons.yaml.schema;
import java.util.Set;
import org.springframework.ide.vscode.commons.util.text.IDocument;
+import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
import com.google.common.collect.ImmutableSet;
@@ -38,6 +39,12 @@ public interface DynamicSchemaContext {
public IDocument getDocument() {
return null;
}
+
+ @Override
+ public YamlPath getPath() {
+ return null;
+ }
+
};
/**
@@ -60,4 +67,9 @@ public interface DynamicSchemaContext {
*/
IDocument getDocument();
+ /**
+ * Returns the yamlpath leading to the current node.
+ */
+ YamlPath getPath();
+
}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java
index 7f25f284a..9d6818ecc 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java
@@ -18,6 +18,7 @@ import java.util.Set;
import org.springframework.ide.vscode.commons.util.CollectionUtil;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.text.IDocument;
+import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SChildBearingNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SKeyNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode;
@@ -61,5 +62,11 @@ public class SNodeDynamicSchemaContext extends CachingSchemaContext {
return contextNode.getDocument();
}
+ @Override
+ public YamlPath getPath() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java
index 20c02c500..e7e8f74d6 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java
@@ -44,6 +44,10 @@ import com.google.common.collect.ImmutableMap;
*/
public class YTypeFactory {
+ public YType contextAware(String name, SchemaContextAware guessType) {
+ return new YContextSensitive(name, guessType);
+ }
+
public YType yany(String name) {
return new YAny(name);
}
@@ -264,6 +268,32 @@ public class YTypeFactory {
}
}
+
+ /**
+ * Represents a type that depends on the DynamicSchemaContext
+ */
+ public static class YContextSensitive extends YAny {
+
+ private final SchemaContextAware typeGuesser;
+
+ public YContextSensitive(String name, SchemaContextAware typeGuesser) {
+ super(name);
+ this.typeGuesser = typeGuesser;
+ }
+
+ @Override
+ public YType inferMoreSpecificType(DynamicSchemaContext dc) {
+ if (dc!=null) {
+ YType inferred = typeGuesser.withContext(dc);
+ if (inferred!=null) {
+ return inferred;
+ }
+ }
+ return this;
+ }
+
+ }
+
/**
* Represents a type that is completely unconstrained. Anything goes: A map, a sequence or some
@@ -415,7 +445,7 @@ public class YTypeFactory {
* this property is being assigned a value we can infer from that which
* specific bean-type we are dealing with.
*/
- public class YBeanUnionType extends AbstractType {
+ public static class YBeanUnionType extends AbstractType {
private final String name;
private List types;
@@ -424,10 +454,13 @@ public class YTypeFactory {
public YBeanUnionType(String name, YBeanType... types) {
this.name = name;
- this.types = new ArrayList<>(Arrays.asList(types));
+ this.types = new ArrayList<>();
+ for (YBeanType t : types) {
+ addUnionMember(t);
+ }
}
- public synchronized void addUnionMember(YBeanType type) {
+ private void addUnionMember(YBeanType type) {
types.add(type);
}
diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java
index 4128b2b7b..1a5731099 100644
--- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java
+++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java
@@ -122,7 +122,15 @@ public class ConcourseModel {
return null;
}
- private YamlFileAST getAst(IDocument doc) throws Exception {
+ public YamlFileAST getSafeAst(IDocument doc) {
+ try {
+ return getAst(doc);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public YamlFileAST getAst(IDocument doc) throws Exception {
return getAstProvider(true).getAST(doc);
}
diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java
index b079d81e5..76822796d 100644
--- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java
+++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java
@@ -10,8 +10,14 @@
*******************************************************************************/
package org.springframework.ide.vscode.concourse;
+import java.util.Set;
+
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.util.Renderables;
+import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
+import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
+import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
+import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory;
@@ -153,18 +159,39 @@ public class PipelineYmlSchema implements YamlSchema {
prop(doStep, "do", f.yseq(step));
prop(tryStep, "try", step);
- // shared properties applicable for any type of Step:
- prop(step, "on_success", step);
- prop(step, "on_failure", step);
- prop(step, "ensure", step);
- prop(step, "attempts", t_strictly_pos_integer);
- prop(step, "tags", t_strings);
- prop(step, "timeout", t_duration);
+ // shared properties applicable for any subtype of Step:
+ for (YBeanType subStep : stepTypes) {
+ prop(step, subStep, "on_success", step);
+ prop(step, subStep, "on_failure", step);
+ prop(step, subStep, "ensure", step);
+ prop(step, subStep, "attempts", t_strictly_pos_integer);
+ prop(step, subStep, "tags", t_strings);
+ prop(step, subStep, "timeout", t_duration);
+ }
+
+ YType gitResourceSource = t_any;
+
+ YType resourceSource = f.contextAware("ResourceSource", (dc) -> {
+ YamlPath path = dc.getPath();
+ if (path!=null) {
+ YamlFileAST root = models.getSafeAst(dc.getDocument());
+ if (root!=null) {
+ String typeTag = NodeUtil.asScalar(path.dropLast().append(YamlPathSegment.valueAt("type")).traverseToNode(root));
+ switch (typeTag) {
+ case "git":
+ return gitResourceSource;
+ default:
+ break;
+ }
+ }
+ }
+ return t_any;
+ });
YBeanType resource = f.ybean("Resource");
prop(resource, "name", resourceNameDef);
prop(resource, "type", t_resource_type_name);
- prop(resource, "source", t_any);
+ prop(resource, "source", resourceSource);
prop(resource, "check_every", t_duration);
YBeanType job = f.ybean("Job");
@@ -194,8 +221,12 @@ public class PipelineYmlSchema implements YamlSchema {
}
+ private void prop(AbstractType superType, AbstractType bean, String name, YType type) {
+ bean.addProperty(name, type, descriptionFor(superType, name));
+ }
+
private void prop(AbstractType bean, String name, YType type) {
- bean.addProperty(name, type, descriptionFor(bean, name));
+ prop(bean, bean, name, type);
}
private Renderable descriptionFor(YType owner, String propName) {
diff --git a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java
index 2f4124c2f..8c5a24b6a 100644
--- a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java
+++ b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java
@@ -638,6 +638,23 @@ public class PipelineYamlEditorTest {
"not-a-resource|does not exist"
);
}
+
+ @Test
+ public void reconcileGitResource() throws Exception {
+ Editor editor = harness.newEditor(
+ "resources:\n" +
+ "- name: sts4-out\n" +
+ " type: git\n" +
+ " source:\n" +
+ " uri: git@github.com:spring-projects/sts4.git\n" +
+ " bogus: bad\n" +
+ " branch: {{branch}}\n" +
+ " private_key: {{rsa_id}}\n"
+ );
+ editor.assertProblems(
+ "bogus|Unknown property"
+ );
+ }
@Test
public void contentAssistJobNames() throws Exception {