Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion internal/template/groupby_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ var groupByContainers = []*context.RuntimeContainer{
ID: "3",
},
{
ID: "4",
Env: map[string]string{},
ID: "4",
},
}

Expand Down Expand Up @@ -170,6 +171,10 @@ func TestGroupByMulti(t *testing.T) {
},
ID: "3",
},
{
Env: map[string]string{},
ID: "4",
},
}

groups, _ := groupByMulti(containers, "Env.VIRTUAL_HOST", ",")
Expand Down
18 changes: 17 additions & 1 deletion internal/template/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,23 @@ func deepGetImpl(v reflect.Value, path []string) interface{} {
case reflect.Struct:
return deepGetImpl(v.FieldByName(path[0]), path[1:])
case reflect.Map:
return deepGetImpl(v.MapIndex(reflect.ValueOf(path[0])), path[1:])
// If the first part of the path is a key in the map, we use it directly
if mapValue := v.MapIndex(reflect.ValueOf(path[0])); mapValue.IsValid() {
return deepGetImpl(mapValue, path[1:])
}

// If the first part of the path is not a key in the map, we try to find a valid key by joining the path parts
for i := 2; i <= len(path); i++ {
joinedPath := strings.Join(path[0:i], ".")
if mapValue := v.MapIndex(reflect.ValueOf(joinedPath)); mapValue.IsValid() {
if i == len(path) {
return mapValue.Interface()
}
return deepGetImpl(mapValue, path[i:])
}
}

return nil
case reflect.Slice, reflect.Array:
i, err := parseAllocateInt(path[0])
if err != nil {
Expand Down
30 changes: 30 additions & 0 deletions internal/template/reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ func TestDeepGet(t *testing.T) {
path string
want interface{}
}{
{
"map of string",
map[string]string{
"Env": "quux",
},
"Env",
"quux",
},
{
"map key empty string",
map[string]map[string]map[string]string{
Expand All @@ -74,6 +82,28 @@ func TestDeepGet(t *testing.T) {
"...",
"foo",
},
{
"map with dot in key",
map[string]map[string]string{
"Env": {
"foo.bar.baz.qux": "quux",
},
},
"Env.foo.bar.baz.qux",
"quux",
},
{
"nested maps with dot in keys",
map[string]map[string]map[string]string{
"Env": {
"foo.bar": {
"baz.qux": "quux",
},
},
},
"Env.foo.bar.baz.qux",
"quux",
},
{"struct", s, "X", "foo"},
{"pointer to struct", sp, "X", "foo"},
{"double pointer to struct", &sp, ".X", nil},
Expand Down
18 changes: 15 additions & 3 deletions internal/template/sort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,36 @@ func TestSortObjectsByKeys(t *testing.T) {
Env: map[string]string{
"VIRTUAL_HOST": "bar.localhost",
},
Labels: map[string]string{
"com.docker.compose.container_number": "1",
},
ID: "11",
}
o1 := &context.RuntimeContainer{
Created: time.Date(2021, 1, 2, 0, 0, 10, 0, time.UTC),
Env: map[string]string{
"VIRTUAL_HOST": "foo.localhost",
},
Labels: map[string]string{
"com.docker.compose.container_number": "11",
},
ID: "1",
}
o2 := &context.RuntimeContainer{
Created: time.Date(2021, 1, 2, 0, 0, 0, 0, time.UTC),
Env: map[string]string{
"VIRTUAL_HOST": "baz.localhost",
},
ID: "3",
Labels: map[string]string{},
ID: "3",
}
o3 := &context.RuntimeContainer{
Created: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
Env: map[string]string{},
ID: "8",
Labels: map[string]string{
"com.docker.compose.container_number": "2",
},
ID: "8",
}
containers := []*context.RuntimeContainer{o0, o1, o2, o3}

Expand All @@ -85,9 +95,11 @@ func TestSortObjectsByKeys(t *testing.T) {
want []interface{}
}{
{"Asc simple", sortObjectsByKeysAsc, "ID", []interface{}{o1, o2, o3, o0}},
{"Asc complex", sortObjectsByKeysAsc, "Env.VIRTUAL_HOST", []interface{}{o3, o0, o2, o1}},
{"Desc simple", sortObjectsByKeysDesc, "ID", []interface{}{o0, o3, o2, o1}},
{"Asc complex", sortObjectsByKeysAsc, "Env.VIRTUAL_HOST", []interface{}{o3, o0, o2, o1}},
{"Desc complex", sortObjectsByKeysDesc, "Env.VIRTUAL_HOST", []interface{}{o1, o2, o0, o3}},
{"Asc complex w/ dots in key name", sortObjectsByKeysAsc, "Labels.com.docker.compose.container_number", []interface{}{o2, o0, o3, o1}},
{"Desc complex w/ dots in key name", sortObjectsByKeysDesc, "Labels.com.docker.compose.container_number", []interface{}{o1, o3, o0, o2}},
{"Asc time", sortObjectsByKeysAsc, "Created", []interface{}{o3, o0, o2, o1}},
{"Desc time", sortObjectsByKeysDesc, "Created", []interface{}{o1, o2, o0, o3}},
} {
Expand Down
Loading