Fixes Concourse issues for https://github.com/spring-projects/sts4/issues/41
1) Turn errors for empty task.input|output.path into a warning 2) Add task.optional property to the schema
This commit is contained in:
@@ -24,7 +24,7 @@ public class ValueParsers {
|
||||
throw new ValueParseException("String should not be empty");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static final ValueParser POS_INTEGER = integerRange(0, null);
|
||||
|
||||
public static ValueParser integerAtLeast(final Integer lowerBound) {
|
||||
|
||||
@@ -55,7 +55,7 @@ public class YamlSchemaProblems {
|
||||
public static final ProblemType DEPRECATED_VALUE = problemType("DeprecatedValue", ProblemSeverity.WARNING);
|
||||
public static final ProblemType MISSING_PROPERTY = problemType("MissingProperty", ProblemSeverity.ERROR);
|
||||
public static final ProblemType EXTRA_PROPERTY = problemType("ExtraProperty", ProblemSeverity.ERROR);
|
||||
|
||||
public static final ProblemType EMPTY_OPTIONAL_STRING = problemType("EmptyOptionalString", ProblemSeverity.WARNING);
|
||||
|
||||
public static final Set<ProblemType> PROPERTY_CONSTRAINT = ImmutableSet.of(
|
||||
MISSING_PROPERTY, EXTRA_PROPERTY
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.reconcile;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileException;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
|
||||
/**
|
||||
* Reusable value parsers and helpers that are somewhat specific
|
||||
* to yaml schema validation.
|
||||
*/
|
||||
public class YamlSchemaValueParsers {
|
||||
|
||||
public static final ValueParser OPT_STRING = (s) -> {
|
||||
if (StringUtil.hasText(s)) {
|
||||
return s;
|
||||
} else {
|
||||
throw new ReconcileException("Empty optional String attribute is useless and can be omitted.", YamlSchemaProblems.EMPTY_OPTIONAL_STRING);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -106,5 +106,4 @@ public class ConcourseValueParsers {
|
||||
return time + pm + zone;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaValueParsers;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.BasicYValueHint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
@@ -88,6 +89,8 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
public final YType t_string = f.yatomic("String");
|
||||
public final YType t_ne_string = f.yatomic("String")
|
||||
.parseWith(ValueParsers.NE_STRING);
|
||||
public final YType t_opt_string = f.yatomic("String")
|
||||
.parseWith(YamlSchemaValueParsers.OPT_STRING);
|
||||
|
||||
public final YType t_strings = f.yseq(t_string);
|
||||
public final YType t_pair = f.ybean("NameValuePair",
|
||||
@@ -248,11 +251,12 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
|
||||
AbstractType t_input = f.ybean("TaskInput");
|
||||
addProp(t_input, "name", t_ne_string).isPrimary(true);
|
||||
addProp(t_input, "path", t_ne_string);
|
||||
addProp(t_input, "path", t_opt_string);
|
||||
addProp(t_input, "optional", t_boolean);
|
||||
|
||||
AbstractType t_output = f.ybean("TaskOutput");
|
||||
addProp(t_output, "name", t_ne_string).isPrimary(true);
|
||||
addProp(t_output, "path", t_ne_string);
|
||||
addProp(t_output, "path", t_opt_string);
|
||||
|
||||
AbstractType t_command = f.ybean("Command");
|
||||
addProp(t_command, "path", t_ne_string).isRequired(true);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
*Optional*. If `true`, then the input is not required by the task. The task may run even if this input is missing.
|
||||
|
||||
An optional input that is missing will not appear in the current directory of the running task.
|
||||
@@ -12,7 +12,6 @@ package org.springframework.ide.vscode.concourse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.ide.vscode.languageserver.testharness.Editor.INDENTED_COMPLETION;
|
||||
import static org.springframework.ide.vscode.languageserver.testharness.Editor.PLAIN_COMPLETION;
|
||||
@@ -31,7 +30,7 @@ import org.eclipse.lsp4j.DiagnosticSeverity;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.commons.util.IOUtil;
|
||||
import org.springframework.ide.vscode.commons.util.Unicodes;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
@@ -47,21 +46,20 @@ import org.springframework.ide.vscode.languageserver.testharness.Synchronization
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class ConcourseEditorTest {
|
||||
|
||||
private static final YamlCompletionEngineOptions OPTIONS = YamlCompletionEngineOptions.TEST_DEFAULT;
|
||||
|
||||
private static final String CURSOR = "<*>";
|
||||
LanguageServerHarness harness;
|
||||
LanguageServerHarness<ConcourseLanguageServer> harness;
|
||||
|
||||
private GithubInfoProvider github= Mockito.mock(GithubInfoProvider.class);
|
||||
|
||||
@Before public void setup() throws Exception {
|
||||
harness = new LanguageServerHarness(() -> {
|
||||
return new ConcourseLanguageServer(OPTIONS, github)
|
||||
.setMaxCompletions(100);
|
||||
harness = new LanguageServerHarness<>(() -> {
|
||||
ConcourseLanguageServer s = new ConcourseLanguageServer(OPTIONS, github);
|
||||
s.setMaxCompletions(100);
|
||||
return s;
|
||||
},
|
||||
LanguageId.CONCOURSE_PIPELINE
|
||||
);
|
||||
@@ -4611,6 +4609,40 @@ public class ConcourseEditorTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void emptyInputPathWarning() throws Exception {
|
||||
Editor editor = harness.newEditor(LanguageId.CONCOURSE_TASK,
|
||||
"platform: linux\n" +
|
||||
"run:\n" +
|
||||
" path: blah\n" +
|
||||
"inputs:\n" +
|
||||
"- name: foo\n" +
|
||||
" path: \"\"\n" +
|
||||
"outputs:\n" +
|
||||
"- name: bar\n" +
|
||||
" path: \"\"\n"
|
||||
);
|
||||
List<Diagnostic> problems = editor.assertProblems(
|
||||
"\"\"|Empty optional String attribute is useless and can be omitted",
|
||||
"\"\"|Empty optional String attribute is useless and can be omitted"
|
||||
);
|
||||
for (Diagnostic problem : problems) {
|
||||
assertEquals(DiagnosticSeverity.Warning, problem.getSeverity());
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void taskInputOptionalAttribute() throws Exception {
|
||||
Editor editor = harness.newEditor(LanguageId.CONCOURSE_TASK,
|
||||
"platform: linux\n" +
|
||||
"run:\n" +
|
||||
" path: blah\n" +
|
||||
"inputs:\n" +
|
||||
"- name: foo\n" +
|
||||
" optional: non-bool\n"
|
||||
);
|
||||
editor.assertProblems("non-bool|boolean");
|
||||
editor.assertHoverContains("optional", "If `true`, then the input is not required by the task");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void assertContextualCompletions(String conText, String textBefore, String... textAfter) throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user