1
0
mirror of https://github.com/rancher/os.git synced 2025-08-19 07:19:05 +00:00

Merge pull request #848 from joshwget/show-default-values

`ros config get` shows default values
This commit is contained in:
Darren Shepherd 2016-04-01 09:21:03 -07:00
commit 97e0c01666
12 changed files with 103 additions and 18 deletions

View File

@ -211,7 +211,7 @@ func configGet(c *cli.Context) {
log.WithFields(log.Fields{"err": err}).Fatal("config get: failed to load config") log.WithFields(log.Fields{"err": err}).Fatal("config get: failed to load config")
} }
val, err := cfg.Get(arg) val, err := cfg.GetIgnoreOmitEmpty(arg)
if err != nil { if err != nil {
log.WithFields(log.Fields{"cfg": cfg, "key": arg, "val": val, "err": err}).Fatal("config get: failed to retrieve value") log.WithFields(log.Fields{"cfg": cfg, "key": arg, "val": val, "err": err}).Fatal("config get: failed to retrieve value")
} }

View File

@ -140,6 +140,16 @@ func (c *CloudConfig) Get(key string) (interface{}, error) {
return v, nil return v, nil
} }
func (c *CloudConfig) GetIgnoreOmitEmpty(key string) (interface{}, error) {
data := map[interface{}]interface{}{}
if err := util.ConvertIgnoreOmitEmpty(c, &data); err != nil {
return nil, err
}
v, _ := getOrSetVal(key, data, nil)
return v, nil
}
func (c *CloudConfig) Set(key string, value interface{}) (*CloudConfig, error) { func (c *CloudConfig) Set(key string, value interface{}) (*CloudConfig, error) {
data := map[interface{}]interface{}{} data := map[interface{}]interface{}{}
if err := util.Convert(c, &data); err != nil { if err := util.Convert(c, &data); err != nil {

View File

@ -5,7 +5,8 @@ import:
version: v0.9.0 version: v0.9.0
- package: github.com/cloudfoundry-incubator/candiedyaml - package: github.com/cloudfoundry-incubator/candiedyaml
version: 55a459c2d9da2b078f0725e5fb324823b2c71702 version: 01cbc92901719f599b11f3a7e3b1768d7002b0bb
repo: https://github.com/rancher/candiedyaml
- package: github.com/codegangsta/cli - package: github.com/codegangsta/cli
version: v1.2.0 version: v1.2.0

View File

@ -1,6 +1,7 @@
package util package util
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -68,6 +69,25 @@ func Convert(from, to interface{}) error {
return yaml.Unmarshal(bytes, to) return yaml.Unmarshal(bytes, to)
} }
func ConvertIgnoreOmitEmpty(from, to interface{}) error {
var buffer bytes.Buffer
encoder := yaml.NewEncoder(&buffer)
encoder.IgnoreOmitEmpty = true
if err := encoder.Encode(from); err != nil {
return err
}
decoder := yaml.NewDecoder(&buffer)
if err := decoder.Decode(to); err != nil {
return err
}
return nil
}
func Copy(d interface{}) interface{} { func Copy(d interface{}) interface{} {
switch d := d.(type) { switch d := d.(type) {
case map[interface{}]interface{}: case map[interface{}]interface{}:

View File

@ -25,6 +25,7 @@ func main() {
println("File does not exist:", err.Error()) println("File does not exist:", err.Error())
os.Exit(1) os.Exit(1)
} }
defer file.Close()
document := new(interface{}) document := new(interface{})
decoder := candiedyaml.NewDecoder(file) decoder := candiedyaml.NewDecoder(file)
@ -41,6 +42,7 @@ func main() {
println("Failed to open file for writing:", err.Error()) println("Failed to open file for writing:", err.Error())
os.Exit(1) os.Exit(1)
} }
defer fileToWrite.Close()
encoder := candiedyaml.NewEncoder(fileToWrite) encoder := candiedyaml.NewEncoder(fileToWrite)
err = encoder.Encode(document) err = encoder.Encode(document)

View File

@ -62,6 +62,15 @@ var _ = Describe("Decode", func() {
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal(map[interface{}]interface{}{"": ""})) Expect(v).To(Equal(map[interface{}]interface{}{"": ""}))
}) })
It("Decodes strings starting with a colon", func() {
d := NewDecoder(strings.NewReader(`:colon
`))
var v interface{}
err := d.Decode(&v)
Expect(err).NotTo(HaveOccurred())
Expect(v).To(Equal(":colon"))
})
}) })
Context("Sequence", func() { Context("Sequence", func() {

View File

@ -1276,7 +1276,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
for i, w := 0, 0; i < len(value); i += w { for i, w := 0, 0; i < len(value); i += w {
w = width(value[i]) w = width(value[i])
followed_by_whitespace = i+w >= len(value) || is_blankz_at(value, w) followed_by_whitespace = i+w >= len(value) || is_blankz_at(value, i+w)
if i == 0 { if i == 0 {
switch value[i] { switch value[i] {

View File

@ -57,6 +57,8 @@ type Encoder struct {
event yaml_event_t event yaml_event_t
flow bool flow bool
err error err error
IgnoreOmitEmpty bool
} }
func Marshal(v interface{}) ([]byte, error) { func Marshal(v interface{}) ([]byte, error) {
@ -174,7 +176,7 @@ func (e *Encoder) emitStruct(tag string, v reflect.Value) {
e.mapping(tag, func() { e.mapping(tag, func() {
for _, f := range fields { for _, f := range fields {
fv := fieldByIndex(v, f.index) fv := fieldByIndex(v, f.index)
if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) { if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) && !e.IgnoreOmitEmpty {
continue continue
} }

View File

@ -68,6 +68,14 @@ var _ = Describe("Encode", func() {
}) })
It("handles strings that contain colons followed by whitespace", func() {
err := enc.Encode("contains: colon")
Expect(err).NotTo(HaveOccurred())
Expect(buf.String()).To(Equal(`'contains: colon'
`))
})
Context("handles ints", func() { Context("handles ints", func() {
It("handles ints", func() { It("handles ints", func() {
err := enc.Encode(13) err := enc.Encode(13)
@ -303,7 +311,7 @@ int: 123
}) })
Context("Maps", func() { Context("Maps", func() {
It("Decodes simple maps", func() { It("Encodes simple maps", func() {
err := enc.Encode(&map[string]string{ err := enc.Encode(&map[string]string{
"name": "Mark McGwire", "name": "Mark McGwire",
"hr": "65", "hr": "65",
@ -315,10 +323,27 @@ int: 123
hr: "65" hr: "65"
name: Mark McGwire name: Mark McGwire
`)) `))
}) })
It("Decodes mix types", func() { It("sorts by key when strings otherwise by kind", func() {
err := enc.Encode(&map[interface{}]string{
1.2: "float",
8: "integer",
"name": "Mark McGwire",
"hr": "65",
"avg": "0.278",
})
Expect(err).NotTo(HaveOccurred())
Expect(buf.String()).To(Equal(`8: integer
1.2: float
avg: "0.278"
hr: "65"
name: Mark McGwire
`))
})
It("encodes mix types", func() {
err := enc.Encode(&map[string]interface{}{ err := enc.Encode(&map[string]interface{}{
"name": "Mark McGwire", "name": "Mark McGwire",
"hr": 65, "hr": 65,
@ -330,12 +355,11 @@ name: Mark McGwire
hr: 65 hr: 65
name: Mark McGwire name: Mark McGwire
`)) `))
}) })
}) })
Context("Sequence of Maps", func() { Context("Sequence of Maps", func() {
It("decodes", func() { It("encodes", func() {
err := enc.Encode([]map[string]interface{}{ err := enc.Encode([]map[string]interface{}{
{"name": "Mark McGwire", {"name": "Mark McGwire",
"hr": 65, "hr": 65,
@ -360,7 +384,7 @@ name: Mark McGwire
}) })
Context("Maps of Sequence", func() { Context("Maps of Sequence", func() {
It("decodes", func() { It("encodes", func() {
err := enc.Encode(map[string][]interface{}{ err := enc.Encode(map[string][]interface{}{
"name": []interface{}{"Mark McGwire", "Sammy Sosa"}, "name": []interface{}{"Mark McGwire", "Sammy Sosa"},
"hr": []interface{}{65, 63}, "hr": []interface{}{65, 63},

View File

@ -323,7 +323,7 @@ func resolve_time(val string, v reflect.Value, event yaml_event_t) (string, erro
} else { } else {
matches = timestamp_regexp.FindStringSubmatch(val) matches = timestamp_regexp.FindStringSubmatch(val)
if len(matches) == 0 { if len(matches) == 0 {
return "", fmt.Errorf("Invalid timestap: '%s' at %s", val, event.start_mark) return "", fmt.Errorf("Invalid timestamp: '%s' at %s", val, event.start_mark)
} }
year, _ := strconv.Atoi(matches[1]) year, _ := strconv.Atoi(matches[1])

View File

@ -909,7 +909,7 @@ func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
b == '@' || b == '`') || b == '@' || b == '`') ||
(b == '-' && !is_blank(buf[pos+1])) || (b == '-' && !is_blank(buf[pos+1])) ||
(parser.flow_level == 0 && (parser.flow_level == 0 &&
(buf[pos] == '?' || buf[pos+1] == ':') && (buf[pos] == '?' || buf[pos] == ':') &&
!is_blank(buf[pos+1])) { !is_blank(buf[pos+1])) {
return yaml_parser_fetch_plain_scalar(parser) return yaml_parser_fetch_plain_scalar(parser)
} }

View File

@ -308,8 +308,25 @@ type stringValues []reflect.Value
func (sv stringValues) Len() int { return len(sv) } func (sv stringValues) Len() int { return len(sv) }
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) } func (sv stringValues) Less(i, j int) bool {
func (sv stringValues) get(i int) string { return sv[i].String() } av, ak := getElem(sv[i])
bv, bk := getElem(sv[j])
if ak == reflect.String && bk == reflect.String {
return av.String() < bv.String()
}
return ak < bk
}
func getElem(v reflect.Value) (reflect.Value, reflect.Kind) {
k := v.Kind()
for k == reflect.Interface || k == reflect.Ptr && !v.IsNil() {
v = v.Elem()
k = v.Kind()
}
return v, k
}
// parseTag splits a struct field's json tag into its name and // parseTag splits a struct field's json tag into its name and
// comma-separated options. // comma-separated options.