From 1cd521bc070d79dc4d80d25aaa9c4f6d5973324d Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Thu, 22 Dec 2016 11:28:25 -0800 Subject: [PATCH] Add hover docs for resource_type sub attributes --- .../languageserver/testharness/Editor.java | 46 +++++++++++++++++-- .../vscode/concourse/PipelineYmlSchema.java | 18 ++++---- .../main/resources/desc/ResourceType/name.md | 1 + .../resources/desc/ResourceType/source.md | 3 ++ .../main/resources/desc/ResourceType/type.md | 1 + .../concourse/PipelineYamlEditorTest.java | 16 +++++++ 6 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/name.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/source.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/type.md diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java index ccbbadb7f..79cce2554 100644 --- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java +++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java @@ -9,9 +9,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.Stream.Builder; import javax.swing.text.BadLocationException; @@ -27,6 +30,8 @@ import org.junit.Assert; import com.google.common.base.Strings; +import reactor.core.publisher.Flux; + public class Editor { static class EditorState { @@ -313,15 +318,48 @@ public class Editor { } public void assertIsHoverRegion(String string) throws Exception { - int hoverPosition = getRawText().indexOf(string) + string.length() / 2; + int hoverPosition = getHoverPosition(string, 1); Hover hover = harness.getHover(document, document.toPosition(hoverPosition)); assertEquals(string, getText(hover.getRange())); } - public void assertHoverContains(String hoverOver, String snippet) throws Exception { - int hoverPosition = getRawText().indexOf(hoverOver) + hoverOver.length() / 2; + public void assertHoverContains(String hoverOver, int occurrence, String snippet) throws Exception { + int hoverPosition = getHoverPosition(hoverOver, occurrence); Hover hover = harness.getHover(document, document.toPosition(hoverPosition)); - assertContains(snippet, hover.getContents().toString()); } + assertContains(snippet, hover.getContents().toString()); + } + + private int getHoverPosition(String hoverOver, int occurrence) throws Exception { + assertTrue(occurrence>0); + return occurrences(getRawText(), hoverOver) + .elementAt(occurrence-1) + .map(offset -> offset + hoverOver.length()/2) + .block(); + } + + private Flux occurrences(String text, String substring) { + return Flux.fromIterable(() -> new Iterator() { + int searchFrom = 0; + @Override + public boolean hasNext() { + return searchFrom>=0 && searchFrom < text.length() && text.indexOf(substring, searchFrom) >= 0; + } + + @Override + public Integer next() { + int found = text.indexOf(substring, searchFrom); + assertTrue(found>=0); + searchFrom = found+1; + return found; + } + }); + } + + public void assertHoverContains(String hoverOver, String snippet) throws Exception { + int hoverPosition = getHoverPosition(hoverOver,1); + Hover hover = harness.getHover(document, document.toPosition(hoverPosition)); + assertContains(snippet, hover.getContents().toString()); + } public void assertNoHover(String hoverOver) throws Exception { int hoverPosition = getRawText().indexOf(hoverOver) + hoverOver.length() / 2; 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 60a23219b..7045936bc 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 @@ -61,8 +61,8 @@ public class PipelineYmlSchema implements YamlSchema { YAtomicType t_image_type = f.yatomic("ImageType"); t_image_type.addHints("docker_image"); - YAtomicType t_resource_type = f.yatomic("ResourceType"); - t_resource_type.addHints( + YAtomicType t_resource_type_name = f.yatomic("ResourceType Name"); + t_resource_type_name.addHints( f.hint("archive", "archive - The 'archive' resource can fetch and extract .tar.gz archives."), f.hint("git", "git - The 'git' resource can pull and push to git repositories"), f.hint("s3", "s3 - The 's3' resource can fetch from and upload to S3 buckets."), @@ -158,7 +158,7 @@ public class PipelineYmlSchema implements YamlSchema { YBeanType resource = f.ybean("Resource"); prop(resource, "name", t_ne_string); - prop(resource, "type", t_resource_type); + prop(resource, "type", t_resource_type_name); prop(resource, "source", t_any); YBeanType job = f.ybean("Job"); @@ -171,12 +171,10 @@ public class PipelineYmlSchema implements YamlSchema { prop(job, "disable_manual_trigger", t_boolean); prop(job, "plan", f.yseq(step)); - YType resource_type_def = f.ybean("ResourceTypeDef", - //TODO: This way of initializing the props doesn't attach descriptions! - f.yprop("name", t_ne_string), - f.yprop("type", t_image_type), - f.yprop("source", t_any) - ); + YBeanType resourceType = f.ybean("ResourceType"); + prop(resourceType, "name", t_ne_string); + prop(resourceType, "type", t_image_type); + prop(resourceType, "source", t_any); YBeanType group = f.ybean("Group"); prop(group, "name", t_ne_string); @@ -185,7 +183,7 @@ public class PipelineYmlSchema implements YamlSchema { prop(TOPLEVEL_TYPE, "resources", f.yseq(resource)); prop(TOPLEVEL_TYPE, "jobs", f.yseq(job)); - prop(TOPLEVEL_TYPE, "resource_types", f.yseq(resource_type_def)); + prop(TOPLEVEL_TYPE, "resource_types", f.yseq(resourceType)); prop(TOPLEVEL_TYPE, "groups", f.yseq(group)); } diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/name.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/name.md new file mode 100644 index 000000000..61acfa9dd --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/name.md @@ -0,0 +1 @@ +*Required.* The name of the new resource type. This should be short and simple. This name will be referenced by `resources` defined within the same pipeline, and `image_resource`s used by tasks running in the pipeline. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/source.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/source.md new file mode 100644 index 000000000..13c2f5ab1 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/source.md @@ -0,0 +1,3 @@ +*Optional.* The location of the resource type's resource. This varies by resource type, and is a black box to Concourse; it is blindly passed to the resource at runtime. + +To use `docker-image` as an example, the source would contain something like `repository: username/reponame`. See the [Docker Image resource](https://github.com/concourse/docker-image-resource) (or whatever resource type your resource type uses) for more information. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/type.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/type.md new file mode 100644 index 000000000..255250fbc --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/ResourceType/type.md @@ -0,0 +1 @@ +*Required.* The type of the resource used to provide the resource type's container image. Yes, this is a bit meta. Usually this will be `docker-image`, as the resource type must result in a container image, though there may be other image formats (possibly themselves defined as custom resource types!). \ 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 0064202ad..edfae533d 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 @@ -10,6 +10,7 @@ *******************************************************************************/ package org.springframework.ide.vscode.concourse; +import static org.junit.Assert.*; import static org.springframework.ide.vscode.languageserver.testharness.TestAsserts.assertContains; import java.io.InputStream; @@ -606,6 +607,21 @@ 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" + + " 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"); + } + //////////////////////////////////////////////////////////////////////////////