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) { case *runtime.Unknown: var err error if objs[ix], _, err = decoder.Decode(u.Raw, nil, nil); err != nil { return nil, err } } } values, err := parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface()) if err != nil { return nil, err } if len(values) == 0 { return nil, fmt.Errorf("couldn't find any field with path: %s", field) } sorter := NewRuntimeSort(field, objs) sort.Sort(sorter) return sorter, nil }
func (r *RuntimeSort) Less(i, j int) bool { iObj := r.objs[i] jObj := r.objs[j] parser := jsonpath.New("sorting") parser.Parse(r.field) iValues, err := parser.FindResults(reflect.ValueOf(iObj).Elem().Interface()) if err != nil { glog.Fatalf("Failed to get i values for %#v using %s (%#v)", iObj, r.field, err) } jValues, err := parser.FindResults(reflect.ValueOf(jObj).Elem().Interface()) if err != nil { glog.Fatalf("Failed to get j values for %#v using %s (%v)", jObj, r.field, err) } iField := iValues[0][0] jField := jValues[0][0] switch iField.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return iField.Int() < jField.Int() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return iField.Uint() < jField.Uint() case reflect.Float32, reflect.Float64: return iField.Float() < jField.Float() case reflect.String: return iField.String() < jField.String() default: glog.Fatalf("Field %s in %v is an unsortable type: %s", r.field, iObj, iField.Kind().String()) } // default to preserving order return i < j }
func (r *RuntimeSort) Less(i, j int) bool { iObj := r.objs[i] jObj := r.objs[j] parser := jsonpath.New("sorting") parser.Parse(r.field) iValues, err := parser.FindResults(reflect.ValueOf(iObj).Elem().Interface()) if err != nil { glog.Fatalf("Failed to get i values for %#v using %s (%#v)", iObj, r.field, err) } jValues, err := parser.FindResults(reflect.ValueOf(jObj).Elem().Interface()) if err != nil { glog.Fatalf("Failed to get j values for %#v using %s (%v)", jObj, r.field, err) } 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) } return less }
func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error { w := tabwriter.NewWriter(out, columnwidth, tabwidth, padding, padding_character, flags) headers := make([]string, len(s.Columns)) for ix := range s.Columns { headers[ix] = s.Columns[ix].Header } fmt.Fprintln(w, strings.Join(headers, "\t")) parsers := make([]*jsonpath.JSONPath, len(s.Columns)) for ix := range s.Columns { parsers[ix] = jsonpath.New(fmt.Sprintf("column%d", ix)) if err := parsers[ix].Parse(s.Columns[ix].FieldSpec); err != nil { return err } } if meta.IsListType(obj) { objs, err := meta.ExtractList(obj) if err != nil { return err } for ix := range objs { if err := s.printOneObject(objs[ix], parsers, w); err != nil { return err } } } else { if err := s.printOneObject(obj, parsers, w); err != nil { return err } } return w.Flush() }
func (s *SortingPrinter) sortObj(obj runtime.Object) error { objs, err := runtime.ExtractList(obj) if err != nil { return err } if len(objs) == 0 { return nil } parser := jsonpath.New("sorting") parser.Parse(s.SortField) values, err := parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface()) if err != nil { return err } if len(values) == 0 { return fmt.Errorf("couldn't find any field with path: %s", s.SortField) } sorter := &RuntimeSort{ field: s.SortField, objs: objs, } sort.Sort(sorter) runtime.SetList(obj, sorter.objs) return nil }
func NewJSONPathPrinter(tmpl string) (*JSONPathPrinter, error) { j := jsonpath.New("out") if err := j.Parse(tmpl); err != nil { return nil, err } return &JSONPathPrinter{tmpl, j}, nil }
func parseJSONPath(input interface{}, name, template string) (string, error) { j := jsonpath.New(name) buf := new(bytes.Buffer) if err := j.Parse(template); err != nil { return "", err } if err := j.Execute(buf, input); err != nil { return "", err } return buf.String(), nil }
func NewJSONPathArgumentPrinter(includeNamespace, strict bool, templates ...string) (*JSONPathColumnPrinter, error) { p := &JSONPathColumnPrinter{ includeNamespace: includeNamespace, rawTemplates: templates, buf: &bytes.Buffer{}, } for _, s := range templates { t := jsonpath.New("template").AllowMissingKeys(!strict) if err := t.Parse(s); err != nil { return nil, err } p.templates = append(p.templates, t) } return p, nil }
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) { case *runtime.Unknown: var err error // decode runtime.Unknown to runtime.Unstructured for sorting. // we don't actually want the internal versions of known types. if objs[ix], _, err = decoder.Decode(u.Raw, nil, &unstructured.Unstructured{}); err != nil { return nil, err } } } 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()) } if err != nil { return nil, err } if len(values) == 0 { return nil, fmt.Errorf("couldn't find any field with path: %s", field) } sorter := NewRuntimeSort(field, objs) sort.Sort(sorter) return sorter, nil }
func (r *RuntimeSort) Less(i, j int) bool { iObj := r.objs[i] jObj := r.objs[j] parser := jsonpath.New("sorting") parser.Parse(r.field) var iValues [][]reflect.Value var jValues [][]reflect.Value var err error if unstructured, ok := iObj.(*runtime.Unstructured); ok { iValues, err = parser.FindResults(unstructured.Object) } else { iValues, err = parser.FindResults(reflect.ValueOf(iObj).Elem().Interface()) } if err != nil { glog.Fatalf("Failed to get i values for %#v using %s (%#v)", iObj, r.field, err) } if unstructured, ok := jObj.(*runtime.Unstructured); ok { jValues, err = parser.FindResults(unstructured.Object) } else { jValues, err = parser.FindResults(reflect.ValueOf(jObj).Elem().Interface()) } if err != nil { glog.Fatalf("Failed to get j values for %#v using %s (%v)", jObj, r.field, err) } 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) } return less }
func (s *SortingPrinter) sortObj(obj runtime.Object) error { objs, err := runtime.ExtractList(obj) if err != nil { return err } if len(objs) == 0 { return nil } parser := jsonpath.New("sorting") parser.Parse(s.SortField) for ix := range objs { item := objs[ix] switch u := item.(type) { case *runtime.Unknown: var err error if objs[ix], err = api.Codec.Decode(u.RawJSON); err != nil { return err } } } values, err := parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface()) if err != nil { return err } if len(values) == 0 { return fmt.Errorf("couldn't find any field with path: %s", s.SortField) } sorter := &RuntimeSort{ field: s.SortField, objs: objs, } sort.Sort(sorter) runtime.SetList(obj, sorter.objs) return nil }