From ca87c339b03ee735490b3f489cb76f210479f424 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Sat, 15 Oct 2022 17:05:15 +0200 Subject: [PATCH] added support to sort by time, duration, numerical --- TODO.md | 4 +++- cmd/root.go | 3 +++ go.mod | 6 ++++-- go.sum | 13 ++++++++++--- lib/common.go | 3 +++ lib/sort.go | 47 +++++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 66 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index fd04222..82a78c4 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,9 @@ ## Features to be implemented -- sorting by: numerical, time, duration, string(default) +- sorting by: numerical, time, duration, string(default) [DONE] + +- add unit tests for the above - add output modes yaml and csv diff --git a/cmd/root.go b/cmd/root.go index f47239e..c60c4d8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -89,6 +89,9 @@ func init() { // sort options rootCmd.PersistentFlags().IntVarP(&lib.SortByColumn, "sort-by", "k", 0, "Sort by column (default: 1)") rootCmd.PersistentFlags().BoolVarP(&lib.SortDescending, "sort-desc", "D", false, "Sort in descending order (default: ascending)") + rootCmd.PersistentFlags().BoolVarP(&lib.SortNumeric, "sort-numeric", "i", false, "sort according to string numerical value") + rootCmd.PersistentFlags().BoolVarP(&lib.SortTime, "sort-time", "t", false, "sort according to time string") + rootCmd.PersistentFlags().BoolVarP(&lib.SortAge, "sort-age", "a", false, "sort according to age (duration) string") // output flags, only 1 allowed, hidden, since just short cuts rootCmd.PersistentFlags().BoolVarP(&lib.OutflagExtended, "extended", "X", false, "Enable extended output") diff --git a/go.mod b/go.mod index 514ddd3..7dc3343 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,17 @@ go 1.18 require ( github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 + github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/gookit/color v1.5.2 github.com/olekukonko/tablewriter v0.0.5 github.com/spf13/cobra v1.5.0 - github.com/xhit/go-str2duration v1.2.0 + github.com/xhit/go-str2duration/v2 v2.0.0 ) require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-runewidth v0.0.10 // indirect + github.com/rivo/uniseg v0.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 // indirect diff --git a/go.sum b/go.sum index f1f1de4..413b9f5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA= +github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -8,24 +10,29 @@ github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc= -github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= +github.com/xhit/go-str2duration/v2 v2.0.0 h1:uFtk6FWB375bP7ewQl+/1wBcn840GPhnySOdcz/okPE= +github.com/xhit/go-str2duration/v2 v2.0.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c= diff --git a/lib/common.go b/lib/common.go index 1f208f6..e765ca2 100644 --- a/lib/common.go +++ b/lib/common.go @@ -78,6 +78,9 @@ var ( // sorting SortByColumn int SortDescending bool + SortNumeric bool + SortTime bool + SortAge bool ) // contains a whole parsed table diff --git a/lib/sort.go b/lib/sort.go index ecdd105..f5a1877 100644 --- a/lib/sort.go +++ b/lib/sort.go @@ -18,7 +18,10 @@ along with this program. If not, see . package lib import ( + "github.com/araddon/dateparse" + str2duration "github.com/xhit/go-str2duration/v2" "sort" + "strconv" ) func sortTable(data *Tabdata, col int) { @@ -41,9 +44,45 @@ func sortTable(data *Tabdata, col int) { // actual sorting sort.SliceStable(data.entries, func(i, j int) bool { - if SortDescending { - return data.entries[i][col] > data.entries[j][col] - } - return data.entries[i][col] < data.entries[j][col] + return compare(data.entries[i][col], data.entries[j][col]) }) } + +func compare(a string, b string) bool { + var comp bool + + switch { + case SortNumeric: + left, err := strconv.Atoi(a) + if err != nil { + left = 0 + } + right, err := strconv.Atoi(b) + if err != nil { + right = 0 + } + comp = left < right + case SortAge: + left, err := str2duration.ParseDuration(a) + if err != nil { + left = 0 + } + right, err := str2duration.ParseDuration(b) + if err != nil { + right = 0 + } + comp = left.Seconds() < right.Seconds() + case SortTime: + left, _ := dateparse.ParseAny(a) + right, _ := dateparse.ParseAny(b) + comp = left.Unix() < right.Unix() + default: + comp = a < b + } + + if SortDescending { + comp = !comp + } + + return comp +}