helpers/gitlab_ci_yaml_parser/data_bag.go (108 lines of code) (raw):
package gitlab_ci_yaml_parser
import (
"encoding/json"
"fmt"
"strings"
"gitlab.com/gitlab-org/gitlab-ci-multi-runner/helpers"
)
type DataBag map[string]interface{}
func (m *DataBag) Get(keys ...string) (interface{}, bool) {
return helpers.GetMapKey(*m, keys...)
}
func (m *DataBag) GetSlice(keys ...string) ([]interface{}, bool) {
slice, ok := helpers.GetMapKey(*m, keys...)
if slice != nil {
return slice.([]interface{}), ok
}
return nil, false
}
func (m *DataBag) GetStringSlice(keys ...string) (slice []string, ok bool) {
rawSlice, ok := m.GetSlice(keys...)
if !ok {
return
}
for _, rawElement := range rawSlice {
if element, ok := rawElement.(string); ok {
slice = append(slice, element)
}
}
return
}
func (m *DataBag) GetSubOptions(keys ...string) (result DataBag, ok bool) {
value, ok := helpers.GetMapKey(*m, keys...)
if ok {
result, ok = value.(map[string]interface{})
}
return
}
func (m *DataBag) GetString(keys ...string) (result string, ok bool) {
value, ok := helpers.GetMapKey(*m, keys...)
if ok {
result, ok = value.(string)
}
return
}
func (m *DataBag) Decode(result interface{}, keys ...string) error {
value, ok := m.Get(keys...)
if !ok {
return fmt.Errorf("key not found %v", strings.Join(keys, "."))
}
data, err := json.Marshal(value)
if err != nil {
return err
}
return json.Unmarshal(data, result)
}
func convertMapToStringMap(in interface{}) (out interface{}, err error) {
mapString, ok := in.(map[string]interface{})
if ok {
for k, v := range mapString {
mapString[k], err = convertMapToStringMap(v)
if err != nil {
return
}
}
return mapString, nil
}
mapInterface, ok := in.(map[interface{}]interface{})
if ok {
mapString := make(map[string]interface{})
for k, v := range mapInterface {
key, ok := k.(string)
if !ok {
return nil, fmt.Errorf("failed to convert %v to string", k)
}
mapString[key], err = convertMapToStringMap(v)
if err != nil {
return
}
}
return mapString, nil
}
return in, nil
}
func (m *DataBag) Sanitize() (err error) {
n := make(DataBag)
for k, v := range *m {
n[k], err = convertMapToStringMap(v)
if err != nil {
return
}
}
*m = n
return
}
func getOptionsMap(optionKey string, primary, secondary DataBag) (value DataBag) {
value, ok := primary.GetSubOptions(optionKey)
if !ok {
value, _ = secondary.GetSubOptions(optionKey)
}
return
}
func getOptions(optionKey string, primary, secondary DataBag) (value []interface{}, ok bool) {
value, ok = primary.GetSlice(optionKey)
if !ok {
value, ok = secondary.GetSlice(optionKey)
}
return
}