diff --git a/change_logs/release_0.4.1.md b/change_logs/release_0.4.1.md
index 67f569cd..00d8dff4 100644
--- a/change_logs/release_0.4.1.md
+++ b/change_logs/release_0.4.1.md
@@ -1,4 +1,5 @@
-
+
+
# Release v0.4.1
@@ -59,4 +60,5 @@ Thank you so much for your support and awesome suggestions to make K9s better!!
---
-
© 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+
© 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
diff --git a/change_logs/release_0.4.2.md b/change_logs/release_0.4.2.md
index 5fd66bc9..7f3c98b1 100644
--- a/change_logs/release_0.4.2.md
+++ b/change_logs/release_0.4.2.md
@@ -1,4 +1,4 @@
-
+
# Release v0.4.2
@@ -38,4 +38,4 @@ Also if you dig this tool, please make some noise on social! [@kitesurfer](https
---
-
© 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
© 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
diff --git a/change_logs/release_0.4.3.md b/change_logs/release_0.4.3.md
new file mode 100644
index 00000000..173b513c
--- /dev/null
+++ b/change_logs/release_0.4.3.md
@@ -0,0 +1,29 @@
+
+
+# Release v0.4.3
+
+## Notes
+
+Thank you to all that contributed with flushing out issues with K9s! I'll try
+to mark some of these issues as fixed. But if you don't mind grab the latest
+rev and see if we're happier with some of the fixes!
+
+If you've filed an issue please help me verify and close.
+
+Thank you so much for your support and awesome suggestions to make K9s better!!
+
+Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
+
+---
+
+## Change Logs
+
+---
+
+## Resolved Bugs
+
++ Sort by age busted (with feeling edition!) [Issue #145](https://github.com/derailed/k9s/issues/145)
+
+---
+
+
© 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
diff --git a/internal/resource/cronjob.go b/internal/resource/cronjob.go
index 14e449cb..c5ab2b0d 100644
--- a/internal/resource/cronjob.go
+++ b/internal/resource/cronjob.go
@@ -107,7 +107,7 @@ func (r *CronJob) Fields(ns string) Row {
lastScheduled := ""
if i.Status.LastScheduleTime != nil {
- lastScheduled = toAge(*i.Status.LastScheduleTime)
+ lastScheduled = toAgeHuman(toAge(*i.Status.LastScheduleTime))
}
return append(ff,
diff --git a/internal/resource/helpers.go b/internal/resource/helpers.go
index d11cf7f3..018700cb 100644
--- a/internal/resource/helpers.go
+++ b/internal/resource/helpers.go
@@ -83,11 +83,16 @@ func boolToStr(b bool) string {
}
func toAge(timestamp metav1.Time) string {
- if timestamp.IsZero() {
+ return time.Since(timestamp.Time).String()
+}
+
+func toAgeHuman(s string) string {
+ d, err := time.ParseDuration(s)
+ if err != nil {
return ""
}
- return duration.HumanDuration(time.Since(timestamp.Time))
+ return duration.HumanDuration(d)
}
// Truncate a string to the given l and suffix ellipsis if needed.
diff --git a/internal/views/helpers.go b/internal/views/helpers.go
index 8e7e94c7..b95b8a4a 100644
--- a/internal/views/helpers.go
+++ b/internal/views/helpers.go
@@ -13,46 +13,46 @@ func toPerc(f float64) string {
func deltas(c, n string) string {
c, n = strings.TrimSpace(c), strings.TrimSpace(n)
if c == "n/a" {
- return n
+ return ""
}
if i, ok := numerical(c); ok {
if j, ok := numerical(n); ok {
switch {
case i < j:
- return plus(n)
+ return plus()
case i > j:
- return minus(n)
+ return minus()
default:
- return n
+ return ""
}
}
- return n
+ return ""
}
if isAlpha(c) {
if strings.Contains(c, "(") {
- return n
+ return ""
}
switch strings.Compare(c, n) {
case -1:
- return plus(n)
+ return plus()
case 1:
- return minus(n)
+ return minus()
default:
- return n
+ return ""
}
}
if len(c) == 0 {
- return n
+ return ""
}
switch strings.Compare(c, n) {
case 1, -1:
- return delta(n)
+ return delta()
default:
- return n
+ return ""
}
}
@@ -75,18 +75,14 @@ func numerical(s string) (int, bool) {
return n, true
}
-func delta(s string) string {
- return suffix(s, "𝜟")
+func delta() string {
+ return "𝜟"
}
-func plus(s string) string {
- return suffix(s, "⬆")
+func plus() string {
+ return "⬆"
}
-func minus(s string) string {
- return suffix(s, "⬇︎")
-}
-
-func suffix(s, su string) string {
- return s + su
+func minus() string {
+ return "⬇︎"
}
diff --git a/internal/views/helpers_test.go b/internal/views/helpers_test.go
index 1c2a716c..24d23df9 100644
--- a/internal/views/helpers_test.go
+++ b/internal/views/helpers_test.go
@@ -11,14 +11,14 @@ func TestDeltas(t *testing.T) {
uu := []struct {
s1, s2, e string
}{
- {"fred", "fred", "fred"},
- {"fred", "blee", delta("blee")},
- {"1", "2", plus("2")},
- {"2", "1", minus("1")},
- {"10Gi", "20Gi", plus("20Gi")},
- {"15%(-)", "15%", "15%"},
- {resource.MissingValue, "fred", delta("fred")},
- {resource.NAValue, "fred", delta("fred")},
+ {"fred", "fred", ""},
+ {"fred", "blee", delta()},
+ {"1", "2", plus()},
+ {"2", "1", minus()},
+ {"10Gi", "20Gi", plus()},
+ {"15%(-)", "15%", ""},
+ {resource.MissingValue, "", delta()},
+ {resource.NAValue, "", delta()},
}
for _, u := range uu {
diff --git a/internal/views/sorter.go b/internal/views/sorter.go
index c917eb65..7d7f5dd6 100644
--- a/internal/views/sorter.go
+++ b/internal/views/sorter.go
@@ -118,6 +118,18 @@ func isMetric(s string) (string, bool) {
}
func isDuration(s string) (time.Duration, bool) {
+ // rx := regexp.MustCompile(`(\d+)([h|d])`)
+ // mm := rx.FindStringSubmatch(s)
+ // if len(mm) == 3 {
+ // n, _ := strconv.Atoi(mm[1])
+ // switch mm[2] {
+ // case "d":
+ // s = fmt.Sprintf("%dh", n*24)
+ // case "y":
+ // s = fmt.Sprintf("%dh", n*365*24)
+ // }
+ // }
+
d, err := time.ParseDuration(s)
if err != nil {
return d, false
diff --git a/internal/views/sorter_test.go b/internal/views/sorter_test.go
index b87a5558..bec39090 100644
--- a/internal/views/sorter_test.go
+++ b/internal/views/sorter_test.go
@@ -24,6 +24,11 @@ func TestGroupSort(t *testing.T) {
{false, []string{"xyz", "abc"}, []string{"xyz", "abc"}},
{true, []string{"2m30s", "1m10s"}, []string{"1m10s", "2m30s"}},
{true, []string{"3d", "1d"}, []string{"1d", "3d"}},
+
+ {true, []string{"95h", "93h"}, []string{"93h", "95h"}},
+ {true, []string{"95d", "93d"}, []string{"93d", "95d"}},
+ {true, []string{"1h10m", "59m"}, []string{"59m", "1h10m"}},
+ {true, []string{"95m", "1h30m"}, []string{"1h30m", "95m"}},
}
for _, u := range uu {
diff --git a/internal/views/table.go b/internal/views/table.go
index c3fdb444..cc6ac27f 100644
--- a/internal/views/table.go
+++ b/internal/views/table.go
@@ -6,11 +6,13 @@ import (
"sort"
"strings"
"sync"
+ "time"
"github.com/derailed/k9s/internal/resource"
"github.com/derailed/tview"
"github.com/gdamore/tcell"
"github.com/rs/zerolog/log"
+ "k8s.io/apimachinery/pkg/util/duration"
)
const (
@@ -338,7 +340,11 @@ func (v *tableView) doUpdate(data resource.TableData) {
fgColor = v.colorerFn(data.Namespace, data.Rows[sk])
}
for col, field := range data.Rows[sk].Fields {
- v.addBodyCell(row, col, field, data.Rows[sk].Deltas[col], fgColor, pads)
+ var age bool
+ if data.Header[col] == "AGE" {
+ age = true
+ }
+ v.addBodyCell(age, row, col, field, data.Rows[sk].Deltas[col], fgColor, pads)
}
row++
}
@@ -375,15 +381,22 @@ func (v *tableView) addHeaderCell(col int, name string, pads maxyPad) {
v.SetCell(0, col, c)
}
-func (v *tableView) addBodyCell(row, col int, field, delta string, color tcell.Color, pads maxyPad) {
- var pField string
- if isASCII(field) {
- pField = pad(deltas(delta, field), pads[col]+5)
- } else {
- pField = deltas(delta, field)
+func (v *tableView) addBodyCell(age bool, row, col int, field, delta string, color tcell.Color, pads maxyPad) {
+ dField := field
+ if age {
+ dur, err := time.ParseDuration(field)
+ if err == nil {
+ log.Debug().Msg("YO!")
+ dField = duration.HumanDuration(dur)
+ }
}
- c := tview.NewTableCell(pField)
+ dField += deltas(delta, field)
+ if isASCII(field) {
+ dField = pad(dField, pads[col]+5)
+ }
+
+ c := tview.NewTableCell(dField)
{
c.SetExpansion(1)
c.SetTextColor(color)