Check for duplicate defintions in bosh manifest
This commit is contained in:
@@ -18,6 +18,8 @@ import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParsers;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.ASTTypeCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.AbstractType;
|
||||
@@ -72,8 +74,10 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
private YType t_stemcell_alias_name_def;
|
||||
private YType t_release_name_def;
|
||||
private YType t_var_name_def;
|
||||
private final ASTTypeCache astTypes;
|
||||
|
||||
public BoshDeploymentManifestSchema() {
|
||||
public BoshDeploymentManifestSchema(ASTTypeCache astTypes) {
|
||||
this.astTypes = astTypes;
|
||||
TYPE_UTIL = f.TYPE_UTIL;
|
||||
|
||||
V2_TOPLEVEL_TYPE = createV2Schema();
|
||||
@@ -228,6 +232,10 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
for (String v1Prop : DEPRECATED_V1_PROPS) {
|
||||
addProp(v2Schema, v1Prop, t_any).isDeprecated("Deprecated: '"+v1Prop+"' is a V1 schema property. Consider migrating your deployment manifest to V2");
|
||||
}
|
||||
|
||||
for (YType defType : getDefinitionTypes()) {
|
||||
v2Schema.require(Constraints.uniqueDefinition(this.astTypes, defType, YamlSchemaProblems.problemType("BOSH_DUPLICATE_"+defType)));
|
||||
}
|
||||
return v2Schema;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ public class BoshLanguageServer extends SimpleLanguageServer {
|
||||
super("vscode-bosh");
|
||||
YamlASTProvider parser = new YamlParser(yaml);
|
||||
SimpleTextDocumentService documents = getTextDocumentService();
|
||||
BoshDeploymentManifestSchema schema = new BoshDeploymentManifestSchema();
|
||||
ASTTypeCache astTypeCache = new ASTTypeCache();
|
||||
BoshDeploymentManifestSchema schema = new BoshDeploymentManifestSchema(astTypeCache);
|
||||
|
||||
YamlStructureProvider structureProvider = YamlStructureProvider.DEFAULT;
|
||||
YamlAssistContextProvider contextProvider = new SchemaBasedYamlAssistContextProvider(schema);
|
||||
@@ -54,7 +55,6 @@ public class BoshLanguageServer extends SimpleLanguageServer {
|
||||
HoverInfoProvider infoProvider = new YamlHoverInfoProvider(parser, structureProvider, contextProvider);
|
||||
VscodeHoverEngine hoverEngine = new VscodeHoverEngineAdapter(this, infoProvider);
|
||||
YamlQuickfixes quickfixes = new YamlQuickfixes(getQuickfixRegistry(), getTextDocumentService(), structureProvider);
|
||||
ASTTypeCache astTypeCache = new ASTTypeCache();
|
||||
YamlSchemaBasedReconcileEngine engine = new YamlSchemaBasedReconcileEngine(parser, schema, quickfixes);
|
||||
engine.setTypeCollector(astTypeCache);
|
||||
documents.onDocumentSymbol(new TypeBasedYamlSymbolHandler(documents, astTypeCache, schema.getDefinitionTypes()));
|
||||
|
||||
@@ -681,4 +681,62 @@ public class BoshEditorTest {
|
||||
"blobstore_secure_link_secret|Variable"
|
||||
);
|
||||
}
|
||||
|
||||
@Test public void duplicateSymbolChecking() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"name: foo\n" +
|
||||
"variables:\n" +
|
||||
"- name: dup_var\n" +
|
||||
" type: password\n" +
|
||||
"- name: blobstore_admin_users_password\n" +
|
||||
" type: password\n" +
|
||||
"- name: blobstore_secure_link_secret\n" +
|
||||
" type: password\n" +
|
||||
"- name: dup_var\n" +
|
||||
" type: ssh\n" +
|
||||
"stemcells:\n" +
|
||||
"- alias: default\n" +
|
||||
" os: ubuntu-trusty\n" +
|
||||
" version: '3421.11'\n" +
|
||||
"- alias: dup_cell\n" +
|
||||
" os: ubuntu-trusty\n" +
|
||||
" version: '3421.11'\n" +
|
||||
"- alias: dup_cell\n" +
|
||||
" os: ubuntu-trusty\n" +
|
||||
" version: '3421.11'\n" +
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" networks:\n" +
|
||||
" - name: the-network\n" +
|
||||
" static_ips: []\n" +
|
||||
" default: []\n" +
|
||||
"- name: bar-group\n" +
|
||||
" networks:\n" +
|
||||
" - name: the-network\n" +
|
||||
" static_ips: []\n" +
|
||||
" default: []\n" +
|
||||
"- name: bar-group\n" +
|
||||
" networks:\n" +
|
||||
" - name: the-network\n" +
|
||||
" static_ips: []\n" +
|
||||
" default: []\n" +
|
||||
"releases:\n" +
|
||||
"- name: one-release\n" +
|
||||
"- name: other-release\n" +
|
||||
"- name: one-release\n"
|
||||
);
|
||||
editor.ignoreProblem(YamlSchemaProblems.MISSING_PROPERTY);
|
||||
|
||||
editor.assertProblems(
|
||||
"dup_var|Duplicate 'VariableName'",
|
||||
"dup_var|Duplicate 'VariableName'",
|
||||
"dup_cell|Duplicate 'StemcellAliasName'",
|
||||
"dup_cell|Duplicate 'StemcellAliasName'",
|
||||
"bar-group|Duplicate 'InstanceGroupName'",
|
||||
"bar-group|Duplicate 'InstanceGroupName'",
|
||||
"one-release|Duplicate 'ReleaseName'",
|
||||
"one-release|Duplicate 'ReleaseName'"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,15 +16,20 @@ import static org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaPr
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
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.reconcile.ASTTypeCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.ASTTypeCache.NodeTypes;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.SchemaContextAware;
|
||||
@@ -33,7 +38,11 @@ import org.yaml.snakeyaml.nodes.MappingNode;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
import org.yaml.snakeyaml.nodes.NodeTuple;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import com.google.common.collect.Multiset;
|
||||
|
||||
/**
|
||||
* Various static methods for constructing/composing {@link Constraint}s.
|
||||
@@ -156,4 +165,33 @@ public class Constraints {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all nodes of a given type, across the AST represent unique names.
|
||||
*/
|
||||
public static Constraint uniqueDefinition(ASTTypeCache astTypes, YType defType, ProblemType problemType) {
|
||||
return (DynamicSchemaContext dc, Node parent, Node _ignored_node, YType type, IProblemCollector problems) -> {
|
||||
NodeTypes nodeTypes = astTypes.getNodeTypes(dc.getDocument().getUri());
|
||||
if (nodeTypes!=null) {
|
||||
Collection<Node> nodes = nodeTypes.getNodes(defType);
|
||||
if (nodes!=null && !nodes.isEmpty()) {
|
||||
Multimap<String, Node> name2nodes = ArrayListMultimap.create();
|
||||
for (Node node : nodes) {
|
||||
String name = NodeUtil.asScalar(node);
|
||||
if (StringUtil.hasText(name)) {
|
||||
name2nodes.put(name, node);
|
||||
}
|
||||
}
|
||||
for (String name : name2nodes.keys()) {
|
||||
Collection<Node> nodesForName = name2nodes.get(name);
|
||||
if (nodesForName.size()>1) {
|
||||
for (Node duplicateNode : nodesForName) {
|
||||
problems.accept(YamlSchemaProblems.problem(problemType, "Duplicate '"+defType+"'", duplicateNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user