Conourse: reconcile checks for duplicate job names
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<ValueParser> resourceNameDef(ConcourseModel models) {
|
||||
return acceptOnlyUniqueNames(models::getResourceNames, "resource name");
|
||||
}
|
||||
|
||||
public static final SchemaContextAware<ValueParser> jobNameDef(ConcourseModel models) {
|
||||
return acceptOnlyUniqueNames(models::getJobNames, "job name");
|
||||
}
|
||||
|
||||
public static SchemaContextAware<ValueParser> acceptOnlyUniqueNames(
|
||||
Function<IDocument, Multiset<String>> getDefinedNameCounts,
|
||||
String typeName
|
||||
) {
|
||||
return (dc) -> {
|
||||
Multiset<String> resourceNames = models.getResourceNames(dc.getDocument());
|
||||
Multiset<String> 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'."
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user