Commit adb6b43d authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

common: remove unused config methods

parent 1a15371c
......@@ -2,14 +2,10 @@ package common
import (
"fmt"
"github.com/mitchellh/mapstructure"
"github.com/mitchellh/packer/packer"
"net/url"
"os"
"path/filepath"
"reflect"
"runtime"
"sort"
"strings"
)
......@@ -23,28 +19,6 @@ func ScrubConfig(target interface{}, values ...string) string {
return conf
}
// CheckUnusedConfig is a helper that makes sure that the there are no
// unused configuration keys, properly ignoring keys that don't matter.
func CheckUnusedConfig(md *mapstructure.Metadata) *packer.MultiError {
errs := make([]error, 0)
if md.Unused != nil && len(md.Unused) > 0 {
sort.Strings(md.Unused)
for _, unused := range md.Unused {
if unused != "type" && !strings.HasPrefix(unused, "packer_") {
errs = append(
errs, fmt.Errorf("Unknown configuration key: %q", unused))
}
}
}
if len(errs) > 0 {
return &packer.MultiError{errs}
}
return nil
}
// ChooseString returns the first non-empty value.
func ChooseString(vals ...string) string {
for _, el := range vals {
......@@ -56,42 +30,6 @@ func ChooseString(vals ...string) string {
return ""
}
// DecodeConfig is a helper that handles decoding raw configuration using
// mapstructure. It returns the metadata and any errors that may happen.
// If you need extra configuration for mapstructure, you should configure
// it manually and not use this helper function.
func DecodeConfig(target interface{}, raws ...interface{}) (*mapstructure.Metadata, error) {
decodeHook, err := decodeConfigHook(raws)
if err != nil {
return nil, err
}
var md mapstructure.Metadata
decoderConfig := &mapstructure.DecoderConfig{
DecodeHook: mapstructure.ComposeDecodeHookFunc(
decodeHook,
mapstructure.StringToSliceHookFunc(","),
),
Metadata: &md,
Result: target,
WeaklyTypedInput: true,
}
decoder, err := mapstructure.NewDecoder(decoderConfig)
if err != nil {
return nil, err
}
for _, raw := range raws {
err := decoder.Decode(raw)
if err != nil {
return nil, err
}
}
return &md, nil
}
// DownloadableURL processes a URL that may also be a file path and returns
// a completely valid URL. For example, the original URL might be "local/file.iso"
// which isn't a valid URL. DownloadableURL will return "file:///local/file.iso"
......@@ -182,62 +120,3 @@ func DownloadableURL(original string) (string, error) {
return url.String(), nil
}
// This returns a mapstructure.DecodeHookFunc that automatically template
// processes any configuration values that aren't strings but have been
// provided as strings.
//
// For example: "image_id" wants an int and the user uses a string with
// a user variable like "{{user `image_id`}}". This decode hook makes that
// work.
func decodeConfigHook(raws []interface{}) (mapstructure.DecodeHookFunc, error) {
// First thing we do is decode PackerConfig so that we can have access
// to the user variables so that we can process some templates.
var pc PackerConfig
decoderConfig := &mapstructure.DecoderConfig{
Result: &pc,
WeaklyTypedInput: true,
}
decoder, err := mapstructure.NewDecoder(decoderConfig)
if err != nil {
return nil, err
}
for _, raw := range raws {
if err := decoder.Decode(raw); err != nil {
return nil, err
}
}
tpl, err := packer.NewConfigTemplate()
if err != nil {
return nil, err
}
tpl.UserVars = pc.PackerUserVars
return func(f reflect.Kind, t reflect.Kind, v interface{}) (interface{}, error) {
if t != reflect.String {
// We need to convert []uint8 to string. We have to do this
// because internally Packer uses MsgPack for RPC and the MsgPack
// codec turns strings into []uint8
if f == reflect.Slice {
dataVal := reflect.ValueOf(v)
dataType := dataVal.Type()
elemKind := dataType.Elem().Kind()
if elemKind == reflect.Uint8 {
v = string(dataVal.Interface().([]uint8))
}
}
if sv, ok := v.(string); ok {
var err error
v, err = tpl.Process(sv, nil)
if err != nil {
return nil, err
}
}
}
return v, nil
}, nil
}
......@@ -2,33 +2,14 @@ package common
import (
"fmt"
"github.com/mitchellh/mapstructure"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"testing"
)
func TestCheckUnusedConfig(t *testing.T) {
md := &mapstructure.Metadata{
Unused: make([]string, 0),
}
err := CheckUnusedConfig(md)
if err != nil {
t.Fatalf("err: %s", err)
}
md.Unused = []string{"foo", "bar"}
err = CheckUnusedConfig(md)
if err == nil {
t.Fatal("should have error")
}
}
func TestChooseString(t *testing.T) {
cases := []struct {
Input []string
......@@ -56,129 +37,6 @@ func TestChooseString(t *testing.T) {
}
}
func TestDecodeConfig(t *testing.T) {
type Local struct {
Foo string
Bar string
}
raws := []interface{}{
map[string]interface{}{
"foo": "bar",
},
map[string]interface{}{
"bar": "baz",
"baz": "what",
},
}
var result Local
md, err := DecodeConfig(&result, raws...)
if err != nil {
t.Fatalf("err: %s", err)
}
if result.Foo != "bar" {
t.Fatalf("invalid: %#v", result.Foo)
}
if result.Bar != "baz" {
t.Fatalf("invalid: %#v", result.Bar)
}
if md == nil {
t.Fatal("metadata should not be nil")
}
if !reflect.DeepEqual(md.Unused, []string{"baz"}) {
t.Fatalf("unused: %#v", md.Unused)
}
}
// This test tests the case that a user var is used for an integer
// configuration.
func TestDecodeConfig_stringToSlice(t *testing.T) {
type Local struct {
Val []string
EmptyVal []string
}
raw := map[string]interface{}{
"packer_user_variables": map[string]string{
"foo": "bar",
},
"val": "foo,{{user `foo`}}",
"emptyval": "",
}
var result Local
_, err := DecodeConfig(&result, raw)
if err != nil {
t.Fatalf("err: %s", err)
}
expected := []string{"foo", "bar"}
if !reflect.DeepEqual(result.Val, expected) {
t.Fatalf("invalid: %#v", result.Val)
}
if len(result.EmptyVal) > 0 {
t.Fatalf("invalid: %#v", result.EmptyVal)
}
}
// This test tests the case that a user var is used for an integer
// configuration.
func TestDecodeConfig_userVarConversion(t *testing.T) {
type Local struct {
Val int
}
raw := map[string]interface{}{
"packer_user_variables": map[string]string{
"foo": "42",
},
"val": "{{user `foo`}}",
}
var result Local
_, err := DecodeConfig(&result, raw)
if err != nil {
t.Fatalf("err: %s", err)
}
if result.Val != 42 {
t.Fatalf("invalid: %#v", result.Val)
}
}
// This tests the way MessagePack decodes strings (into []uint8) and
// that we can still decode into the proper types.
func TestDecodeConfig_userVarConversionUInt8(t *testing.T) {
type Local struct {
Val int
}
raw := map[string]interface{}{
"packer_user_variables": map[string]string{
"foo": "42",
},
"val": []uint8("{{user `foo`}}"),
}
var result Local
_, err := DecodeConfig(&result, raw)
if err != nil {
t.Fatalf("err: %s", err)
}
if result.Val != 42 {
t.Fatalf("invalid: %#v", result.Val)
}
}
func TestDownloadableURL(t *testing.T) {
// Invalid URL: has hex code in host
_, err := DownloadableURL("http://what%20.com")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment