From ca3f3fc9072d09b89e423daa9cedf0a386266639 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Fri, 23 Dec 2016 19:18:22 -0800 Subject: [PATCH] Conourse: reconcile checks for duplicate job names --- .../ide/vscode/concourse/ConcourseModel.java | 6 +----- .../vscode/concourse/PipelineYmlSchema.java | 4 +++- .../ide/vscode/concourse/ValueParsers.java | 21 +++++++++++++++++-- .../concourse/PipelineYamlEditorTest.java | 14 +++++++++++++ 4 files changed, 37 insertions(+), 8 deletions(-) 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 bc4882e76..4128b2b7b 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 @@ -13,10 +13,7 @@ package org.springframework.ide.vscode.concourse; import static org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment.anyChild; import static org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment.valueAt; -import java.util.Collection; -import java.util.Set; import java.util.function.Function; -import java.util.stream.Collectors; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.languageserver.util.TextDocumentContentChange; @@ -34,7 +31,6 @@ import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.nodes.Node; import com.google.common.collect.Multiset; -import com.google.common.collect.Multisets; /** * ConcourseModels is responsible for extracting various bits of information @@ -119,7 +115,7 @@ public class ConcourseModel { } } } catch (YAMLException e) { - // ignore: garbage in the doc. Can't compute stuff and that's to be expected. + // ignore: found garbage in the doc. Can't compute stuff and that's to be expected. } catch (Exception e) { Log.log(e); } 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 2267b2f6a..325f54531 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 @@ -109,6 +109,8 @@ public class PipelineYmlSchema implements YamlSchema { YAtomicType resourceNameDef = f.yatomic("Resource Name"); resourceNameDef.parseWith(ValueParsers.resourceNameDef(models)); + YAtomicType jobNameDef = f.yatomic("Job Name"); + jobNameDef.parseWith(ValueParsers.jobNameDef(models)); YBeanType getStep = f.ybean("GetStep"); prop(getStep, "get", resourceName); @@ -165,7 +167,7 @@ public class PipelineYmlSchema implements YamlSchema { prop(resource, "source", t_any); YBeanType job = f.ybean("Job"); - prop(job, "name", t_ne_string); + prop(job, "name", jobNameDef); prop(job, "serial", t_boolean); prop(job, "build_logs_to_retain", t_pos_integer); prop(job, "serial_groups", t_strings); diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ValueParsers.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ValueParsers.java index 5368ff505..a6f1b7ffa 100644 --- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ValueParsers.java +++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/ValueParsers.java @@ -10,10 +10,13 @@ *******************************************************************************/ package org.springframework.ide.vscode.concourse; +import java.util.function.Function; + import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.commons.util.RegexpParser; import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.ValueParser; +import org.springframework.ide.vscode.commons.util.text.IDocument; import org.springframework.ide.vscode.commons.yaml.schema.SchemaContextAware; import com.google.common.collect.Multiset; @@ -25,6 +28,8 @@ import com.google.common.collect.Multiset; * @author Kris De Volder */ public class ValueParsers { + + //TODO: some of the parsers here are pretty general purpose and could be moved to commons. public static final ValueParser NE_STRING = (s) -> { if (StringUtil.hasText(s)) { @@ -37,14 +42,25 @@ public class ValueParsers { public static final ValueParser POS_INTEGER = integerRange(0, null); public static final SchemaContextAware resourceNameDef(ConcourseModel models) { + return acceptOnlyUniqueNames(models::getResourceNames, "resource name"); + } + + public static final SchemaContextAware jobNameDef(ConcourseModel models) { + return acceptOnlyUniqueNames(models::getJobNames, "job name"); + } + + public static SchemaContextAware acceptOnlyUniqueNames( + Function> getDefinedNameCounts, + String typeName + ) { return (dc) -> { - Multiset resourceNames = models.getResourceNames(dc.getDocument()); + Multiset resourceNames = getDefinedNameCounts.apply(dc.getDocument()); return (String input) -> { if (resourceNames.count(input)<=1) { //okay return resourceNames; } - throw new IllegalArgumentException("Duplicate resource name '"+input+"'"); + throw new IllegalArgumentException("Duplicate "+typeName+" '"+input+"'"); }; }; }; @@ -82,6 +98,7 @@ public class ValueParsers { + " '2h45m'. Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', " + "'m', 'h'." ); + 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 7ed9b2e08..30abba30c 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 @@ -502,6 +502,20 @@ public class PipelineYamlEditorTest { ); } + @Test + public void reconcileDuplicateJobNames() throws Exception { + Editor editor = harness.newEditor( + "jobs:\n" + + "- name: job-1\n" + + "- name: utils\n" + + "- name: job-1\n" + ); + editor.assertProblems( + "job-1|Duplicate job name", + "job-1|Duplicate job name" + ); + } + @Test public void completionsResourceReferences() throws Exception { assertContextualCompletions(