diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java index 81fe49912..1a4866160 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseModel.java @@ -372,25 +372,27 @@ public class ConcourseModel { }); } - public Multiset getResourceTypeNames(DynamicSchemaContext dc) { - Collection hints = getResourceTypeNameHints(dc); + public Multiset getResourceTypeNames(DynamicSchemaContext dc, boolean includeBuiltin) { + Collection hints = getResourceTypeNameHints(dc, includeBuiltin); if (hints!=null) { return ImmutableMultiset.copyOf(YTypeFactory.values(hints)); } return null; } - public Collection getResourceTypeNameHints(DynamicSchemaContext dc) { + public Collection getResourceTypeNameHints(DynamicSchemaContext dc, boolean includeBuiltin) { IDocument doc = dc.getDocument(); Multiset userDefined = getStringsFromAst(doc, RESOURCE_TYPE_NAMES_PATH); if (userDefined!=null) { Builder builder = ImmutableMultiset.builder(); builder.addAll(YTypeFactory.hints(userDefined)); - builder.addAll( - Arrays.stream(PipelineYmlSchema.BUILT_IN_RESOURCE_TYPES) - .map(h -> addExtraInsertion(h, dc)) - .collect(Collectors.toList()) - ); + if (includeBuiltin) { + builder.addAll( + Arrays.stream(PipelineYmlSchema.BUILT_IN_RESOURCE_TYPES) + .map(h -> addExtraInsertion(h, dc)) + .collect(Collectors.toList()) + ); + } return builder.build(); } return null; diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseValueParsers.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseValueParsers.java index a0564e2ac..2e19f4a44 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseValueParsers.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/ConcourseValueParsers.java @@ -49,7 +49,7 @@ public class ConcourseValueParsers { } public static SchemaContextAware resourceTypeNameDef(ConcourseModel models) { - return acceptOnlyUniqueNames(models::getResourceTypeNames, "resource-type name"); + return acceptOnlyUniqueNames(dc -> models.getResourceTypeNames(dc, false), "resource-type name"); } public static SchemaContextAware acceptOnlyUniqueNames( diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java index adc1e3b21..7ae77c52a 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java @@ -183,7 +183,7 @@ public class PipelineYmlSchema implements YamlSchema { return "The '"+parseString+"' Resource Type does not exist. Existing types: "+validValues; }, (DynamicSchemaContext dc) -> { - return PartialCollection.compute(() -> models.getResourceTypeNameHints(dc)); + return PartialCollection.compute(() -> models.getResourceTypeNameHints(dc, true)); } ); diff --git a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java index ff3841e2c..0108bff9e 100644 --- a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java +++ b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java @@ -732,6 +732,42 @@ public class ConcourseEditorTest { ); } + @Test + public void reconcileDuplicateResourceTypeNames_exempt_Builtins() throws Exception { + //See https://github.com/spring-projects/sts4/issues/196 + Editor editor; + + //Redefintion of built-in resource-type: no errors! + editor = harness.newEditor( + "resource_types:\n" + + "- name: docker-image\n" + + " privileged: true\n" + + " type: docker-image\n" + + " source:\n" + + " repository: concourse/docker-image-resource" + ); + editor.assertProblems(/*None*/); + + //... unless they are redefined twice... + editor = harness.newEditor( + "resource_types:\n" + + "- name: docker-image\n" + + " privileged: true\n" + + " type: docker-image\n" + + " source:\n" + + " repository: concourse/docker-image-resource\n" + + "- name: docker-image\n" + + " privileged: true\n" + + " type: docker-image\n" + + " source:\n" + + " repository: concourse/docker-image-resource" + ); + editor.assertProblems( + "docker-image|Duplicate", + "docker-image|Duplicate" + ); + } + @Test public void violatedPropertyConstraintsAreWarnings() throws Exception { Editor editor;