mirror of https://github.com/databricks/cli.git
Refactor
This commit is contained in:
parent
6a8c0524dd
commit
5a37d661a7
|
@ -47,6 +47,8 @@ func (s *Schema) ValidateInstance(instance map[string]any) error {
|
||||||
s.validateRequired,
|
s.validateRequired,
|
||||||
s.validateTypes,
|
s.validateTypes,
|
||||||
s.validatePattern,
|
s.validatePattern,
|
||||||
|
s.validateConst,
|
||||||
|
s.validateAnyOf,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fn := range validations {
|
for _, fn := range validations {
|
||||||
|
@ -129,3 +131,32 @@ func (s *Schema) validatePattern(instance map[string]any) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Schema) validateConst(instance map[string]any) error {
|
||||||
|
for name, property := range s.Properties {
|
||||||
|
if property.Const == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v, ok := instance[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("property %s has const set to %v but no value was provided", name, property.Const)
|
||||||
|
}
|
||||||
|
if v != property.Const {
|
||||||
|
return fmt.Errorf("expected value of property %s to be %v. Found: %v", name, property.Const, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Schema) validateAnyOf(instance map[string]any) error {
|
||||||
|
if s.AnyOf == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, anyOf := range s.AnyOf {
|
||||||
|
err := anyOf.validateConst(instance)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("instance does not match any of the schemas in anyOf")
|
||||||
|
}
|
||||||
|
|
|
@ -222,3 +222,92 @@ func TestValidateInstanceForMultiplePatterns(t *testing.T) {
|
||||||
assert.EqualError(t, schema.validatePattern(invalidInstanceValue), "invalid value for bar: \"xyz\". Expected to match regex pattern: ^[d-f]+$")
|
assert.EqualError(t, schema.validatePattern(invalidInstanceValue), "invalid value for bar: \"xyz\". Expected to match regex pattern: ^[d-f]+$")
|
||||||
assert.EqualError(t, schema.ValidateInstance(invalidInstanceValue), "invalid value for bar: \"xyz\". Expected to match regex pattern: ^[d-f]+$")
|
assert.EqualError(t, schema.ValidateInstance(invalidInstanceValue), "invalid value for bar: \"xyz\". Expected to match regex pattern: ^[d-f]+$")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateInstanceForConst(t *testing.T) {
|
||||||
|
schema, err := Load("./testdata/instance-validate/test-schema-const.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Valid values for both foo and bar
|
||||||
|
validInstance := map[string]any{
|
||||||
|
"foo": "abc",
|
||||||
|
"bar": "def",
|
||||||
|
}
|
||||||
|
assert.NoError(t, schema.validateConst(validInstance))
|
||||||
|
assert.NoError(t, schema.ValidateInstance(validInstance))
|
||||||
|
|
||||||
|
// Empty instance
|
||||||
|
emptyInstanceValue := map[string]any{}
|
||||||
|
assert.ErrorContains(t, schema.validateConst(emptyInstanceValue), "but no value was provided")
|
||||||
|
assert.ErrorContains(t, schema.ValidateInstance(emptyInstanceValue), "but no value was provided")
|
||||||
|
|
||||||
|
// Missing value for bar
|
||||||
|
missingInstanceValue := map[string]any{
|
||||||
|
"foo": "abc",
|
||||||
|
}
|
||||||
|
assert.EqualError(t, schema.validateConst(missingInstanceValue), "property bar has const set to def but no value was provided")
|
||||||
|
assert.EqualError(t, schema.ValidateInstance(missingInstanceValue), "property bar has const set to def but no value was provided")
|
||||||
|
|
||||||
|
// Valid value for bar, invalid value for foo
|
||||||
|
invalidInstanceValue := map[string]any{
|
||||||
|
"foo": "xyz",
|
||||||
|
"bar": "def",
|
||||||
|
}
|
||||||
|
assert.EqualError(t, schema.validateConst(invalidInstanceValue), "expected value of property foo to be abc. Found: xyz")
|
||||||
|
assert.EqualError(t, schema.ValidateInstance(invalidInstanceValue), "expected value of property foo to be abc. Found: xyz")
|
||||||
|
|
||||||
|
// Valid value for foo, invalid value for bar
|
||||||
|
invalidInstanceValue = map[string]any{
|
||||||
|
"foo": "abc",
|
||||||
|
"bar": "xyz",
|
||||||
|
}
|
||||||
|
assert.EqualError(t, schema.validateConst(invalidInstanceValue), "expected value of property bar to be def. Found: xyz")
|
||||||
|
assert.EqualError(t, schema.ValidateInstance(invalidInstanceValue), "expected value of property bar to be def. Found: xyz")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateInstanceForAnyOf(t *testing.T) {
|
||||||
|
schema, err := Load("./testdata/instance-validate/test-schema-anyof.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Valid values for both foo and bar
|
||||||
|
validInstance := map[string]any{
|
||||||
|
"foo": "abc",
|
||||||
|
"bar": "abc",
|
||||||
|
}
|
||||||
|
assert.NoError(t, schema.validateAnyOf(validInstance))
|
||||||
|
assert.NoError(t, schema.ValidateInstance(validInstance))
|
||||||
|
|
||||||
|
// Valid values for bar
|
||||||
|
validInstance = map[string]any{
|
||||||
|
"foo": "abc",
|
||||||
|
"bar": "def",
|
||||||
|
}
|
||||||
|
assert.NoError(t, schema.validateAnyOf(validInstance))
|
||||||
|
assert.NoError(t, schema.ValidateInstance(validInstance))
|
||||||
|
|
||||||
|
// Empty instance
|
||||||
|
emptyInstanceValue := map[string]any{}
|
||||||
|
assert.EqualError(t, schema.validateAnyOf(emptyInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
assert.EqualError(t, schema.ValidateInstance(emptyInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
|
||||||
|
// Missing values for bar, invalid value for foo
|
||||||
|
missingInstanceValue := map[string]any{
|
||||||
|
"foo": "xyz",
|
||||||
|
}
|
||||||
|
assert.EqualError(t, schema.validateAnyOf(missingInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
assert.EqualError(t, schema.ValidateInstance(missingInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
|
||||||
|
// Valid value for bar, invalid value for foo
|
||||||
|
invalidInstanceValue := map[string]any{
|
||||||
|
"foo": "xyz",
|
||||||
|
"bar": "abc",
|
||||||
|
}
|
||||||
|
assert.EqualError(t, schema.validateAnyOf(invalidInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
assert.EqualError(t, schema.ValidateInstance(invalidInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
|
||||||
|
// Invalid value for both
|
||||||
|
invalidInstanceValue = map[string]any{
|
||||||
|
"bar": "xyz",
|
||||||
|
}
|
||||||
|
assert.EqualError(t, schema.validateAnyOf(invalidInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
assert.EqualError(t, schema.ValidateInstance(invalidInstanceValue), "instance does not match any of the schemas in anyOf")
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"foo": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "abc"
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "abc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"bar": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
"foo": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "abc"
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "def"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -125,36 +125,10 @@ func (c *config) skipPrompt(p jsonschema.Property, r *renderer) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if conditions specified by template author for skipping the prompt
|
validationErr := p.Schema.SkipPromptIf.ValidateInstance(c.values)
|
||||||
// are satisfied. If they are not, we have to prompt for a user input.
|
if validationErr != nil {
|
||||||
if p.Schema.SkipPromptIf.Properties != nil {
|
|
||||||
for name, property := range p.Schema.SkipPromptIf.Properties {
|
|
||||||
if v, ok := c.values[name]; ok && v == property.Const {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check if AnyOf is set first. If so, then iterate over all property sets to find a match.
|
|
||||||
// If no match is found (allFalse stays true), we have to prompt for a user input.
|
|
||||||
if p.Schema.SkipPromptIf.AnyOf != nil {
|
|
||||||
allFalse := true
|
|
||||||
for _, properties := range p.Schema.SkipPromptIf.AnyOf {
|
|
||||||
match := true
|
|
||||||
for name, property := range properties.Properties {
|
|
||||||
if v, ok := c.values[name]; !ok || v != property.Const {
|
|
||||||
match = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if match {
|
|
||||||
allFalse = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if allFalse {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Schema.Default == nil {
|
if p.Schema.Default == nil {
|
||||||
return false, fmt.Errorf("property %s has skip_prompt_if set but no default value", p.Name)
|
return false, fmt.Errorf("property %s has skip_prompt_if set but no default value", p.Name)
|
||||||
|
|
Loading…
Reference in New Issue