Some tweaks to the contraints checking for releases.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.bosh;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems.MISSING_PROPERTY;
|
||||
import static org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems.problem;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
import org.yaml.snakeyaml.nodes.NodeTuple;
|
||||
|
||||
public class BoshConstraints {
|
||||
|
||||
public static final Constraint SHA1_REQUIRED_FOR_HTTP_URL = new Constraint() {
|
||||
|
||||
@Override
|
||||
public void verify(DynamicSchemaContext dc, Node parent, Node node, YType type, IProblemCollector problems) {
|
||||
NodeTuple urlProp = NodeUtil.getPropertyTuple(node, "url");
|
||||
if (urlProp!=null) {
|
||||
String url = NodeUtil.asScalar(urlProp.getValueNode());
|
||||
if (url!=null && url.startsWith("http")) {
|
||||
Node sha1 = NodeUtil.getProperty(node, "sha1");
|
||||
if (sha1==null) {
|
||||
problems.accept(problem(MISSING_PROPERTY, "'sha1' is required when the 'url' is http(s)", urlProp.getKeyNode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -142,15 +142,15 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
|
||||
YBeanType t_release = f.ybean("Release");
|
||||
addProp(t_release, "name", t_ne_string).isPrimary(true);
|
||||
addProp(t_release, "version", t_version).isRequired(true); //TODO: Is it really required? Maybe not id we use url + sha
|
||||
//See: https://github.com/cloudfoundry/docs-bosh/issues/330
|
||||
addProp(t_release, "version", t_version);
|
||||
//TODO: the checking here is just 'my best guess'. Unclarity remains:
|
||||
// See: https://github.com/cloudfoundry/docs-bosh/issues/330
|
||||
addProp(t_release, "url", t_url);
|
||||
addProp(t_release, "sha1", t_ne_string);
|
||||
addProp(v2Schema, "releases", f.yseq(t_release)).isRequired(true);
|
||||
//TODO: these extra checks disabled because we aren't sure they are valid
|
||||
// See: https://github.com/cloudfoundry/docs-bosh/issues/330
|
||||
// t_release.require(Constraints.requireOneOf("url", "version"));
|
||||
// t_release.require(Constraints.mutuallyExclusive("version", "sha1"));
|
||||
t_release.require(Constraints.requireAtLeastOneOf("url", "version")); //allthough docs seem to imply you shouldn't define both url and version..
|
||||
//... it seems bosh tolerates it.
|
||||
t_release.require(BoshConstraints.SHA1_REQUIRED_FOR_HTTP_URL);
|
||||
|
||||
YBeanType t_stemcell = f.ybean("Stemcell");
|
||||
addProp(t_stemcell, "alias", t_ne_string).isRequired(true);
|
||||
|
||||
@@ -232,7 +232,22 @@ public class BoshEditorTest {
|
||||
" version: <*>"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test public void releasesBlockSha1RequiredForHttpUrl() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"releases:\n" +
|
||||
"- name: some-release\n" +
|
||||
" url: https://my.releases.com/funky.tar.gz\n" +
|
||||
"- name: other-relase\n" +
|
||||
" url: file:///root/releases/a-nice-file.tar.gz\n" +
|
||||
"#x"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"url|'sha1' is required when the 'url' is http(s)",
|
||||
"x|are required"
|
||||
);
|
||||
}
|
||||
|
||||
@Test public void releasesBlockReconcileAndHovers() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"releases:\n" +
|
||||
|
||||
@@ -116,6 +116,18 @@ public class NodeUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static NodeTuple getPropertyTuple(Node node, String propName) {
|
||||
if (node instanceof MappingNode) {
|
||||
for (NodeTuple entry : ((MappingNode)node).getValue()) {
|
||||
String key = NodeUtil.asScalar(entry.getKeyNode());
|
||||
if (propName.equals(key)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Node getProperty(Node node, String propName) {
|
||||
if (node instanceof MappingNode) {
|
||||
for (NodeTuple entry : ((MappingNode)node).getValue()) {
|
||||
|
||||
@@ -49,17 +49,28 @@ public class Constraints {
|
||||
public static Constraint requireAtMostOneOf(String... properties) {
|
||||
return new RequireOneOf(properties).allowFewer(true);
|
||||
}
|
||||
|
||||
public static Constraint requireAtLeastOneOf(String... properties) {
|
||||
return new RequireOneOf(properties).allowMultiple(true);
|
||||
}
|
||||
|
||||
|
||||
static private class RequireOneOf implements Constraint {
|
||||
|
||||
private final String[] _requiredProps;
|
||||
private boolean allowFewer = false;
|
||||
private boolean allowMultiple = false;
|
||||
|
||||
public RequireOneOf(String[] properties) {
|
||||
Assert.isLegal(properties.length>1);
|
||||
this._requiredProps = properties;
|
||||
}
|
||||
|
||||
public Constraint allowMultiple(boolean b) {
|
||||
this.allowMultiple = b;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Constraint allowFewer(boolean b) {
|
||||
this.allowFewer = b;
|
||||
return this;
|
||||
@@ -80,7 +91,7 @@ public class Constraints {
|
||||
problems.accept(missingProperty(
|
||||
"One of "+requiredProps+" is required for '"+type+"'", doc, parent, map));
|
||||
}
|
||||
} else if (foundPropsCount>1) {
|
||||
} else if (foundPropsCount>1 && !allowMultiple) {
|
||||
//Mark each of the found keys as a violation:
|
||||
for (NodeTuple entry : map.getValue()) {
|
||||
String key = NodeUtil.asScalar(entry.getKeyNode());
|
||||
@@ -144,4 +155,5 @@ public class Constraints {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user