Add duplicate-key checking to concourse editor

This commit is contained in:
Kris De Volder
2016-12-21 08:46:47 -08:00
parent 302938ab75
commit 216e96156a
2 changed files with 51 additions and 1 deletions

View File

@@ -1,8 +1,12 @@
package org.springframework.ide.vscode.commons.yaml.reconcile;
import static org.springframework.ide.vscode.commons.yaml.ast.NodeUtil.asScalar;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
@@ -51,6 +55,7 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
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));
@@ -108,6 +113,28 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
}
}
private void checkForDuplicateKeys(MappingNode node) {
Set<String> duplicateKeys = new HashSet<>();
Set<String> seenKeys = new HashSet<>();
for (NodeTuple entry : node.getValue()) {
String key = asScalar(entry.getKeyNode());
if (key!=null) {
if (!seenKeys.add(key)) {
duplicateKeys.add(key);
}
}
}
if (!duplicateKeys.isEmpty()) {
for (NodeTuple entry : node.getValue()) {
Node keyNode = entry.getKeyNode();
String key = asScalar(keyNode);
if (key!=null && duplicateKeys.contains(key)) {
problem(keyNode, "Duplicate key '"+key+"'");
}
}
}
}
private void valueParseError(YType type, Node node, String parseErrorMsg) {
if (!StringUtil.hasText(parseErrorMsg)) {
parseErrorMsg= "Couldn't parse as '"+describe(type)+"'";

View File

@@ -439,7 +439,30 @@ public class PipelineYamlEditorTest {
, // =>
"repo-a<*>", "repo-b<*>"
);
}
@Test
public void reconcileDuplicateKeys() throws Exception {
Editor editor = harness.newEditor(
"resources:\n" +
"- name: my-repo\n" +
" type: git\n" +
" source:\n" +
" repository: https://github.com/kdvolder/my-repo\n" +
"resources:\n" +
"- name: your-repo\n" +
" type: git\n" +
" type: git\n" +
" source:\n" +
" repository: https://github.com/kdvolder/forked-repo\n"
);
editor.assertProblems(
"resources|Duplicate key",
"resources|Duplicate key",
"type|Duplicate key",
"type|Duplicate key"
);
}
//////////////////////////////////////////////////////////////////////////////