From 1fb5c6ddebdb437c0129cde9a32227458f828e5f Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Fri, 20 Jan 2017 18:13:55 -0800 Subject: [PATCH] Required properties in Concourse Editor --- .../SchemaBasedYamlASTReconciler.java | 3 +- .../vscode/concourse/PipelineYmlSchema.java | 19 ++--- .../concourse/ResourceTypeRegistry.java | 7 +- .../concourse/PipelineYamlEditorTest.java | 80 +++++++++++++++++++ 4 files changed, 94 insertions(+), 15 deletions(-) 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 8bdbbcf5b..581baef8f 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 @@ -18,6 +18,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -182,7 +183,7 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler { .filter(YTypedProperty::isRequired) .map(YTypedProperty::getName) .filter((required) -> !foundProps.contains(required)) - .collect(Collectors.toSet()); + .collect(Collectors.toCollection(TreeSet::new)); if (!missingProps.isEmpty()) { String message; if (missingProps.size()==1) { 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 e290d3cb5..dc901fd29 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 @@ -177,13 +177,9 @@ public class PipelineYmlSchema implements YamlSchema { addProp(step, subStep, "timeout", t_duration); } - YType resourceSource = f.contextAware("ResourceSource", (dc) -> { - String typeTag = getResourceTypeTag(models, dc); - if (typeTag!=null) { - return resourceTypes.getSourceType(typeTag); - } - return null; - }); + YType resourceSource = f.contextAware("ResourceSource", (dc) -> + resourceTypes.getSourceType(getResourceTypeTag(models, dc)) + ); YBeanType resource = f.ybean("Resource"); addProp(resource, "name", resourceNameDef).isRequired(true); @@ -202,12 +198,12 @@ public class PipelineYmlSchema implements YamlSchema { addProp(job, "disable_manual_trigger", t_boolean); YBeanType resourceType = f.ybean("ResourceType"); - addProp(resourceType, "name", t_ne_string); - addProp(resourceType, "type", t_image_type); - addProp(resourceType, "source", t_any); + addProp(resourceType, "name", t_ne_string).isRequired(true); + addProp(resourceType, "type", t_image_type).isRequired(true); + addProp(resourceType, "source", resourceSource); YBeanType group = f.ybean("Group"); - addProp(group, "name", t_ne_string); + addProp(group, "name", t_ne_string).isRequired(true); addProp(group, "resources", f.yseq(resourceName)); addProp(group, "jobs", f.yseq(jobName)); @@ -256,7 +252,6 @@ public class PipelineYmlSchema implements YamlSchema { return prop; } - private YTypedPropertyImpl addProp(AbstractType superType, AbstractType bean, String name, YType type) { YTypedPropertyImpl p = prop(superType, name, type); bean.addProperty(p); diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ResourceTypeRegistry.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ResourceTypeRegistry.java index f5bf907e3..62b3a9fb8 100644 --- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ResourceTypeRegistry.java +++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ResourceTypeRegistry.java @@ -20,7 +20,7 @@ import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YBeanType /** * Keeps track of known resource types. For now this only keeps track of the resource-types that * are built-in to concourse. - * + * * @author Kris De Volder */ public class ResourceTypeRegistry { @@ -36,7 +36,10 @@ public class ResourceTypeRegistry { } public YType getSourceType(String typeTag) { - return sourceTypes.get(typeTag); + if (typeTag!=null) { + return sourceTypes.get(typeTag); + } + return null; } } 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 f71af4f22..dd59454ea 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 @@ -835,6 +835,86 @@ public class PipelineYamlEditorTest { editor.assertHoverContains("check_every", "The interval on which to check for new versions"); } + @Test public void requiredPropertiesReconcile() throws Exception { + Editor editor; + + //addProp(resource, "name", resourceNameDef).isRequired(true); + editor = harness.newEditor( + "resources:\n" + + "- type: foo" + ); + editor.assertProblems("type: foo|'name' is required"); + + //addProp(resource, "type", t_resource_type_name).isRequired(true); + editor = harness.newEditor( + "resources:\n" + + "- name: foo" + ); + editor.assertProblems("name: foo|'type' is required"); + + //Both name and type missing: + editor = harness.newEditor( + "resources:\n" + + "- source: {}" + ); + editor.assertProblems("source: {}|[name, type] are required"); + + //addProp(job, "name", jobNameDef).isRequired(true); + editor = harness.newEditor( + "jobs:\n" + + "- name: foo" + ); + editor.assertProblems("name: foo|'plan' is required"); + + //addProp(job, "plan", f.yseq(step)).isRequired(true); + editor = harness.newEditor( + "jobs:\n" + + "- plan: []" + ); + editor.assertProblems("plan: []|'name' is required"); + + //addProp(resourceType, "name", t_ne_string).isRequired(true); + editor = harness.newEditor( + "resource_types:\n" + + "- type: docker-image" + ); + editor.assertProblems("type: docker-image|'name' is required"); + + //addProp(resourceType, "type", t_image_type).isRequired(true); + editor = harness.newEditor( + "resource_types:\n" + + "- name: foo" + ); + editor.assertProblems("name: foo|'type' is required"); + + //addProp(gitSource, "uri", t_string).isRequired(true); + editor = harness.newEditor( + "resources:\n" + + "- name: foo\n" + + " type: git\n" + + " source:\n" + + " branch: master" + ); + editor.assertProblems("branch: master|'uri' is required"); + + //addProp(gitSource, "branch", t_string).isRequired(true); + editor = harness.newEditor( + "resources:\n" + + "- name: foo\n" + + " type: git\n" + + " source:\n" + + " uri: https://yada" + ); + editor.assertProblems("uri: https://yada|'branch' is required"); + + //addProp(group, "name", t_ne_string).isRequired(true); + editor = harness.newEditor( + "groups:\n" + + "- jobs: []" + ); + editor.assertProblems("jobs: []|'name' is required"); + } + ////////////////////////////////////////////////////////////////////////////// private void assertContextualCompletions(String conText, String textBefore, String... textAfter) throws Exception {