Fix sorting printer with missing fields

This commit is contained in:
Fabiano Franz
2017-01-26 17:26:00 -02:00
parent 0107e93cc6
commit 5eeef81edf
3 changed files with 176 additions and 29 deletions

View File

@@ -88,17 +88,6 @@ func (s *SortingPrinter) sortObj(obj runtime.Object) error {
}
func SortObjects(decoder runtime.Decoder, objs []runtime.Object, fieldInput string) (*RuntimeSort, error) {
parser := jsonpath.New("sorting")
field, err := massageJSONPath(fieldInput)
if err != nil {
return nil, err
}
if err := parser.Parse(field); err != nil {
return nil, err
}
for ix := range objs {
item := objs[ix]
switch u := item.(type) {
@@ -112,18 +101,38 @@ func SortObjects(decoder runtime.Decoder, objs []runtime.Object, fieldInput stri
}
}
var values [][]reflect.Value
if unstructured, ok := objs[0].(*unstructured.Unstructured); ok {
values, err = parser.FindResults(unstructured.Object)
} else {
values, err = parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface())
}
field, err := massageJSONPath(fieldInput)
if err != nil {
return nil, err
}
if len(values) == 0 {
return nil, fmt.Errorf("couldn't find any field with path: %s", field)
parser := jsonpath.New("sorting").AllowMissingKeys(true)
if err := parser.Parse(field); err != nil {
return nil, err
}
// We don't do any model validation here, so we traverse all objects to be sorted
// and, if the field is valid to at least one of them, we consider it to be a
// valid field; otherwise error out.
// Note that this requires empty fields to be considered later, when sorting.
var fieldFoundOnce bool
for _, obj := range objs {
var values [][]reflect.Value
if unstructured, ok := obj.(*unstructured.Unstructured); ok {
values, err = parser.FindResults(unstructured.Object)
} else {
values, err = parser.FindResults(reflect.ValueOf(obj).Elem().Interface())
}
if err != nil {
return nil, err
}
if len(values) > 0 && len(values[0]) > 0 {
fieldFoundOnce = true
break
}
}
if !fieldFoundOnce {
return nil, fmt.Errorf("couldn't find any field with path %q in the list of objects", field)
}
sorter := NewRuntimeSort(field, objs)
@@ -260,7 +269,7 @@ func (r *RuntimeSort) Less(i, j int) bool {
iObj := r.objs[i]
jObj := r.objs[j]
parser := jsonpath.New("sorting")
parser := jsonpath.New("sorting").AllowMissingKeys(true)
parser.Parse(r.field)
var iValues [][]reflect.Value
@@ -285,12 +294,18 @@ func (r *RuntimeSort) Less(i, j int) bool {
glog.Fatalf("Failed to get j values for %#v using %s (%v)", jObj, r.field, err)
}
if len(iValues) == 0 || len(iValues[0]) == 0 {
return true
}
if len(jValues) == 0 || len(jValues[0]) == 0 {
return false
}
iField := iValues[0][0]
jField := jValues[0][0]
less, err := isLess(iField, jField)
if err != nil {
glog.Fatalf("Field %s in %v is an unsortable type: %s, err: %v", r.field, iObj, iField.Kind().String(), err)
glog.Fatalf("Field %s in %T is an unsortable type: %s, err: %v", r.field, iObj, iField.Kind().String(), err)
}
return less
}