Allow variable references in non-string fields in the JSON schema (#1398)

## Tests
Verified manually.

Before:
<img width="373" alt="Screenshot 2024-04-24 at 7 18 44 PM"
src="https://github.com/databricks/cli/assets/88374338/b4aef51f-0c16-4589-9d47-cdec9ab91158">

After:
<img width="364" alt="Screenshot 2024-04-24 at 7 18 31 PM"
src="https://github.com/databricks/cli/assets/88374338/3d8e412e-77ee-4641-943d-f99eab26ba02">
<img width="356" alt="Screenshot 2024-04-24 at 7 16 54 PM"
src="https://github.com/databricks/cli/assets/88374338/2aed369a-3c6a-4754-9c76-0969423f319e">

Manually verified the schema diff is sane. Example:
```
<                               "type": "boolean",
<                               "description": "If inference tables are enabled or not. NOTE: If you have already disabled payload logging once, you cannot enable again."
---
>                               "description": "If inference tables are enabled or not. NOTE: If you have already disabled payload logging once, you cannot enable again.",
>                               "anyOf": [
>                                 {
>                                   "type": "boolean"
>                                 },
>                                 {
>                                   "type": "string",
>                                   "pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
>                                 }
>                               ]
```
This commit is contained in:
shreyas-goenka 2024-04-25 16:50:45 +05:30 committed by GitHub
parent 4c71f8cac4
commit 6fd581d173
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 457 additions and 54 deletions

View File

@ -6,6 +6,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/databricks/cli/libs/dyn/dynvar"
"github.com/databricks/cli/libs/jsonschema" "github.com/databricks/cli/libs/jsonschema"
) )
@ -167,6 +168,22 @@ func toSchema(golangType reflect.Type, docs *Docs, tracker *tracker) (*jsonschem
} }
jsonSchema := &jsonschema.Schema{Type: rootJavascriptType} jsonSchema := &jsonschema.Schema{Type: rootJavascriptType}
// If the type is a non-string primitive, then we allow it to be a string
// provided it's a pure variable reference (ie only a single variable reference).
if rootJavascriptType == jsonschema.BooleanType || rootJavascriptType == jsonschema.NumberType {
jsonSchema = &jsonschema.Schema{
AnyOf: []*jsonschema.Schema{
{
Type: rootJavascriptType,
},
{
Type: jsonschema.StringType,
Pattern: dynvar.VariableRegex,
},
},
}
}
if docs != nil { if docs != nil {
jsonSchema.Description = docs.Description jsonSchema.Description = docs.Description
} }

View File

@ -14,7 +14,15 @@ func TestIntSchema(t *testing.T) {
expected := expected :=
`{ `{
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}` }`
schema, err := New(reflect.TypeOf(elemInt), nil) schema, err := New(reflect.TypeOf(elemInt), nil)
@ -33,7 +41,15 @@ func TestBooleanSchema(t *testing.T) {
expected := expected :=
`{ `{
"type": "boolean" "anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}` }`
schema, err := New(reflect.TypeOf(elem), nil) schema, err := New(reflect.TypeOf(elem), nil)
@ -101,46 +117,150 @@ func TestStructOfPrimitivesSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"bool_val": { "bool_val": {
"type": "boolean" "anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"float32_val": { "float32_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"float64_val": { "float64_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"int16_val": { "int16_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"int32_val": { "int32_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"int64_val": { "int64_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"int8_val": { "int8_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"int_val": { "int_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"string_val": { "string_val": {
"type": "string" "type": "string"
}, },
"uint16_val": { "uint16_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"uint32_val": { "uint32_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"uint64_val": { "uint64_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"uint8_val": { "uint8_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"uint_val": { "uint_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -200,7 +320,15 @@ func TestStructOfStructsSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"a": { "a": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"b": { "b": {
"type": "string" "type": "string"
@ -257,7 +385,15 @@ func TestStructOfMapsSchema(t *testing.T) {
"my_map": { "my_map": {
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
} }
}, },
@ -339,7 +475,15 @@ func TestMapOfPrimitivesSchema(t *testing.T) {
`{ `{
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}` }`
@ -368,7 +512,15 @@ func TestMapOfStructSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"my_int": { "my_int": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -398,7 +550,15 @@ func TestMapOfMapSchema(t *testing.T) {
"additionalProperties": { "additionalProperties": {
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
} }
}` }`
@ -495,7 +655,15 @@ func TestSliceOfMapSchema(t *testing.T) {
"items": { "items": {
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
} }
}` }`
@ -525,7 +693,15 @@ func TestSliceOfStructSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"my_int": { "my_int": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -575,7 +751,15 @@ func TestEmbeddedStructSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"country": { "country": {
"type": "string" "type": "string"
@ -607,7 +791,15 @@ func TestEmbeddedStructSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"home": { "home": {
"type": "object", "type": "object",
@ -694,7 +886,15 @@ func TestNonAnnotatedFieldsAreSkipped(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"bar": { "bar": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -728,7 +928,15 @@ func TestDashFieldsAreSkipped(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"bar": { "bar": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -773,7 +981,15 @@ func TestPointerInStructSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"ptr_val2": { "ptr_val2": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -782,13 +998,29 @@ func TestPointerInStructSchema(t *testing.T) {
] ]
}, },
"float_val": { "float_val": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"ptr_bar": { "ptr_bar": {
"type": "object", "type": "object",
"properties": { "properties": {
"ptr_val2": { "ptr_val2": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -797,7 +1029,15 @@ func TestPointerInStructSchema(t *testing.T) {
] ]
}, },
"ptr_int": { "ptr_int": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"ptr_string": { "ptr_string": {
"type": "string" "type": "string"
@ -860,7 +1100,15 @@ func TestGenericSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"name": { "name": {
"type": "string" "type": "string"
@ -875,7 +1123,15 @@ func TestGenericSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"name": { "name": {
"type": "string" "type": "string"
@ -895,7 +1151,15 @@ func TestGenericSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"name": { "name": {
"type": "string" "type": "string"
@ -910,7 +1174,15 @@ func TestGenericSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"name": { "name": {
"type": "string" "type": "string"
@ -932,7 +1204,15 @@ func TestGenericSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"name": { "name": {
"type": "string" "type": "string"
@ -950,7 +1230,15 @@ func TestGenericSchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"age": { "age": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"name": { "name": {
"type": "string" "type": "string"
@ -1028,16 +1316,40 @@ func TestFieldsWithoutOmitEmptyAreRequired(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"apple": { "apple": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"bar": { "bar": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"papaya": { "papaya": {
"type": "object", "type": "object",
"properties": { "properties": {
"a": { "a": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"b": { "b": {
"type": "string" "type": "string"
@ -1111,7 +1423,15 @@ func TestDocIngestionForObject(t *testing.T) {
"description": "docs for a" "description": "docs for a"
}, },
"b": { "b": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -1185,12 +1505,28 @@ func TestDocIngestionForSlice(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"guava": { "guava": {
"type": "number", "description": "docs for guava",
"description": "docs for guava" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"pineapple": { "pineapple": {
"type": "number", "description": "docs for pineapple",
"description": "docs for pineapple" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -1268,12 +1604,28 @@ func TestDocIngestionForMap(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"apple": { "apple": {
"type": "number", "description": "docs for apple",
"description": "docs for apple" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"mango": { "mango": {
"type": "number", "description": "docs for mango",
"description": "docs for mango" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -1324,8 +1676,16 @@ func TestDocIngestionForTopLevelPrimitive(t *testing.T) {
"description": "docs for root", "description": "docs for root",
"properties": { "properties": {
"my_val": { "my_val": {
"type": "number", "description": "docs for my val",
"description": "docs for my val" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
} }
}, },
"additionalProperties": false, "additionalProperties": false,
@ -1395,7 +1755,15 @@ func TestInterfaceGeneratesEmptySchema(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"apple": { "apple": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"mango": {} "mango": {}
}, },
@ -1436,7 +1804,15 @@ func TestBundleReadOnlytag(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"apple": { "apple": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"pokemon": { "pokemon": {
"type": "object", "type": "object",
@ -1488,7 +1864,15 @@ func TestBundleInternalTag(t *testing.T) {
"type": "object", "type": "object",
"properties": { "properties": {
"apple": { "apple": {
"type": "number" "anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "\\$\\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\\}"
}
]
}, },
"pokemon": { "pokemon": {
"type": "object", "type": "object",

View File

@ -6,7 +6,9 @@ import (
"github.com/databricks/cli/libs/dyn" "github.com/databricks/cli/libs/dyn"
) )
var re = regexp.MustCompile(`\$\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\}`) const VariableRegex = `\$\{([a-zA-Z]+([-_]?[a-zA-Z0-9]+)*(\.[a-zA-Z]+([-_]?[a-zA-Z0-9]+)*)*)\}`
var re = regexp.MustCompile(VariableRegex)
// ref represents a variable reference. // ref represents a variable reference.
// It is a string [dyn.Value] contained in a larger [dyn.Value]. // It is a string [dyn.Value] contained in a larger [dyn.Value].