Make put/get resource name conditional on absence of explicit resource attribute
This commit is contained in:
@@ -44,7 +44,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
*/
|
||||
public class YTypeFactory {
|
||||
|
||||
public YType contextAware(String name, SchemaContextAware<YType> guessType) {
|
||||
public YContextSensitive contextAware(String name, SchemaContextAware<YType> guessType) {
|
||||
return new YContextSensitive(name, guessType);
|
||||
}
|
||||
|
||||
@@ -180,8 +180,9 @@ public class YTypeFactory {
|
||||
addHintProvider((DynamicSchemaContext dc) -> hintProvider);
|
||||
}
|
||||
|
||||
public void addHintProvider(SchemaContextAware<Callable<Collection<YValueHint>>> hintProvider) {
|
||||
public AbstractType addHintProvider(SchemaContextAware<Callable<Collection<YValueHint>>> hintProvider) {
|
||||
this.hintProvider = hintProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
public YValueHint[] getHintValues(DynamicSchemaContext dc) throws Exception {
|
||||
@@ -307,12 +308,15 @@ public class YTypeFactory {
|
||||
/**
|
||||
* Represents a type that depends on the DynamicSchemaContext
|
||||
*/
|
||||
public static class YContextSensitive extends YAny {
|
||||
public static class YContextSensitive extends AbstractType {
|
||||
|
||||
private final SchemaContextAware<YType> typeGuesser;
|
||||
private final String name;
|
||||
|
||||
boolean treatAsAtomic = false;
|
||||
|
||||
public YContextSensitive(String name, SchemaContextAware<YType> typeGuesser) {
|
||||
super(name);
|
||||
this.name = name;
|
||||
this.typeGuesser = typeGuesser;
|
||||
}
|
||||
|
||||
@@ -327,6 +331,38 @@ public class YTypeFactory {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAtomic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSequenceable() {
|
||||
return !treatAsAtomic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMap() {
|
||||
return !treatAsAtomic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to false (which is the default), then this type (when not yet inferred to a
|
||||
* more specific version of itself) will be treated as if it can be anything (i.e atomic, map or sequence)
|
||||
* <p>
|
||||
* If set to true, then it is treated as strictly atomic type instead (i.e it isn't valid to
|
||||
* use a map or sequence for its value).
|
||||
*/
|
||||
public YContextSensitive treatAsAtomic(boolean isAtomic) {
|
||||
this.treatAsAtomic = isAtomic;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.stream.Collectors;
|
||||
import org.springframework.ide.vscode.commons.util.MimeTypes;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParsers;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
@@ -36,6 +37,7 @@ import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
|
||||
/**
|
||||
* @author Kris De Volder
|
||||
@@ -196,9 +198,19 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
addProp(task, "params", t_string_params);
|
||||
task.requireOneOf("image_resource", "image");
|
||||
|
||||
AbstractType t_put_get_name = f.contextAware("Name", (dc) -> {
|
||||
if (getParentPropertyNode("resource", models, dc)!=null) {
|
||||
return null;
|
||||
} else {
|
||||
return t_resource_name;
|
||||
}
|
||||
})
|
||||
.treatAsAtomic(true)
|
||||
.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
YBeanType getStep = f.ybean("GetStep");
|
||||
addProp(getStep, "get", t_resource_name);
|
||||
addProp(getStep, "resource", t_string);
|
||||
addProp(getStep, "get", t_put_get_name);
|
||||
addProp(getStep, "resource", t_resource_name);
|
||||
addProp(getStep, "version", t_version);
|
||||
addProp(getStep, "passed", f.yseq(t_job_name));
|
||||
addProp(getStep, "params", f.contextAware("GetParams", (dc) ->
|
||||
@@ -207,7 +219,7 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
addProp(getStep, "trigger", t_boolean);
|
||||
|
||||
YBeanType putStep = f.ybean("PutStep");
|
||||
addProp(putStep, "put", t_resource_name);
|
||||
addProp(putStep, "put", t_put_get_name);
|
||||
addProp(putStep, "resource", t_resource_name);
|
||||
addProp(putStep, "params", f.contextAware("PutParams", (dc) ->
|
||||
resourceTypes.getOutParamsType(getResourceType("put", models, dc))
|
||||
@@ -441,7 +453,10 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
}
|
||||
|
||||
private String getResourceType(String resourceNameProp, ConcourseModel models, DynamicSchemaContext dc) {
|
||||
String resourceName = getParentPropertyValue(resourceNameProp, models, dc);
|
||||
String resourceName = getParentPropertyValue("resource", models, dc);
|
||||
if (resourceName==null) {
|
||||
resourceName = getParentPropertyValue(resourceNameProp, models, dc);
|
||||
}
|
||||
if (resourceName!=null) {
|
||||
return models.getResourceType(dc.getDocument(), resourceName);
|
||||
}
|
||||
@@ -453,11 +468,15 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
}
|
||||
|
||||
private String getParentPropertyValue(String propName, ConcourseModel models, DynamicSchemaContext dc) {
|
||||
return NodeUtil.asScalar(getParentPropertyNode(propName, models, dc));
|
||||
}
|
||||
|
||||
private Node getParentPropertyNode(String propName, ConcourseModel models, DynamicSchemaContext dc) {
|
||||
YamlPath path = dc.getPath();
|
||||
if (path!=null) {
|
||||
YamlFileAST root = models.getSafeAst(dc.getDocument());
|
||||
if (root!=null) {
|
||||
return NodeUtil.asScalar(path.dropLast().append(YamlPathSegment.valueAt(propName)).traverseToNode(root));
|
||||
return path.dropLast().append(YamlPathSegment.valueAt(propName)).traverseToNode(root);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -1603,6 +1603,159 @@ public class ConcourseEditorTest {
|
||||
editor.assertHoverContains("remove", "remove the given lock from the pool");
|
||||
}
|
||||
|
||||
@Test public void reconcileExplicitResourceAttributeInPutStep() throws Exception {
|
||||
//See: https://www.pivotaltracker.com/story/show/138568839
|
||||
Editor editor;
|
||||
|
||||
editor = harness.newEditor(
|
||||
"resources:\n" +
|
||||
"- name: aws-environments\n" +
|
||||
" type: pool\n" +
|
||||
"jobs:\n" +
|
||||
"- name: test-multi-aws\n" +
|
||||
" plan:\n" +
|
||||
" - put: environment-1\n" +
|
||||
" resource: aws-environments\n" +
|
||||
" params:\n" +
|
||||
" acquire: true\n" +
|
||||
" bogus_param: bad\n" +
|
||||
" get_params:\n" +
|
||||
" bogus_get_param: bad"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"bogus_param|Unknown property",
|
||||
"bogus_get_param|Unknown property"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"resources:\n" +
|
||||
"- name: aws-environments\n" +
|
||||
" type: pool\n" +
|
||||
"jobs:\n" +
|
||||
"- name: test-multi-aws\n" +
|
||||
" plan:\n" +
|
||||
" - get: environment-1\n" +
|
||||
" resource: aws-environments\n" +
|
||||
" params:\n" +
|
||||
" bogus_param: bad\n"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"bogus_param|Unknown property"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"resources:\n" +
|
||||
"- name: aws-environments\n" +
|
||||
" type: pool\n" +
|
||||
" source:\n" +
|
||||
" uri: git@github.com:concourse/locks.git\n" +
|
||||
" branch: master\n" +
|
||||
" pool: aws\n" +
|
||||
" private_key: |\n" +
|
||||
" -----BEGIN RSA PRIVATE KEY-----\n" +
|
||||
" MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W\n" +
|
||||
" ...\n" +
|
||||
" DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l\n" +
|
||||
" -----END RSA PRIVATE KEY-----\n" +
|
||||
" username: jonhsmith\n" +
|
||||
" password: his-password\n" +
|
||||
" retry_delay: 10s\n" +
|
||||
"jobs:\n" +
|
||||
"- name: test-multi-aws\n" +
|
||||
" plan:\n" +
|
||||
" - get: aws-environments\n" +
|
||||
" params: {} \n" +
|
||||
" - put: environment-1\n" +
|
||||
" resource: aws-environments\n" +
|
||||
" params: {acquire: true}\n" +
|
||||
" - put: environment-2\n" +
|
||||
" resource: aws-environments\n" +
|
||||
" params: \n" +
|
||||
" acquire: true\n" +
|
||||
" bogus_param: blah\n" +
|
||||
" - task: test-multi-aws\n" +
|
||||
" file: my-scripts/test-multi-aws.yml\n" +
|
||||
" - put: aws-environments\n" +
|
||||
" params: {release: environment-1}\n" +
|
||||
" - put: aws-environments\n" +
|
||||
" params: {release: environment-2}"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"bogus_param|Unknown property"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resourceNameContentAssist() throws Exception {
|
||||
String conText;
|
||||
|
||||
conText =
|
||||
"resources:\n" +
|
||||
"- name: foo-resource\n" +
|
||||
"- name: bar-resource\n" +
|
||||
"- name: other-resource\n" +
|
||||
"jobs:\n" +
|
||||
"- name: test-multi-aws\n" +
|
||||
" plan:\n" +
|
||||
" - <*>";
|
||||
assertContextualCompletions(conText
|
||||
, // ==============
|
||||
"get: <*>"
|
||||
,
|
||||
"get: bar-resource<*>",
|
||||
"get: foo-resource<*>",
|
||||
"get: other-resource<*>"
|
||||
);
|
||||
assertContextualCompletions(conText
|
||||
, // ==============
|
||||
"put: <*>"
|
||||
, // ==>
|
||||
"put: bar-resource<*>",
|
||||
"put: foo-resource<*>",
|
||||
"put: other-resource<*>"
|
||||
);
|
||||
|
||||
|
||||
conText =
|
||||
"resources:\n" +
|
||||
"- name: foo-resource\n" +
|
||||
"- name: bar-resource\n" +
|
||||
"- name: other-resource\n" +
|
||||
"jobs:\n" +
|
||||
"- name: test-multi-aws\n" +
|
||||
" plan:\n" +
|
||||
" - put: something\n" +
|
||||
" <*>";
|
||||
assertContextualCompletions(conText
|
||||
, // ==============
|
||||
"resource: <*>"
|
||||
, // ==>
|
||||
"resource: bar-resource<*>",
|
||||
"resource: foo-resource<*>",
|
||||
"resource: other-resource<*>"
|
||||
);
|
||||
|
||||
conText =
|
||||
"resources:\n" +
|
||||
"- name: foo-resource\n" +
|
||||
"- name: bar-resource\n" +
|
||||
"- name: other-resource\n" +
|
||||
"jobs:\n" +
|
||||
"- name: test-multi-aws\n" +
|
||||
" plan:\n" +
|
||||
" - <*>\n" +
|
||||
" resource: foo-resource\n"; // presence of explicit 'resource' attribute should disable treating the name in put/get as a resource-name
|
||||
|
||||
assertContextualCompletions(conText,
|
||||
"put: <*>"
|
||||
// ==> NONE
|
||||
);
|
||||
assertContextualCompletions(conText,
|
||||
"get: <*>"
|
||||
// ==> NONE
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gotoResourceDefinition() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
|
||||
Reference in New Issue
Block a user