Laying the groundwork for GitResourceSource type support
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
* <p>
|
||||
* 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<ASTCursor> {
|
||||
|
||||
public abstract Stream<ASTCursor> 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();
|
||||
|
||||
}
|
||||
@@ -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<ASTCursor> 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<Node> nodes = getNode().getNodes();
|
||||
int index = s.toIndex();
|
||||
int size = nodes.size();
|
||||
if (index<size && 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<NodeCursor> {
|
||||
public class NodeCursor extends ASTCursor {
|
||||
|
||||
private final Node currentNode;
|
||||
|
||||
@@ -35,9 +33,11 @@ public class NodeCursor implements YamlNavigable<NodeCursor> {
|
||||
Assert.isNotNull(node);
|
||||
this.currentNode = node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Stream<NodeCursor> traverseAmbiguously(YamlPathSegment s) {
|
||||
public Stream<ASTCursor> traverseAmbiguously(YamlPathSegment s) {
|
||||
switch (s.getType()) {
|
||||
case KEY_AT_KEY: {
|
||||
String key = s.toPropString();
|
||||
@@ -87,6 +87,7 @@ public class NodeCursor implements YamlNavigable<NodeCursor> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getNode() {
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
@@ -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 extends YamlNavigable<T>> T traverse(T startNode) {
|
||||
return traverseAmbiguously(startNode).findFirst().orElse(null);
|
||||
@@ -129,8 +138,7 @@ public class YamlPath {
|
||||
public Stream<Node> traverseAmbiguously(Node startNode) {
|
||||
if (startNode!=null) {
|
||||
return traverseAmbiguously(new NodeCursor(startNode))
|
||||
.map(NodeCursor::getNode);
|
||||
|
||||
.map((ASTCursor cursor) -> (Node)cursor.getNode());
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@@ -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<Node> 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<String, YTypedProperty> 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<String> duplicateKeys = new HashSet<>();
|
||||
Set<String> seenKeys = new HashSet<>();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,10 @@ import com.google.common.collect.ImmutableMap;
|
||||
*/
|
||||
public class YTypeFactory {
|
||||
|
||||
public YType contextAware(String name, SchemaContextAware<YType> 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<YType> typeGuesser;
|
||||
|
||||
public YContextSensitive(String name, SchemaContextAware<YType> 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<YBeanType> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user