1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

Convert invalid config value types (#1408)

Co-authored-by: Daniel Kurzynski <daniel.kurzynski@sap.com>
This commit is contained in:
Stephan Aßmus 2020-04-17 10:29:18 +02:00 committed by GitHub
parent 6d7ab39e29
commit a09482a14f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import (
"io"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/SAP/jenkins-library/pkg/config"
@ -154,6 +155,7 @@ func PrepareConfig(cmd *cobra.Command, metadata *config.StepData, stepName strin
}
}
stepConfig.Config = convertTypes(stepConfig.Config, options)
confJSON, _ := json.Marshal(stepConfig.Config)
_ = json.Unmarshal(confJSON, &options)
@ -162,6 +164,70 @@ func PrepareConfig(cmd *cobra.Command, metadata *config.StepData, stepName strin
return nil
}
func convertTypes(config map[string]interface{}, options interface{}) map[string]interface{} {
optionsType := getStepOptionsStructType(options)
for paramName := range config {
optionsField := findStructFieldByJSONTag(paramName, optionsType)
if optionsField == nil {
continue
}
paramValueType := reflect.ValueOf(config[paramName])
if paramValueType.Kind() != reflect.String {
// We can only convert from strings at the moment
continue
}
paramValue := paramValueType.String()
logWarning := true
switch optionsField.Type.Kind() {
case reflect.String:
// Types already match, ignore
logWarning = false
case reflect.Slice, reflect.Array:
if optionsField.Type.Elem().Kind() == reflect.String {
config[paramName] = []string{paramValue}
logWarning = false
}
case reflect.Bool:
paramValue = strings.ToLower(paramValue)
if paramValue == "true" {
config[paramName] = true
logWarning = false
} else if paramValue == "false" {
config[paramName] = false
logWarning = false
}
}
if logWarning {
log.Entry().Warnf("Config value for '%s' is of unexpected type and is ignored", paramName)
}
}
return config
}
func findStructFieldByJSONTag(tagName string, optionsType reflect.Type) *reflect.StructField {
for i := 0; i < optionsType.NumField(); i++ {
field := optionsType.Field(i)
tag := field.Tag.Get("json")
if tagName == tag || tagName+",omitempty" == tag {
return &field
}
}
return nil
}
func getStepOptionsStructType(stepOptions interface{}) reflect.Type {
typedOptions := reflect.ValueOf(stepOptions)
if typedOptions.Kind() == reflect.Ptr {
typedOptions = typedOptions.Elem()
}
return typedOptions.Type()
}
func getProjectConfigFile(name string) string {
var altName string

View File

@ -1,6 +1,7 @@
package cmd
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
@ -128,3 +129,38 @@ func TestGetProjectConfigFile(t *testing.T) {
})
}
}
func TestConvertTypes(t *testing.T) {
// Init
options := struct {
Foo []string `json:"foo,omitempty"`
Bar bool `json:"bar,omitempty"`
Baz string `json:"baz,omitempty"`
Bla int `json:"bla,omitempty"`
}{}
stepConfig := map[string]interface{}{}
stepConfig["baz"] = "ignore"
stepConfig["foo"] = "element"
stepConfig["bar"] = "True"
stepConfig["bla"] = "42"
// Test
stepConfig = convertTypes(stepConfig, options)
confJSON, _ := json.Marshal(stepConfig)
_ = json.Unmarshal(confJSON, &options)
// Assert
assert.Equal(t, []string{"element"}, stepConfig["foo"])
assert.Equal(t, true, stepConfig["bar"])
assert.Equal(t, []string{"element"}, options.Foo)
assert.Equal(t, true, options.Bar)
assert.Equal(t, "ignore", stepConfig["baz"])
assert.Equal(t, "42", stepConfig["bla"])
assert.Equal(t, "ignore", options.Baz)
assert.Equal(t, 0, options.Bla)
}