diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java index 1396c3a07..e0cc9a5d1 100644 --- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java +++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java @@ -52,8 +52,8 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { public YTypeAssistContext(YTypeAssistContext parent, YamlPath contextPath, YType YType, YTypeUtil typeUtil) { super(parent.getDocument(), parent.documentSelector, contextPath); this.parent = parent; - this.type = YType; this.typeUtil = typeUtil; + this.type = typeUtil.inferMoreSpecificType(YType, getSchemaContext()); } public YTypeAssistContext(TopLevelAssistContext parent, int documentSelector, YType type, YTypeUtil typeUtil) { @@ -76,7 +76,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { public List getKeyCompletions(YamlDocument doc, int offset, String query) throws Exception { int queryOffset = offset - query.length(); SNode contextNode = getContextNode(); - DynamicSchemaContext dynamicCtxt = new SNodeDynamicSchemaContext(contextNode); + DynamicSchemaContext dynamicCtxt = getSchemaContext(); List properties = typeUtil.getProperties(type, dynamicCtxt); if (CollectionUtil.hasElements(properties)) { ArrayList proposals = new ArrayList<>(properties.size()); @@ -171,12 +171,11 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { @Override public YamlAssistContext traverse(YamlPathSegment s) throws Exception { if (s.getType()==YamlPathSegmentType.VAL_AT_KEY) { + DynamicSchemaContext dynamicCtxt = getSchemaContext(); if (typeUtil.isSequencable(type) || typeUtil.isMap(type)) { return contextWith(s, typeUtil.getDomainType(type)); } String key = s.toPropString(); - SNode contextNode = getContextNode(); - DynamicSchemaContext dynamicCtxt = new SNodeDynamicSchemaContext(contextNode); Map subproperties = typeUtil.getPropertiesMap(type, dynamicCtxt); if (subproperties!=null) { return contextWith(s, getType(subproperties.get(key))); @@ -237,11 +236,12 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { } return null; } - - private DynamicSchemaContext getSchemaContext() { + + protected DynamicSchemaContext getSchemaContext() { try { SNode contextNode = getContextNode(); - return new SNodeDynamicSchemaContext(contextNode); + YamlPath fullContextPath = contextPath.prepend(YamlPathSegment.valueAt(documentSelector)); + return new SNodeDynamicSchemaContext(contextNode, fullContextPath); } catch (Exception e) { Log.log(e); return DynamicSchemaContext.NULL; diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java index 98076aefa..1a26aa600 100644 --- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java +++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/path/YamlPath.java @@ -117,12 +117,19 @@ public class YamlPath { return null; } + public YamlPath prepend(YamlPathSegment s) { + YamlPathSegment[] newPath = new YamlPathSegment[segments.length+1]; + newPath[0] = s; + System.arraycopy(segments, 0, newPath, 1, segments.length); + return new YamlPath(newPath); + } + public YamlPath append(YamlPathSegment s) { YamlPathSegment[] newPath = Arrays.copyOf(segments, segments.length+1); newPath[segments.length] = s; return new YamlPath(newPath); } - + public Node traverseToNode(YamlFileAST root) { ASTCursor cursor = traverse(new ASTRootCursor(root)); if (cursor instanceof NodeCursor) { diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java index 9d6818ecc..aa47f39d9 100644 --- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java +++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/SNodeDynamicSchemaContext.java @@ -31,9 +31,11 @@ import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser public class SNodeDynamicSchemaContext extends CachingSchemaContext { private SNode contextNode; + private YamlPath contextPath; - public SNodeDynamicSchemaContext(SNode contextNode) { + public SNodeDynamicSchemaContext(SNode contextNode, YamlPath contextPath) { this.contextNode = contextNode; + this.contextPath = contextPath; } @Override @@ -64,8 +66,7 @@ public class SNodeDynamicSchemaContext extends CachingSchemaContext { @Override public YamlPath getPath() { - // TODO Auto-generated method stub - return null; + return contextPath; } diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java index 2af8e147f..1fcc75a22 100644 --- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java +++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java @@ -39,11 +39,17 @@ public class PipelineYmlSchema implements YamlSchema { public final YTypeFactory f = new YTypeFactory(); public final YType t_string = f.yatomic("String"); public final YType t_strings = f.yseq(t_string); + public final YType t_pair = f.ybean("NameValuePair", + f.yprop("name", t_string), + f.yprop("value", t_string) + ); + public final YType t_pair_list = f.yseq(t_pair); + public final YAtomicType t_boolean = f.yenum("boolean", "true", "false"); public final YType t_any = f.yany("Object"); public final YType t_params = f.ymap(t_string, t_any); public final YType t_string_params = f.ymap(t_string, t_string); - + private final ResourceTypeRegistry resourceTypes = new ResourceTypeRegistry(); public PipelineYmlSchema(ConcourseModel models) { @@ -64,7 +70,7 @@ public class PipelineYmlSchema implements YamlSchema { YAtomicType t_version = f.yatomic("Version"); t_version.addHints("latest", "every"); - + YAtomicType t_image_type = f.yatomic("ImageType"); t_image_type.addHints("docker_image"); @@ -95,8 +101,8 @@ public class PipelineYmlSchema implements YamlSchema { // // The vagrant-cloud r ); - - YType resourceName = f.yenum("Resource Name", + + YType resourceName = f.yenum("Resource Name", (parseString, validValues) -> { return "The '"+parseString+"' resource does not exist. Existing resources: "+validValues; }, @@ -105,7 +111,7 @@ public class PipelineYmlSchema implements YamlSchema { } ); - YType jobName = f.yenum("Job Name", + YType jobName = f.yenum("Job Name", (parseString, validValues) -> { return "The '"+parseString+"' resource does not exist. Existing resources: "+validValues; }, @@ -113,7 +119,7 @@ public class PipelineYmlSchema implements YamlSchema { return models.getJobNames(dc.getDocument()); } ); - + YAtomicType resourceNameDef = f.yatomic("Resource Name"); resourceNameDef.parseWith(ValueParsers.resourceNameDef(models)); YAtomicType jobNameDef = f.yatomic("Job Name"); @@ -146,7 +152,7 @@ public class PipelineYmlSchema implements YamlSchema { YBeanType aggregateStep = f.ybean("AggregateStep"); YBeanType doStep = f.ybean("DoStep"); YBeanType tryStep = f.ybean("TryStep"); - + YBeanType[] stepTypes = { getStep, putStep, @@ -175,9 +181,9 @@ public class PipelineYmlSchema implements YamlSchema { if (typeTag!=null) { return resourceTypes.getSourceType(typeTag); } - return t_any; + return null; }); - + YBeanType resource = f.ybean("Resource"); addProp(resource, "name", resourceNameDef); addProp(resource, "type", t_resource_type_name); @@ -193,12 +199,12 @@ public class PipelineYmlSchema implements YamlSchema { addProp(job, "public", t_boolean); addProp(job, "disable_manual_trigger", t_boolean); addProp(job, "plan", f.yseq(step)); - + YBeanType resourceType = f.ybean("ResourceType"); addProp(resourceType, "name", t_ne_string); addProp(resourceType, "type", t_image_type); addProp(resourceType, "source", t_any); - + YBeanType group = f.ybean("Group"); addProp(group, "name", t_ne_string); addProp(group, "resources", f.yseq(resourceName)); @@ -208,7 +214,7 @@ public class PipelineYmlSchema implements YamlSchema { addProp(TOPLEVEL_TYPE, "jobs", f.yseq(job)); addProp(TOPLEVEL_TYPE, "resource_types", f.yseq(resourceType)); addProp(TOPLEVEL_TYPE, "groups", f.yseq(group)); - + initializeDefaultResourceTypes(); } @@ -223,12 +229,12 @@ public class PipelineYmlSchema implements YamlSchema { addProp(gitSource, "ignore_paths", t_strings); addProp(gitSource, "skip_ssl_verification", t_boolean); addProp(gitSource, "tag_filter", t_string); - addProp(gitSource, "git_config", t_string); + addProp(gitSource, "git_config", t_pair_list); addProp(gitSource, "disable_ci_skip", t_boolean); addProp(gitSource, "commit_verification_keys", t_strings); addProp(gitSource, "commit_verification_key_ids", t_strings); - addProp(gitSource, "gpg_keyserver", t_strings); - + addProp(gitSource, "gpg_keyserver", t_string); + resourceTypes.def("git", gitSource); } diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/GitResourceSource/uri.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/GitResourceSource/uri.md new file mode 100644 index 000000000..967245f59 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/GitResourceSource/uri.md @@ -0,0 +1 @@ +*Required.* The location of the repository. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java index c94e9e3d0..95294d11d 100644 --- a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java +++ b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/PipelineYamlEditorTest.java @@ -100,12 +100,12 @@ public class PipelineYamlEditorTest { editor = harness.newEditor( "resources:\n" + " name: git\n" + - " type: git\n" + " type: git\n" ); editor.assertProblems( "name: git\n type: git|Expecting a 'Sequence' but found a 'Map'" ); - + editor = harness.newEditor( "jobs:\n" + "- name: a-job\n" + @@ -141,7 +141,7 @@ public class PipelineYamlEditorTest { " - <*>" , // ============== "<*>" - , // => + , // => "aggregate:\n" + " - <*>" , // ============== @@ -158,7 +158,7 @@ public class PipelineYamlEditorTest { " <*>" ); } - + @Test public void PT_136196057_do_step_completion_indentation() throws Exception { assertCompletions( @@ -166,7 +166,7 @@ public class PipelineYamlEditorTest { "- name:\n"+ " plan:\n" + " - do<*>" - , // => + , // => "jobs:\n" + "- name:\n"+ " plan:\n" + @@ -189,7 +189,7 @@ public class PipelineYamlEditorTest { " - try:\n" + " put: test-logs\n" ); - + editor.assertHoverContains("get", "Fetches a resource"); editor.assertHoverContains("put", "Pushes to the given [Resource]"); editor.assertHoverContains("aggregate", "Performs the given steps in parallel"); @@ -197,7 +197,7 @@ public class PipelineYamlEditorTest { editor.assertHoverContains("do", "performs the given steps serially"); editor.assertHoverContains("try", "Performs the given step, swallowing any failure"); } - + @Test public void putStepHovers() throws Exception { Editor editor = harness.newEditor( @@ -247,7 +247,7 @@ public class PipelineYamlEditorTest { editor.assertHoverContains("on_success", "Any step can have `on_success` tacked onto it"); editor.assertHoverContains("ensure", "a second step to execute regardless of the result of the parent step"); } - + @Test public void groupHovers() throws Exception { Editor editor = harness.newEditor( @@ -260,7 +260,7 @@ public class PipelineYamlEditorTest { editor.assertHoverContains("resources", "A list of resources that should appear in this group"); editor.assertHoverContains("jobs", " A list of jobs that should appear in this group"); } - + @Test public void taskStepHovers() throws Exception { Editor editor = harness.newEditor( @@ -302,7 +302,7 @@ public class PipelineYamlEditorTest { @Test public void aggregateStepHovers() throws Exception { Editor editor; - + editor = harness.newEditor( "jobs:\n" + "- name: some-job\n" + @@ -310,7 +310,7 @@ public class PipelineYamlEditorTest { " - aggregate:\n" + " - get: some-resource\n" ); - + editor.assertHoverContains("aggregate", "Performs the given steps in parallel"); } @@ -427,59 +427,59 @@ public class PipelineYamlEditorTest { @Test public void topLevelHoverInfos() throws Exception { Editor editor = harness.newEditor( - "resource_types:\n" + - "- name: s3-multi\n" + - " type: docker-image\n" + - " source:\n" + - " repository: kdvolder/s3-resource-simple\n" + - "resources:\n" + - "- name: docker-git\n" + - " type: git\n" + - " source:\n" + - " uri: git@github.com:spring-projects/sts4.git\n" + - " branch: {{branch}}\n" + - " username: kdvolder\n" + - " private_key: {{rsa_id}}\n" + - " paths:\n" + - " - concourse/docker\n" + - "jobs:\n" + - "- name: build-docker-image\n" + - " serial: true\n" + - " plan:\n" + - " - get: docker-git\n" + - " trigger: true\n" + - " - put: docker-image\n" + - " params:\n" + - " build: docker-git/concourse/docker\n" + - " get_params: \n" + + "resource_types:\n" + + "- name: s3-multi\n" + + " type: docker-image\n" + + " source:\n" + + " repository: kdvolder/s3-resource-simple\n" + + "resources:\n" + + "- name: docker-git\n" + + " type: git\n" + + " source:\n" + + " uri: git@github.com:spring-projects/sts4.git\n" + + " branch: {{branch}}\n" + + " username: kdvolder\n" + + " private_key: {{rsa_id}}\n" + + " paths:\n" + + " - concourse/docker\n" + + "jobs:\n" + + "- name: build-docker-image\n" + + " serial: true\n" + + " plan:\n" + + " - get: docker-git\n" + + " trigger: true\n" + + " - put: docker-image\n" + + " params:\n" + + " build: docker-git/concourse/docker\n" + + " get_params: \n" + " skip_download: true\n" + "groups:\n" + "- name: a-groups\n" ); - + editor.assertHoverContains("resource_types", "each pipeline can configure its own custom types by specifying `resource_types` at the top level."); editor.assertHoverContains("resources", "A resource is any entity that can be checked for new versions"); editor.assertHoverContains("jobs", "At a high level, a job describes some actions to perform"); editor.assertHoverContains("groups", "A pipeline may optionally contain a section called `groups`"); } - + @Test public void reconcileResourceReferences() throws Exception { Editor editor = harness.newEditor( - "resources:\n" + - "- name: sts4\n" + - " type: git\n" + - " source:\n" + - " uri: https://github.com/kdvolder/somestuff\n" + - "jobs:\n" + - "- name: job1\n" + - " plan:\n" + - " - get: sts4\n" + - " - get: bogus-get\n" + - " - task: do-stuff\n" + - " input_mapping:\n" + - " task-input: bogus-input\n" + - " repo: sts4\n" + + "resources:\n" + + "- name: sts4\n" + + " type: git\n" + + " source:\n" + + " uri: https://github.com/kdvolder/somestuff\n" + + "jobs:\n" + + "- name: job1\n" + + " plan:\n" + + " - get: sts4\n" + + " - get: bogus-get\n" + + " - task: do-stuff\n" + + " input_mapping:\n" + + " task-input: bogus-input\n" + + " repo: sts4\n" + " - put: bogus-put\n" ); editor.assertProblems( @@ -487,7 +487,7 @@ public class PipelineYamlEditorTest { "bogus-input|resource does not exist", "bogus-put|resource does not exist" ); - + editor.assertProblems( "bogus-get|[sts4]", "bogus-input|[sts4]", @@ -498,19 +498,19 @@ public class PipelineYamlEditorTest { @Test public void reconcileDuplicateResourceNames() throws Exception { Editor editor = harness.newEditor( - "resources:\n" + - "- name: sts4\n" + - " type: git\n" + - " source:\n" + - " uri: https://github.com/kdvolder/somestuff\n" + - "- name: utils\n" + - " type: git\n" + - " source:\n" + - " uri: https://github.com/kdvolder/someutils\n" + - "- name: sts4\n" + - " type: git\n" + - " source:\n" + - " uri: https://github.com/kdvolder/extras\n" + "resources:\n" + + "- name: sts4\n" + + " type: git\n" + + " source:\n" + + " uri: https://github.com/kdvolder/somestuff\n" + + "- name: utils\n" + + " type: git\n" + + " source:\n" + + " uri: https://github.com/kdvolder/someutils\n" + + "- name: sts4\n" + + " type: git\n" + + " source:\n" + + " uri: https://github.com/kdvolder/extras\n" ); editor.assertProblems( "sts4|Duplicate resource name", @@ -521,9 +521,9 @@ public class PipelineYamlEditorTest { @Test public void reconcileDuplicateJobNames() throws Exception { Editor editor = harness.newEditor( - "jobs:\n" + - "- name: job-1\n" + - "- name: utils\n" + + "jobs:\n" + + "- name: job-1\n" + + "- name: utils\n" + "- name: job-1\n" ); editor.assertProblems( @@ -535,36 +535,36 @@ public class PipelineYamlEditorTest { @Test public void completionsResourceReferences() throws Exception { assertContextualCompletions( - "resources:\n" + - "- name: sts4\n" + + "resources:\n" + + "- name: sts4\n" + "- name: repo-a\n" + "- name: repo-b\n" + - "jobs:\n" + - "- name: job1\n" + - " plan:\n" + - " - get: <*>\n" - , //////////////////// + "jobs:\n" + + "- name: job1\n" + + " plan:\n" + + " - get: <*>\n" + , //////////////////// "<*>" - , // => + , // => "repo-a<*>", "repo-b<*>", "sts4<*>" ); assertContextualCompletions( - "resources:\n" + - "- name: sts4\n" + + "resources:\n" + + "- name: sts4\n" + "- name: repo-a\n" + "- name: repo-b\n" + - "jobs:\n" + - "- name: job1\n" + - " plan:\n" + - " - put: <*>\n" - , //////////////////// + "jobs:\n" + + "- name: job1\n" + + " plan:\n" + + " - put: <*>\n" + , //////////////////// "r<*>" - , // => + , // => "repo-a<*>", "repo-b<*>" ); } - + @Test public void reconcileDuplicateKeys() throws Exception { Editor editor = harness.newEditor( @@ -580,7 +580,7 @@ public class PipelineYamlEditorTest { " source:\n" + " uri: https://github.com/kdvolder/forked-repo\n" ); - + editor.assertProblems( "resources|Duplicate key", "resources|Duplicate key", @@ -588,92 +588,138 @@ public class PipelineYamlEditorTest { "type|Duplicate key" ); } - + @Test public void reconcileJobNames() throws Exception { Editor editor = harness.newEditor( - "resources:\n" + - "- name: git-repo\n" + - "- name: build-artefact\n" + - "jobs:\n" + - "- name: build\n" + - " plan:\n" + - " - get: git-repo\n" + - " - task: run-build\n" + - " - put: build-artefact\n" + - "- name: test\n" + - " plan:\n" + - " - get: git-repo\n" + - " passed:\n" + - " - not-a-job\n" + + "resources:\n" + + "- name: git-repo\n" + + "- name: build-artefact\n" + + "jobs:\n" + + "- name: build\n" + + " plan:\n" + + " - get: git-repo\n" + + " - task: run-build\n" + + " - put: build-artefact\n" + + "- name: test\n" + + " plan:\n" + + " - get: git-repo\n" + + " passed:\n" + + " - not-a-job\n" + " - build\n" ); - + editor.assertProblems("not-a-job|does not exist"); } @Test public void reconcileGroups() throws Exception { Editor editor = harness.newEditor( - "resources:\n" + - "- name: git-repo\n" + - "- name: build-artefact\n" + - "jobs:\n" + - "- name: build\n" + - " plan:\n" + - " - get: git-repo\n" + - " - task: run-build\n" + - " - put: build-artefact\n" + - "- name: test\n" + - " plan:\n" + - " - get: git-repo\n" + + "resources:\n" + + "- name: git-repo\n" + + "- name: build-artefact\n" + + "jobs:\n" + + "- name: build\n" + + " plan:\n" + + " - get: git-repo\n" + + " - task: run-build\n" + + " - put: build-artefact\n" + + "- name: test\n" + + " plan:\n" + + " - get: git-repo\n" + "groups:\n" + "- name: some-group\n" + " jobs: [build, test, bogus-job]\n" + " resources: [git-repo, build-artefact, not-a-resource]" ); - + editor.assertProblems( "bogus-job|does not exist", "not-a-resource|does not exist" ); } - - @Test - public void reconcileGitResource() throws Exception { + + @Test public void reconcileGitResourceSource() throws Exception { Editor editor = harness.newEditor( - "resources:\n" + - "- name: sts4-out\n" + - " type: git\n" + - " source:\n" + - " uri: git@github.com:spring-projects/sts4.git\n" + + "resources:\n" + + "- name: sts4-out\n" + + " type: git\n" + + " source:\n" + + " uri: git@github.com:spring-projects/sts4.git\n" + " bogus: bad\n" + - " branch: {{branch}}\n" + - " private_key: {{rsa_id}}\n" + " branch: {{branch}}\n" + + " private_key: {{rsa_id}}\n" + + " username: jeffy\n" + + " password: {{git_passwords}}\n" + + " paths: not-a-list\n" + + " ignore_paths: also-not-a-list\n" + + " skip_ssl_verification: skip-it\n" + + " tag_filter: RELEASE_*\n" + + " git_config:\n" + + " - name: good\n" + + " val: bad\n" + + " disable_ci_skip: no_ci_skip\n" + + " commit_verification_keys: not-a-list-of-keys\n" + + " commit_verification_key_ids: not-a-list-of-ids\n" + + " gpg_keyserver: hkp://somekeyserver.net" ); editor.assertProblems( - "bogus|Unknown property" + "bogus|Unknown property", + "not-a-list|Expecting a 'Sequence'", + "also-not-a-list|Expecting a 'Sequence'", + "skip-it|'boolean'", + "val|Unknown property", + "no_ci_skip|'boolean'", + "not-a-list-of-keys|Expecting a 'Sequence'", + "not-a-list-of-ids|Expecting a 'Sequence'" ); } + @Test public void gitResourceSourceHovers() throws Exception { + Editor editor = harness.newEditor( + "resources:\n" + + "- name: sts4-out\n" + + " type: git\n" + + " source:\n" + + " uri: git@github.com:spring-projects/sts4.git\n" + + " bogus: bad\n" + + " branch: {{branch}}\n" + + " private_key: {{rsa_id}}\n" + + " username: jeffy\n" + + " password: {{git_passwords}}\n" + + " paths: not-a-list\n" + + " ignore_paths: also-not-a-list\n" + + " skip_ssl_verification: skip-it\n" + + " tag_filter: RELEASE_*\n" + + " git_config:\n" + + " - name: good\n" + + " val: bad\n" + + " disable_ci_skip: no_ci_skip\n" + + " commit_verification_keys: not-a-list-of-keys\n" + + " commit_verification_key_ids: not-a-list-of-ids\n" + + " gpg_keyserver: hkp://somekeyserver.net" + ); + editor.assertHoverContains("uri", "*Required.* The location of the repository."); + } + @Test public void contentAssistJobNames() throws Exception { assertContextualCompletions( - "resources:\n" + - "- name: git-repo\n" + - "- name: build-artefact\n" + - "jobs:\n" + - "- name: build\n" + - " plan:\n" + - " - get: git-repo\n" + - " - task: run-build\n" + - " - put: build-artefact\n" + - "- name: test\n" + - " plan:\n" + - " - get: git-repo\n" + - " passed:\n" + - " - <*>\n" - , /////////////////////////// + "resources:\n" + + "- name: git-repo\n" + + "- name: build-artefact\n" + + "jobs:\n" + + "- name: build\n" + + " plan:\n" + + " - get: git-repo\n" + + " - task: run-build\n" + + " - put: build-artefact\n" + + "- name: test\n" + + " plan:\n" + + " - get: git-repo\n" + + " passed:\n" + + " - <*>\n" + , /////////////////////////// "<*>" , // => "build<*>", @@ -684,29 +730,29 @@ public class PipelineYamlEditorTest { @Test public void resourceTypeAttributeHovers() throws Exception { Editor editor = harness.newEditor( - "resource_types:\n" + - "- name: s3-multi\n" + - " type: docker-image\n" + - " source:\n" + + "resource_types:\n" + + "- name: s3-multi\n" + + " type: docker-image\n" + + " source:\n" + " repository: kdvolder/s3-resource-simple\n" ); - + editor.assertHoverContains("name", "This name will be referenced by `resources` defined within the same pipeline"); editor.assertHoverContains("type", 2, "used to provide the resource type's container image"); editor.assertHoverContains("source", 2, "The location of the resource type's resource"); } - + @Test public void resourceAttributeHovers() throws Exception { Editor editor = harness.newEditor( - "resources:\n" + - "- name: sts4\n" + + "resources:\n" + + "- name: sts4\n" + " type: git\n" + " check_every: 5m\n" + - " source:\n" + + " source:\n" + " repository: https://github.com/spring-projects/sts4\n" ); - + editor.assertHoverContains("name", "The name of the resource"); editor.assertHoverContains("type", "The type of the resource. Each worker advertises"); editor.assertHoverContains("source", 2, "The location of the resource");