From 776e35c8c89a6734a09738607d7e38caad6f46dd Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Wed, 12 Apr 2017 17:36:39 -0700 Subject: [PATCH] Make 'none' flagged as deprecated in manifest.yml --- .../commons/yaml/schema/YTypeFactory.java | 66 +++++++++++++++++-- .../manifest/yaml/ManifestYmlSchema.java | 4 +- .../manifest/yaml/ManifestYamlEditorTest.java | 14 +++- 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java index 689be120c..79d8bfa6c 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java @@ -13,6 +13,7 @@ package org.springframework.ide.vscode.commons.yaml.schema; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -24,12 +25,16 @@ import java.util.concurrent.Callable; import java.util.function.BiFunction; import java.util.stream.Collectors; +import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileException; import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.commons.util.EnumValueParser; import org.springframework.ide.vscode.commons.util.Renderable; import org.springframework.ide.vscode.commons.util.Renderables; +import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.ValueParser; +import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems; import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.AbstractType; +import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.EnumTypeBuilder; import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint; import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraints; @@ -38,6 +43,8 @@ import com.google.common.collect.ImmutableList.Builder; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import reactor.core.publisher.Flux; + /** * Static utility method for creating YType objects representing either * 'array-like', 'map-like' or 'object-like' types which can be used @@ -47,6 +54,56 @@ import com.google.common.collect.ImmutableSet; */ public class YTypeFactory { + public class EnumTypeBuilder { + + private String name; + private String[] values; + + private Map deprecationMsgs = new HashMap<>(); + + public EnumTypeBuilder(String name, String[] values) { + this.name = name; + this.values = values; + } + + public YAtomicType build() { + EnumValueParser basicParser = new EnumValueParser(name, values); + YAtomicType t = yatomic(name); + t.addHints(getNonDeprecatedValues()); + if (deprecationMsgs.isEmpty()) { + t.parseWith(basicParser); + } else { + t.parseWith(ValueParser.of((String value) -> { + basicParser.parse(value); + if (deprecationMsgs.containsKey(value)) { + String msg = deprecationMsgs.get(value); + if (!StringUtil.hasText(msg)) { + msg = "'"+value+"' is deprecated"; + } + throw new ReconcileException(msg, YamlSchemaProblems.DEPRECATED_PROPERTY); + } + return value; + })); + } + return t; + } + + public EnumTypeBuilder deprecate(String value, String msg) { + Assert.isLegal(ImmutableSet.copyOf(values).contains(value)); + deprecationMsgs.put(value, msg); + return this; + } + + private String[] getNonDeprecatedValues() { + return Flux.fromArray(values) + .filter((value) -> !deprecationMsgs.containsKey(value)) + .collectList() + .map(l -> l.toArray(new String[l.size()])) + .block(); + } + + } + public YContextSensitive contextAware(String name, SchemaContextAware guessType) { return new YContextSensitive(name, guessType); } @@ -715,6 +772,10 @@ public class YTypeFactory { return t; } + public EnumTypeBuilder yenumBuilder(String name, String... values) { + return new EnumTypeBuilder(name, values); + } + public YAtomicType yenum(String name, BiFunction, String> errorMessageFormatter, SchemaContextAware> values) { YAtomicType t = yatomic(name); t.addHintProvider((dc) -> { @@ -742,10 +803,7 @@ public class YTypeFactory { } public YAtomicType yenum(String name, String... values) { - YAtomicType t = yatomic(name); - t.addHints(values); - t.parseWith(new EnumValueParser(name, values)); - return t; + return new EnumTypeBuilder(name, values).build(); } public static Callable> valuesFromHintProvider(Callable> hintProvider) { diff --git a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlSchema.java b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlSchema.java index 2e4397632..28f897508 100644 --- a/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlSchema.java +++ b/headless-services/manifest-yaml-language-server/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlSchema.java @@ -107,7 +107,9 @@ public class ManifestYmlSchema implements YamlSchema { t_memory.addHints("256M", "512M", "1024M"); t_memory.parseWith(ManifestYmlValueParsers.MEMORY); - YAtomicType t_health_check_type = f.yenum("Health Check Type", "none", "process", "port", "http"); + YAtomicType t_health_check_type = f.yenumBuilder("Health Check Type", "none", "process", "port", "http") + .deprecate("none", "The value 'none' is deprecated in favor of 'process'") + .build(); YAtomicType t_strictly_pos_integer = f.yatomic("Strictly Positive Integer"); t_strictly_pos_integer.parseWith(ManifestYmlValueParsers.integerAtLeast(1)); diff --git a/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java b/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java index 8f2623c9a..e2c4c84ea 100644 --- a/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java +++ b/headless-services/manifest-yaml-language-server/src/test/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlEditorTest.java @@ -17,6 +17,7 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; import java.io.IOException; +import java.util.List; import org.eclipse.lsp4j.CompletionItem; import org.eclipse.lsp4j.Diagnostic; @@ -408,7 +409,7 @@ public class ManifestYamlEditorTest { assertCompletions("health-check-type: <*>", "health-check-type: http<*>", - "health-check-type: none<*>", +// "health-check-type: none<*>", Still valid, but not suggested because its deprecated "health-check-type: port<*>", "health-check-type: process<*>" ); @@ -498,6 +499,17 @@ public class ManifestYamlEditorTest { editor.assertHoverContains("health-check-type", "Use the `health-check-type` attribute to"); } + @Test + public void deprecatedHealthCheckTypeNone() throws Exception { + Editor editor = harness.newEditor( + "applications:\n" + + "- name: foo\n" + + " health-check-type: none" + ); + Diagnostic problem = editor.assertProblems("none|'none' is deprecated in favor of 'process'").get(0); + assertEquals(DiagnosticSeverity.Warning, problem.getSeverity()); + } + @Test public void noHoverInfos() throws Exception { Editor editor = harness.newEditor(