Basic support for using glob pattern in concourse group declarations.
This commit is contained in:
@@ -16,7 +16,9 @@ import static org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment.v
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -30,6 +32,8 @@ import org.springframework.ide.vscode.commons.languageserver.util.SnippetBuilder
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.SimpleGlob;
|
||||
import org.springframework.ide.vscode.commons.util.SimpleGlob.Match;
|
||||
import org.springframework.ide.vscode.commons.util.Streams;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
@@ -136,10 +140,17 @@ public class ConcourseModel {
|
||||
public final void jobAssignmentIsComplete(DynamicSchemaContext dc, Node parent, Node node, YType type, IProblemCollector problems) {
|
||||
Multiset<String> assignedJobs = getStringsFromAst(dc.getDocument(), JOBS_ASSIGNED_TO_GROUPS);
|
||||
if (assignedJobs!=null && !assignedJobs.isEmpty()) {
|
||||
Map<String, SimpleGlob> assignedJobMatchers = new HashMap<>();
|
||||
for (String jobPattern : assignedJobs) {
|
||||
if (!assignedJobMatchers.containsKey(jobPattern)) {
|
||||
assignedJobMatchers.put(jobPattern, SimpleGlob.create(jobPattern));
|
||||
}
|
||||
}
|
||||
|
||||
getJobNameNodes(dc).forEach(jobDefName -> {
|
||||
String name = NodeUtil.asScalar(jobDefName);
|
||||
if (StringUtil.hasText(name)) { //'not assigned to a group' errors for empty names are a bit silly, so avoid that
|
||||
if (!assignedJobs.contains(name)) {
|
||||
if (!assignedJobMatchers.values().stream().anyMatch(jobPat -> jobPat.match(name)!=Match.FAIL)) {
|
||||
problems.accept(YamlSchemaProblems.schemaProblem("'"+name+"' belongs to no group", jobDefName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +217,14 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
return models.getJobNames(dc);
|
||||
}
|
||||
).require(models::passedJobHasInteractionWithResource);
|
||||
AbstractType t_job_name_pattern = f.yGlobEnum("Job Name Pattern",
|
||||
(parseString, validValues) -> {
|
||||
return "The '"+parseString+"' Job does not match any existing job: "+validValues;
|
||||
},
|
||||
(DynamicSchemaContext dc) -> {
|
||||
return models.getJobNames(dc);
|
||||
}
|
||||
);
|
||||
|
||||
YAtomicType t_resource_name_def = f.yatomic("Resource Name");
|
||||
t_resource_name_def.parseWith(ConcourseValueParsers.resourceNameDef(models));
|
||||
@@ -462,7 +470,7 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
AbstractType group = f.ybean("Group");
|
||||
addProp(group, "name", t_group_name_def).isPrimary(true);
|
||||
addProp(group, "resources", f.yseq(t_resource_name));
|
||||
addProp(group, "jobs", f.yseq(t_job_name));
|
||||
addProp(group, "jobs", f.yseq(t_job_name_pattern));
|
||||
|
||||
YType t_background_image_def = f.yatomic("Background Image")
|
||||
.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
@@ -74,6 +74,82 @@ public class ConcourseEditorTest {
|
||||
serverInitializer.setMaxCompletions(100);
|
||||
}
|
||||
|
||||
@Test public void GH_639_globStar() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"groups:\n" +
|
||||
"- name: build\n" +
|
||||
" jobs:\n" +
|
||||
" - \"ci-*\"\n" +
|
||||
"\n" +
|
||||
"jobs:\n" +
|
||||
"- name: ci-project-one\n" +
|
||||
" plan:\n" +
|
||||
" - task: gradle-build\n" +
|
||||
" file: gradle-build-dcind.yml"
|
||||
);
|
||||
editor.assertProblems(/*NONE*/);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"groups:\n" +
|
||||
"- name: build\n" +
|
||||
" jobs:\n" +
|
||||
" - one-*\n" +
|
||||
" - two-*\n" +
|
||||
"- name: scan\n" +
|
||||
" jobs:\n" +
|
||||
" - one-*\n" +
|
||||
" - three-*\n" +
|
||||
"\n" +
|
||||
"jobs:\n" +
|
||||
"- name: one-project\n" +
|
||||
" plan: []\n" +
|
||||
"- name: two-project\n" +
|
||||
" plan: []\n" +
|
||||
"- name: three-project\n" +
|
||||
" plan: []\n" +
|
||||
"- name: four-project\n" +
|
||||
" plan: []\n"
|
||||
);
|
||||
editor.assertProblems("four-project|no group");
|
||||
|
||||
editor = harness.newEditor(
|
||||
"groups:\n" +
|
||||
"- name: build\n" +
|
||||
" jobs:\n" +
|
||||
" - ci-*\n" +
|
||||
"\n" +
|
||||
"jobs:\n" +
|
||||
"- name: xx-project-one\n" +
|
||||
" plan:\n" +
|
||||
" - task: gradle-build\n" +
|
||||
" file: gradle-build-dcind.yml"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"ci-*|does not match any existing job",
|
||||
"xx-project-one|belongs to no group"
|
||||
);
|
||||
|
||||
// No errors if patterns are too complex for our SimpleGlob to understand
|
||||
editor = harness.newEditor(
|
||||
"groups:\n" +
|
||||
"- name: build\n" +
|
||||
" jobs:\n" +
|
||||
" - \"{one,two,three,four}-project*\"\n" +
|
||||
"- name: scan\n" +
|
||||
"\n" +
|
||||
"jobs:\n" +
|
||||
"- name: one-project\n" +
|
||||
" plan: []\n" +
|
||||
"- name: two-project\n" +
|
||||
" plan: []\n" +
|
||||
"- name: three-project\n" +
|
||||
" plan: []\n" +
|
||||
"- name: four-project\n" +
|
||||
" plan: []\n"
|
||||
);
|
||||
editor.assertProblems(/*NONE*/);
|
||||
}
|
||||
|
||||
@Test public void addSingleRequiredPropertiesQuickfix() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"resources:\n" +
|
||||
@@ -1327,7 +1403,7 @@ public class ConcourseEditorTest {
|
||||
|
||||
editor.assertProblems(
|
||||
"build-artefact^ # <- bad|should define 'branch'",
|
||||
"bogus-job|does not exist",
|
||||
"bogus-job|does not match",
|
||||
"not-a-resource|does not exist"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user