diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java index dcc1dbd27..f97e574a8 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Pivotal, Inc. + * Copyright (c) 2016, 2023 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -189,6 +189,8 @@ public class YTypeFactory { return new YAtomAndMapUnion(name, atoms.get(0), maps.get(0)); } else if (atoms.size()==0 && maps.size()==0 && arrays.size()==1 && beans.size()==1) { return new YBeanAndSequenceUnion(name, beans.get(0), arrays.get(0)); + } else if (atoms.size()==1 && arrays.size()==1 && maps.size()==0 && beans.size()==0) { + return new YAtomAndSequenceUnion(name, atoms.get(0), arrays.get(0)); } throw new IllegalArgumentException("Union of this kind of types is not (yet) supported: "+types); } @@ -909,6 +911,36 @@ public class YTypeFactory { return true; } } + + public class YAtomAndSequenceUnion extends AbstractUnionType { + private final YAtomicType atomic; + private final YSeqType seq; + + public YAtomAndSequenceUnion(String name, YAtomicType atomic, YSeqType seq) { + super(name, atomic, seq); + this.atomic = atomic; + this.seq = seq; + } + @Override + public YType inferMoreSpecificType(DynamicSchemaContext dc) { + if (dc.isAtomic()) { + return atomic; + } else if (dc.isSequence()) { + return seq; + } + return super.inferMoreSpecificType(dc); + } + + @Override + public boolean isAtomic() { + return true; + } + + @Override + public boolean isSequenceable() { + return true; + } + } public static class YTypedPropertyImpl implements YTypedProperty, Cloneable { diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java index 6d3f0144a..102eb69c3 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java @@ -361,7 +361,7 @@ public class PipelineYmlSchema implements YamlSchema { YBeanType putStep = f.ybean("PutStep"); addProp(putStep, "put", t_put_get_name); addProp(putStep, "resource", t_resource_name); - addProp(putStep, "inputs", t_strings); + addProp(putStep, "inputs", f.yunion("PutStepInputs", t_strings, f.yenum("PutStepInputsAllOrDetect", "all", "detect"))); addProp(putStep, "params", f.contextAware("PutParams", (dc) -> resourceTypes.getOutParamsType(getResourceType("put", models, dc)) )); diff --git a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java index 219c998ec..71a922f57 100644 --- a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java +++ b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java @@ -2228,7 +2228,46 @@ public class ConcourseEditorTest { " - put: my-git\n" + " inputs: not-a-list\n" ); - editor.assertProblems("not-a-list|Expecting a 'Sequence'"); + editor.assertProblems("not-a-list|Valid values are: [all, detect]"); + } + + @Test + void putStepInputsReconcileAll() throws Exception { + //See: https://github.com/spring-projects/sts4/issues/341 + Editor editor = harness.newEditor( + "resources:\n" + + "- name: my-git\n" + + " type: git\n" + + " source:\n" + + " uri: https://example.com/my-name/my-repo.git\n" + + " branch: master\n" + + "jobs:\n" + + "- name: do-stuff\n" + + " plan:\n" + + " - put: my-git\n" + + " inputs: all\n" + ); + editor.assertProblems(); + } + + void putStepInputsReconcileNoProblems() throws Exception { + //See: https://github.com/spring-projects/sts4/issues/341 + Editor editor = harness.newEditor( + "resources:\n" + + "- name: my-git\n" + + " type: git\n" + + " source:\n" + + " uri: https://example.com/my-name/my-repo.git\n" + + " branch: master\n" + + "jobs:\n" + + "- name: do-stuff\n" + + " plan:\n" + + " - put: my-git\n" + + " inputs:\n" + + " - build\n" + + " - test\n" + ); + editor.assertProblems(); } @Test