Reviewers: mp+221156_code.launchpad.net,
Message: Please take a look.
Description: Allow charms without a peer listed.
https://code.launchpad.net/~jimmiebtlr/juju-core/fix-no-peers-charms/+merge/221156
(do not edit description out of merge proposal)
Please review this at https://codereview.appspot.com/101810046/
Affected files (+61, -24 lines): A [revision details] M charm/meta.go M charm/meta_test.go M schema/schema.go M schema/schema_test.go A testing/repo/quantal/empty-fields/metadata.yaml
Index: [revision details] === added file '[revision details]' --- [revision details] 2012-01-01 00:00:00 +0000 +++ [revision details] 2012-01-01 00:00:00 +0000 @@ -0,0 +1,2 @@ +Old revision: tarmac-20140528050243-agcci9rl0vqrr911 +New revision: <email address hidden>
Index: charm/meta.go === modified file 'charm/meta.go' --- charm/meta.go 2014-04-09 16:36:12 +0000 +++ charm/meta.go 2014-05-21 01:59:05 +0000 @@ -96,13 +96,13 @@ Summary string Description string Subordinate bool - Provides map[string]Relation `bson:",omitempty"` - Requires map[string]Relation `bson:",omitempty"` - Peers map[string]Relation `bson:",omitempty"` - Format int `bson:",omitempty"` - OldRevision int `bson:",omitempty"` // Obsolete - Categories []string `bson:",omitempty"` - Series string `bson:",omitempty"` + Provides map[string]Relation + Requires map[string]Relation + Peers map[string]Relation + Format int `bson:",omitempty"` + OldRevision int `bson:",omitempty"` // Obsolete + Categories []string `bson:",omitempty"` + Series string `bson:",omitempty"` }
func generateRelationHooks(relName string, allHooks map[string]bool) { @@ -262,10 +262,10 @@ }
func parseRelations(relations interface{}, role RelationRole) map[string]Relation { + result := make(map[string]Relation) if relations == nil { - return nil + return result } - result := make(map[string]Relation) for name, rel := range relations.(map[string]interface{}) { relMap := rel.(map[string]interface{}) relation := Relation{
Index: charm/meta_test.go === modified file 'charm/meta_test.go' --- charm/meta_test.go 2014-04-09 16:36:12 +0000 +++ charm/meta_test.go 2014-05-28 05:01:55 +0000 @@ -93,8 +93,8 @@ Interface: "mysql", Scope: charm.ScopeGlobal, }) - c.Assert(meta.Requires, gc.IsNil) - c.Assert(meta.Peers, gc.IsNil) + c.Assert(meta.Requires, gc.DeepEquals, map[string]charm.Relation{}) + c.Assert(meta.Peers, gc.DeepEquals, map[string]charm.Relation{})
meta, err = charm.ReadMeta(repoMeta("riak")) c.Assert(err, gc.IsNil) @@ -117,7 +117,7 @@ Limit: 1, Scope: charm.ScopeGlobal, }) - c.Assert(meta.Requires, gc.IsNil) + c.Assert(meta.Requires, gc.DeepEquals, map[string]charm.Relation{})
meta, err = charm.ReadMeta(repoMeta("terracotta")) c.Assert(err, gc.IsNil) @@ -135,7 +135,7 @@ Limit: 1, Scope: charm.ScopeGlobal, }) - c.Assert(meta.Requires, gc.IsNil) + c.Assert(meta.Requires, gc.DeepEquals, map[string]charm.Relation{})
meta, err = charm.ReadMeta(repoMeta("wordpress")) c.Assert(err, gc.IsNil) @@ -160,7 +160,13 @@ Optional: true, Scope: charm.ScopeGlobal, }) - c.Assert(meta.Peers, gc.IsNil) + c.Assert(meta.Peers, gc.DeepEquals, map[string]charm.Relation{}) + + meta, err = charm.ReadMeta(repoMeta("empty-fields")) + c.Assert(err, gc.IsNil) + c.Assert(meta.Provides, gc.DeepEquals, map[string]charm.Relation{}) + c.Assert(meta.Requires, gc.DeepEquals, map[string]charm.Relation{}) + c.Assert(meta.Peers, gc.DeepEquals, map[string]charm.Relation{}) }
var relationsConstraintsTests = []struct { @@ -396,12 +402,15 @@ for i, codec := range codecs { c.Logf("codec %d", i) empty_input := charm.Meta{} + empty_input.Provides = make(map[string]charm.Relation) + empty_input.Peers = make(map[string]charm.Relation) + empty_input.Requires = make(map[string]charm.Relation) data, err := codec.Marshal(empty_input) c.Assert(err, gc.IsNil) var empty_output charm.Meta err = codec.Unmarshal(data, &empty_output) c.Assert(err, gc.IsNil) - c.Assert(empty_input, gc.DeepEquals, empty_output) + c.Assert(empty_output, gc.DeepEquals, empty_input) } }
Index: schema/schema.go === modified file 'schema/schema.go' --- schema/schema.go 2014-01-15 10:50:11 +0000 +++ schema/schema.go 2014-05-21 01:38:00 +0000 @@ -293,6 +293,11 @@
func (c mapC) Coerce(v interface{}, path []string) (interface{}, error) { rv := reflect.ValueOf(v) + + // treat nil value as empty map + if rv.Kind() == reflect.Invalid { + return make(map[interface{}]interface{}), nil + } if rv.Kind() != reflect.Map { return nil, error_{"map", v, path} } @@ -334,6 +339,11 @@
func (c stringMapC) Coerce(v interface{}, path []string) (interface{}, error) { rv := reflect.ValueOf(v) + + // treat nil value as empty map + if rv.Kind() == reflect.Invalid { + return make(map[string]interface{}), nil + } if rv.Kind() != reflect.Map { return nil, error_{"map", v, path} } @@ -399,6 +409,11 @@
func (c fieldMapC) Coerce(v interface{}, path []string) (interface{}, error) { rv := reflect.ValueOf(v) + + // treat nil value as empty map + if rv.Kind() == reflect.Invalid { + return make(map[string]interface{}), nil + } if rv.Kind() != reflect.Map { return nil, error_{"map", v, path} } @@ -488,6 +503,11 @@
func (c mapSetC) Coerce(v interface{}, path []string) (interface{}, error) { rv := reflect.ValueOf(v) + + // treat nil value as empty map + if rv.Kind() == reflect.Invalid { + return make(map[string]interface{}), nil + } if rv.Kind() != reflect.Map { return nil, error_{"map", v, path} }
Index: schema/schema_test.go === modified file 'schema/schema_test.go' --- schema/schema_test.go 2014-01-14 13:10:26 +0000 +++ schema/schema_test.go 2014-05-28 04:58:04 +0000 @@ -250,8 +250,8 @@ c.Assert(err, gc.ErrorMatches, "<path>: expected map, got int\\(42\\)")
out, err = sch.Coerce(nil, aPath) - c.Assert(out, gc.IsNil) - c.Assert(err, gc.ErrorMatches, "<path>: expected map, got nothing") + c.Assert(err, gc.IsNil) + c.Assert(out, gc.DeepEquals, map[interface{}]interface{}{})
out, err = sch.Coerce(map[int]int{1: 1}, aPath) c.Assert(out, gc.IsNil) @@ -274,12 +274,12 @@ c.Assert(out, gc.DeepEquals, map[string]interface{}{"a": int64(1), "b": int64(2)})
out, err = sch.Coerce(42, aPath) - c.Assert(out, gc.IsNil) c.Assert(err, gc.ErrorMatches, "<path>: expected map, got int\\(42\\)") + c.Assert(out, gc.IsNil)
out, err = sch.Coerce(nil, aPath) - c.Assert(out, gc.IsNil) - c.Assert(err, gc.ErrorMatches, "<path>: expected map, got nothing") + c.Assert(err, gc.IsNil) + c.Assert(out, gc.DeepEquals, map[string]interface{}{})
out, err = sch.Coerce(map[int]int{1: 1}, aPath) c.Assert(out, gc.IsNil) @@ -306,8 +306,8 @@ c.Assert(err, gc.ErrorMatches, "<path>: expected map, got int\\(42\\)")
out, err = sch.Coerce(map[string]interface{}{"a": "A", "b": "C"}, aPath) c.Assert(out, gc.IsNil) @@ -416,8 +416,8 @@ c.Assert(err, gc.ErrorMatches, `<path>: expected map, got int\(42\)`)
out, err = sch.Coerce(nil, aPath) - c.Assert(out, gc.IsNil) - c.Assert(err, gc.ErrorMatches, `<path>: expected map, got nothing`) + c.Assert(err, gc.IsNil) + c.Assert(out, gc.DeepEquals, map[string]interface{}{})
// First path entry shouldn't have dots in an error message. out, err = sch.Coerce(map[string]int{"a": 1}, nil)
Index: testing/repo/quantal/empty-fields/metadata.yaml === added file 'testing/repo/quantal/empty-fields/metadata.yaml' --- testing/repo/quantal/empty-fields/metadata.yaml 1970-01-01 00:00:00 +0000 +++ testing/repo/quantal/empty-fields/metadata.yaml 2014-05-03 17:48:01 +0000 @@ -0,0 +1,6 @@ +name: empty-fields +summary: "Kerosene powered blender" +description: "Description here" +provides: +peers: +requires:
« Back to merge proposal
Reviewers: mp+221156_ code.launchpad. net,
Message:
Please take a look.
Description:
Allow charms without a peer listed.
https:/ /code.launchpad .net/~jimmiebtl r/juju- core/fix- no-peers- charms/ +merge/ 221156
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/101810046/
Affected files (+61, -24 lines): schema_ test.go repo/quantal/ empty-fields/ metadata. yaml
A [revision details]
M charm/meta.go
M charm/meta_test.go
M schema/schema.go
M schema/
A testing/
Index: [revision details] 20140528050243- agcci9rl0vqrr91 1
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-
+New revision: <email address hidden>
Index: charm/meta.go
=== modified file 'charm/meta.go'
--- charm/meta.go 2014-04-09 16:36:12 +0000
+++ charm/meta.go 2014-05-21 01:59:05 +0000
@@ -96,13 +96,13 @@
Summary string
Description string
Subordinate bool
- Provides map[string]Relation `bson:",omitempty"`
- Requires map[string]Relation `bson:",omitempty"`
- Peers map[string]Relation `bson:",omitempty"`
- Format int `bson:",omitempty"`
- OldRevision int `bson:",omitempty"` // Obsolete
- Categories []string `bson:",omitempty"`
- Series string `bson:",omitempty"`
+ Provides map[string]Relation
+ Requires map[string]Relation
+ Peers map[string]Relation
+ Format int `bson:",omitempty"`
+ OldRevision int `bson:",omitempty"` // Obsolete
+ Categories []string `bson:",omitempty"`
+ Series string `bson:",omitempty"`
}
func generateRelatio nHooks( relName string, allHooks map[string]bool) {
@@ -262,10 +262,10 @@
}
func parseRelations( relations interface{}, role RelationRole) string] Relation) string] Relation) (map[string] interface{ }) { string] interface{ })
map[string]Relation {
+ result := make(map[
if relations == nil {
- return nil
+ return result
}
- result := make(map[
for name, rel := range relations.
relMap := rel.(map[
relation := Relation{
Index: charm/meta_test.go meta_test. go' meta.Requires, gc.IsNil) meta.Peers, gc.IsNil) meta.Requires, gc.DeepEquals, map[string] charm.Relation{ }) meta.Peers, gc.DeepEquals, map[string] charm.Relation{ })
=== modified file 'charm/
--- charm/meta_test.go 2014-04-09 16:36:12 +0000
+++ charm/meta_test.go 2014-05-28 05:01:55 +0000
@@ -93,8 +93,8 @@
Interface: "mysql",
Scope: charm.ScopeGlobal,
})
- c.Assert(
- c.Assert(
+ c.Assert(
+ c.Assert(
meta, err = charm.ReadMeta( repoMeta( "riak") ) meta.Requires, gc.IsNil) meta.Requires, gc.DeepEquals, map[string] charm.Relation{ })
c.Assert(err, gc.IsNil)
@@ -117,7 +117,7 @@
Limit: 1,
Scope: charm.ScopeGlobal,
})
- c.Assert(
+ c.Assert(
meta, err = charm.ReadMeta( repoMeta( "terracotta" )) meta.Requires, gc.IsNil) meta.Requires, gc.DeepEquals, map[string] charm.Relation{ })
c.Assert(err, gc.IsNil)
@@ -135,7 +135,7 @@
Limit: 1,
Scope: charm.ScopeGlobal,
})
- c.Assert(
+ c.Assert(
meta, err = charm.ReadMeta( repoMeta( "wordpress" )) meta.Peers, gc.IsNil) meta.Peers, gc.DeepEquals, map[string] charm.Relation{ }) repoMeta( "empty- fields" )) meta.Provides, gc.DeepEquals, map[string] charm.Relation{ }) meta.Requires, gc.DeepEquals, map[string] charm.Relation{ }) meta.Peers, gc.DeepEquals, map[string] charm.Relation{ })
c.Assert(err, gc.IsNil)
@@ -160,7 +160,13 @@
Optional: true,
Scope: charm.ScopeGlobal,
})
- c.Assert(
+ c.Assert(
+
+ meta, err = charm.ReadMeta(
+ c.Assert(err, gc.IsNil)
+ c.Assert(
+ c.Assert(
+ c.Assert(
}
var relationsConstr aintsTests = []struct { Provides = make(map[ string] charm.Relation) string] charm.Relation) Requires = make(map[ string] charm.Relation) empty_input) (data, &empty_output) empty_input, gc.DeepEquals, empty_output) empty_output, gc.DeepEquals, empty_input)
@@ -396,12 +402,15 @@
for i, codec := range codecs {
c.Logf("codec %d", i)
empty_input := charm.Meta{}
+ empty_input.
+ empty_input.Peers = make(map[
+ empty_input.
data, err := codec.Marshal(
c.Assert(err, gc.IsNil)
var empty_output charm.Meta
err = codec.Unmarshal
c.Assert(err, gc.IsNil)
- c.Assert(
+ c.Assert(
}
}
Index: schema/schema.go
=== modified file 'schema/schema.go'
--- schema/schema.go 2014-01-15 10:50:11 +0000
+++ schema/schema.go 2014-05-21 01:38:00 +0000
@@ -293,6 +293,11 @@
func (c mapC) Coerce(v interface{}, path []string) (interface{}, error) { interface{ }]interface{ }), nil
rv := reflect.ValueOf(v)
+
+ // treat nil value as empty map
+ if rv.Kind() == reflect.Invalid {
+ return make(map[
+ }
if rv.Kind() != reflect.Map {
return nil, error_{"map", v, path}
}
@@ -334,6 +339,11 @@
func (c stringMapC) Coerce(v interface{}, path []string) (interface{}, string] interface{ }), nil
error) {
rv := reflect.ValueOf(v)
+
+ // treat nil value as empty map
+ if rv.Kind() == reflect.Invalid {
+ return make(map[
+ }
if rv.Kind() != reflect.Map {
return nil, error_{"map", v, path}
}
@@ -399,6 +409,11 @@
func (c fieldMapC) Coerce(v interface{}, path []string) (interface{}, string] interface{ }), nil
error) {
rv := reflect.ValueOf(v)
+
+ // treat nil value as empty map
+ if rv.Kind() == reflect.Invalid {
+ return make(map[
+ }
if rv.Kind() != reflect.Map {
return nil, error_{"map", v, path}
}
@@ -488,6 +503,11 @@
func (c mapSetC) Coerce(v interface{}, path []string) (interface{}, error) string] interface{ }), nil
{
rv := reflect.ValueOf(v)
+
+ // treat nil value as empty map
+ if rv.Kind() == reflect.Invalid {
+ return make(map[
+ }
if rv.Kind() != reflect.Map {
return nil, error_{"map", v, path}
}
Index: schema/ schema_ test.go schema_ test.go' schema_ test.go 2014-01-14 13:10:26 +0000 schema_ test.go 2014-05-28 04:58:04 +0000
=== modified file 'schema/
--- schema/
+++ schema/
@@ -250,8 +250,8 @@
c.Assert(err, gc.ErrorMatches, "<path>: expected map, got int\\(42\\)")
out, err = sch.Coerce(nil, aPath) }]interface{ }{})
- c.Assert(out, gc.IsNil)
- c.Assert(err, gc.ErrorMatches, "<path>: expected map, got nothing")
+ c.Assert(err, gc.IsNil)
+ c.Assert(out, gc.DeepEquals, map[interface{
out, err = sch.Coerce( map[int] int{1: 1}, aPath) interface{ }{"a": int64(1), "b":
c.Assert(out, gc.IsNil)
@@ -274,12 +274,12 @@
c.Assert(out, gc.DeepEquals, map[string]
int64(2)})
out, err = sch.Coerce(42, aPath)
- c.Assert(out, gc.IsNil)
c.Assert(err, gc.ErrorMatches, "<path>: expected map, got int\\(42\\)")
+ c.Assert(out, gc.IsNil)
out, err = sch.Coerce(nil, aPath) interface{ }{})
- c.Assert(out, gc.IsNil)
- c.Assert(err, gc.ErrorMatches, "<path>: expected map, got nothing")
+ c.Assert(err, gc.IsNil)
+ c.Assert(out, gc.DeepEquals, map[string]
out, err = sch.Coerce( map[int] int{1: 1}, aPath)
c.Assert(out, gc.IsNil)
@@ -306,8 +306,8 @@
c.Assert(err, gc.ErrorMatches, "<path>: expected map, got int\\(42\\)")
out, err = sch.Coerce(nil, aPath) interface{ }{})
- c.Assert(out, gc.IsNil)
- c.Assert(err, gc.ErrorMatches, "<path>: expected map, got nothing")
+ c.Assert(err, gc.IsNil)
+ c.Assert(out, gc.DeepEquals, map[string]
out, err = sch.Coerce( map[string] interface{ }{"a": "A", "b": "C"}, aPath)
c.Assert(out, gc.IsNil)
@@ -416,8 +416,8 @@
c.Assert(err, gc.ErrorMatches, `<path>: expected map, got int\(42\)`)
out, err = sch.Coerce(nil, aPath) interface{ }{})
- c.Assert(out, gc.IsNil)
- c.Assert(err, gc.ErrorMatches, `<path>: expected map, got nothing`)
+ c.Assert(err, gc.IsNil)
+ c.Assert(out, gc.DeepEquals, map[string]
// First path entry shouldn't have dots in an error message. map[string] int{"a" : 1}, nil)
out, err = sch.Coerce(
Index: testing/ repo/quantal/ empty-fields/ metadata. yaml repo/quantal/ empty-fields/ metadata. yaml' repo/quantal/ empty-fields/ metadata. yaml 1970-01-01 00:00:00 repo/quantal/ empty-fields/ metadata. yaml 2014-05-03 17:48:01
=== added file 'testing/
--- testing/
+0000
+++ testing/
+0000
@@ -0,0 +1,6 @@
+name: empty-fields
+summary: "Kerosene powered blender"
+description: "Description here"
+provides:
+peers:
+requires: