Compare commits

...

5 Commits

26 changed files with 300 additions and 362 deletions

View File

@@ -11,3 +11,5 @@
https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-stream https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-stream
also exclude data stream backing indices from index ls also exclude data stream backing indices from index ls
- table any2string

View File

@@ -89,7 +89,7 @@ func Main() int {
Name: "output", Name: "output",
Aliases: []string{"o"}, Aliases: []string{"o"},
Value: "", Value: "",
Usage: "output mode (tsv, markdown, json, yaml) default: tsv", Usage: "output mode (tsv, json, yaml) default: tsv",
Destination: &conf.Output, Destination: &conf.Output,
}, },
&cli.StringFlag{ &cli.StringFlag{

15
go.mod
View File

@@ -19,6 +19,8 @@ go 1.25.8
require ( require (
github.com/MichaelMure/go-term-markdown v0.1.4 github.com/MichaelMure/go-term-markdown v0.1.4
github.com/alecthomas/repr v0.5.2 github.com/alecthomas/repr v0.5.2
github.com/charmbracelet/bubbles v1.0.0
github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/lipgloss v1.1.0
github.com/chzyer/readline v1.5.1 github.com/chzyer/readline v1.5.1
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
@@ -29,10 +31,11 @@ require (
github.com/go-openapi/spec v0.22.5 github.com/go-openapi/spec v0.22.5
github.com/go-openapi/swag/loading v0.26.1 github.com/go-openapi/swag/loading v0.26.1
github.com/mattn/go-isatty v0.0.22 github.com/mattn/go-isatty v0.0.22
github.com/olekukonko/tablewriter v1.1.4 github.com/seeruk/go-wordwrap v0.0.0-20191208221741-14ec4aac9550
github.com/tidwall/gjson v1.19.0 github.com/tidwall/gjson v1.19.0
github.com/tlinden/yadu v0.1.3 github.com/tlinden/yadu v0.1.3
github.com/urfave/cli/v3 v3.10.1-0.20260623012112-f980ca84bf65 github.com/urfave/cli/v3 v3.10.1-0.20260623012112-f980ca84bf65
golang.org/x/term v0.44.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
@@ -40,9 +43,6 @@ require (
github.com/MichaelMure/go-term-text v0.3.1 // indirect github.com/MichaelMure/go-term-text v0.3.1 // indirect
github.com/alecthomas/chroma v0.7.1 // indirect github.com/alecthomas/chroma v0.7.1 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charmbracelet/bubbles v1.0.0 // indirect
github.com/charmbracelet/bubbletea v1.3.10 // indirect
github.com/charmbracelet/colorprofile v0.4.1 // indirect github.com/charmbracelet/colorprofile v0.4.1 // indirect
github.com/charmbracelet/x/ansi v0.11.6 // indirect github.com/charmbracelet/x/ansi v0.11.6 // indirect
github.com/charmbracelet/x/cellbuf v0.0.15 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
@@ -69,7 +69,6 @@ require (
github.com/go-openapi/swag/typeutils v0.26.1 // indirect github.com/go-openapi/swag/typeutils v0.26.1 // indirect
github.com/go-openapi/swag/yamlutils v0.26.1 // indirect github.com/go-openapi/swag/yamlutils v0.26.1 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/goccy/go-json v0.10.6 // indirect
github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 // indirect github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/kyokomi/emoji/v2 v2.2.8 // indirect github.com/kyokomi/emoji/v2 v2.2.8 // indirect
@@ -81,11 +80,7 @@ require (
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect github.com/muesli/termenv v0.16.0 // indirect
github.com/oklog/ulid/v2 v2.1.1 // indirect github.com/oklog/ulid/v2 v2.1.1 // indirect
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.2.0 // indirect
github.com/olekukonko/ll v0.1.8 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/seeruk/go-wordwrap v0.0.0-20191208221741-14ec4aac9550 // indirect
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/pretty v1.2.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
@@ -94,10 +89,8 @@ require (
go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/image v0.0.0-20191206065243-da761ea9ff43 // indirect golang.org/x/image v0.0.0-20191206065243-da761ea9ff43 // indirect
golang.org/x/net v0.55.0 // indirect golang.org/x/net v0.55.0 // indirect
golang.org/x/sys v0.46.0 // indirect golang.org/x/sys v0.46.0 // indirect
golang.org/x/term v0.44.0 // indirect
golang.org/x/text v0.37.0 // indirect golang.org/x/text v0.37.0 // indirect
) )

24
go.sum
View File

@@ -14,28 +14,18 @@ github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc=
github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E=
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI=
github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
@@ -114,8 +104,6 @@ github.com/go-openapi/testify/v2 v2.5.1 h1:TMdhCaw8fUNraVSf3Omoob1dO/AzBfhtFAPW0
github.com/go-openapi/testify/v2 v2.5.1/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/go-openapi/testify/v2 v2.5.1/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 h1:Qxs3bNRWe8GTcKMxYOSXm0jx6j0de8XUtb/fsP3GZ0I= github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 h1:Qxs3bNRWe8GTcKMxYOSXm0jx6j0de8XUtb/fsP3GZ0I=
github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU= github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
@@ -154,14 +142,6 @@ github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
github.com/olekukonko/errors v1.2.0 h1:10Zcn4GeV59t/EGqJc8fUjtFT/FuUh5bTMzZ1XwmCRo=
github.com/olekukonko/errors v1.2.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.1.8 h1:ysHCJRGHYKzmBSdz9w5AySztx7lG8SQY+naTGYUbsz8=
github.com/olekukonko/ll v0.1.8/go.mod h1:RPRC6UcscfFZgjo1nulkfMH5IM0QAYim0LfnMvUuozw=
github.com/olekukonko/tablewriter v1.1.4 h1:ORUMI3dXbMnRlRggJX3+q7OzQFDdvgbN9nVWj1drm6I=
github.com/olekukonko/tablewriter v1.1.4/go.mod h1:+kedxuyTtgoZLwif3P1Em4hARJs+mVnzKxmsCL/C5RY=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -189,8 +169,6 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tlinden/yadu v0.1.3 h1:5cRCUmj+l5yvlM2irtpFBIJwVV2DPEgYSaWvF19FtcY= github.com/tlinden/yadu v0.1.3 h1:5cRCUmj+l5yvlM2irtpFBIJwVV2DPEgYSaWvF19FtcY=
github.com/tlinden/yadu v0.1.3/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA= github.com/tlinden/yadu v0.1.3/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA=
github.com/urfave/cli/v3 v3.9.1-0.20260524212652-be8b79d0c8de h1:ESKPiS7inVoBnv4FmgGNZdjWBI/wmvaragoyD3D9nM4=
github.com/urfave/cli/v3 v3.9.1-0.20260524212652-be8b79d0c8de/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/urfave/cli/v3 v3.10.1-0.20260623012112-f980ca84bf65 h1:NXitXXO9DupDLEFj8hIyYtsubRxSFTp5JXqohElT0nU= github.com/urfave/cli/v3 v3.10.1-0.20260623012112-f980ca84bf65 h1:NXitXXO9DupDLEFj8hIyYtsubRxSFTp5JXqohElT0nU=
github.com/urfave/cli/v3 v3.10.1-0.20260623012112-f980ca84bf65/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= github.com/urfave/cli/v3 v3.10.1-0.20260623012112-f980ca84bf65/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
@@ -223,8 +201,6 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=

View File

@@ -113,11 +113,11 @@ func CcrRemoteInfo(conf *cfg.Config, index string) error {
table := printer.NewTable(conf, 2, 5) table := printer.NewTable(conf, 2, 5)
table.Addheaders("ccr remote property", "value") table.Addheaders("ccr remote property", "value")
table.Entries = [][]string{ table.Entries = [][]any{
{"Remote Cluster", remote}, {"Remote Cluster", remote},
{"CCR Mode", mode}, {"CCR Mode", mode},
{"Connected", fmt.Sprintf("%t", info.Connected)}, {"Connected", info.Connected},
{"Num Proxy Sockets Connected", fmt.Sprintf("%d", info.NumProxySocketsConnected)}, {"Num Proxy Sockets Connected", info.NumProxySocketsConnected},
{"Proxy Address", info.ProxyAddress}, {"Proxy Address", info.ProxyAddress},
} }

View File

@@ -164,16 +164,16 @@ func CcrFollowerShow(conf *cfg.Config, index string) error {
table := printer.NewTable(conf, 2, 9) table := printer.NewTable(conf, 2, 9)
table.Addheaders("ccr follower property", "value") table.Addheaders("ccr follower property", "value")
table.Entries = [][]string{ table.Entries = [][]any{
{"name", index}, {"name", index},
{"remote_cluster", follower.RemoteCluster}, {"remote_cluster", follower.RemoteCluster},
{"leader_checkpoint", fmt.Sprintf("%d", follower.LeaderGlobalCheckpoint)}, {"leader_checkpoint", follower.LeaderGlobalCheckpoint},
{"follower_checkpoint", fmt.Sprintf("%d", follower.FollowerGlobalCheckpoint)}, {"follower_checkpoint", follower.FollowerGlobalCheckpoint},
{"bytes_read", fmt.Sprintf("%d", follower.BytesRead)}, {"bytes_read", follower.BytesRead},
{"failed_read_requests", fmt.Sprintf("%d", follower.FailedReadRequests)}, {"failed_read_requests", follower.FailedReadRequests},
{"failed_write_requests", fmt.Sprintf("%d", follower.FailedWriteRequests)}, {"failed_write_requests", follower.FailedWriteRequests},
{"successful_read_requests", fmt.Sprintf("%d", follower.SuccessfulReadRequests)}, {"successful_read_requests", follower.SuccessfulReadRequests},
{"successful_write_requests", fmt.Sprintf("%d", follower.SuccessfulWriteRequests)}, {"successful_write_requests", follower.SuccessfulWriteRequests},
} }
if err := table.Print(); err != nil { if err := table.Print(); err != nil {

View File

@@ -81,7 +81,7 @@ func ClusterList(conf *cfg.Config) error {
} }
} }
table.Entries[idx] = []string{name, cluster.Uri, reachableStr, current, errmsg} table.Entries[idx] = []any{name, cluster.Uri, reachableStr, current, errmsg}
idx++ idx++
} }
@@ -190,25 +190,25 @@ func ClusterStatus(conf *cfg.Config) error {
table := printer.NewTable(conf, 2, 7) table := printer.NewTable(conf, 2, 7)
table.Addheaders(conf.DefaultCluster.Name, "status") table.Addheaders(conf.DefaultCluster.Name, "status")
table.Entries = [][]string{ table.Entries = [][]any{
{"Cluster Name", res.health.ClusterName}, {"Cluster Name", res.health.ClusterName},
{"ES Status", printer.Colorize(conf, res.health.Status.Name, res.health.Status.Name)}, {"ES Status", printer.Colorize(conf, res.health.Status.Name, res.health.Status.Name)},
{"ES Version", res.info.Version.Int}, {"ES Version", res.info.Version.Int},
{"Is Leader", fmt.Sprintf("%t", isleader)}, {"Is Leader", isleader},
{"Active Shards", fmt.Sprintf("%d", res.health.ActiveShards)}, {"Active Shards", res.health.ActiveShards},
{"Active Primary Shards", fmt.Sprintf("%d", res.health.ActivePrimaryShards)}, {"Active Primary Shards", res.health.ActivePrimaryShards},
{"Unassigned Shards", fmt.Sprintf("%d", res.health.UnassignedShards)}, {"Unassigned Shards", res.health.UnassignedShards},
{"Unassigned Primary Shards", fmt.Sprintf("%d", res.health.UnassignedPrimaryShards)}, {"Unassigned Primary Shards", res.health.UnassignedPrimaryShards},
{"Pending Tasks", fmt.Sprintf("%d", res.health.NumberOfPendingTasks)}, {"Pending Tasks", res.health.NumberOfPendingTasks},
{"Nodes", fmt.Sprintf("%d", res.health.NumberOfNodes)}, {"Nodes", res.health.NumberOfNodes},
{"Red Indices", fmt.Sprintf("%d", redindices)}, {"Red Indices", redindices},
{"Long Running Tasks", fmt.Sprintf("%d", longtasks)}, {"Long Running Tasks", longtasks},
} }
if !isleader && res.ccr != nil { if !isleader && res.ccr != nil {
table.Entries = append(table.Entries, [][]string{ table.Entries = append(table.Entries, [][]any{
{"AutoFollow (success/failed indices)", ccrfollowing}, {"AutoFollow (success/failed indices)", ccrfollowing},
{"Followed Indices", fmt.Sprintf("%d", len(res.ccr.FollowStats.Indices))}, {"Followed Indices", len(res.ccr.FollowStats.Indices)},
}...) }...)
} }
@@ -219,15 +219,15 @@ func ClusterStatus(conf *cfg.Config) error {
if res.health.Status.Name != "green" { if res.health.Status.Name != "green" {
for name, indicator := range res.healthreport.Indicators { for name, indicator := range res.healthreport.Indicators {
if indicator.Status != "green" { if indicator.Status != "green" {
table.Entries = append(table.Entries, []string{ table.Entries = append(table.Entries, []any{
printer.Colorize(conf, indicator.Status, "Bad health "+name), indicator.Symptom, printer.Colorize(conf, indicator.Status, "Bad health "+name), indicator.Symptom,
}) })
for _, diag := range indicator.Diagnosis { for _, diag := range indicator.Diagnosis {
table.Entries = append(table.Entries, []string{" -> cause", diag.Cause}) table.Entries = append(table.Entries, []any{" -> cause", diag.Cause})
for resource, items := range diag.AffectedResources { for resource, items := range diag.AffectedResources {
table.Entries = append(table.Entries, []string{" -> affected " + resource, strings.Join(items, ",")}) table.Entries = append(table.Entries, []any{" -> affected " + resource, strings.Join(items, ",")})
} }
} }
} }
@@ -255,13 +255,13 @@ func gatherClusterStats(conf *cfg.Config, clusterstats *clusterstats.Response, t
clusterstats.Nodes.Jvm.Versions[0].VmVersion}, " ") clusterstats.Nodes.Jvm.Versions[0].VmVersion}, " ")
} }
table.Entries = append(table.Entries, [][]string{ table.Entries = append(table.Entries, [][]any{
{"Indicies", fmt.Sprintf("%d", clusterstats.Indices.Count)}, {"Indicies", clusterstats.Indices.Count},
{"Docs", fmt.Sprintf("%d", clusterstats.Indices.Docs.Count)}, {"Docs", clusterstats.Indices.Docs.Count},
{"Total Size", humanize.Bytes(uint64(clusterstats.Indices.Docs.TotalSizeInBytes))}, {"Total Size", printer.Bytes(clusterstats.Indices.Docs.TotalSizeInBytes)},
{"Total Queries", fmt.Sprintf("%d", querycount)}, {"Total Queries", "%d", querycount},
{"Shards Primaries", fmt.Sprintf("%d", clusterstats.Indices.Shards.Primaries)}, {"Shards Primaries", clusterstats.Indices.Shards.Primaries},
{"Shards Total", fmt.Sprintf("%d", clusterstats.Indices.Shards.Total)}, {"Shards Total", clusterstats.Indices.Shards.Total},
{"Storage", fmt.Sprintf( {"Storage", fmt.Sprintf(
"%s/%s", "%s/%s",
humanize.Bytes(uint64(clusterstats.Indices.Store.SizeInBytes)), humanize.Bytes(uint64(clusterstats.Indices.Store.SizeInBytes)),
@@ -272,11 +272,11 @@ func gatherClusterStats(conf *cfg.Config, clusterstats *clusterstats.Response, t
humanize.Bytes(uint64(clusterstats.Nodes.Jvm.Mem.HeapUsedInBytes)), humanize.Bytes(uint64(clusterstats.Nodes.Jvm.Mem.HeapUsedInBytes)),
humanize.Bytes(uint64(clusterstats.Nodes.Jvm.Mem.HeapMaxInBytes)), humanize.Bytes(uint64(clusterstats.Nodes.Jvm.Mem.HeapMaxInBytes)),
)}, )},
{"JVM Threads", fmt.Sprintf("%d", clusterstats.Nodes.Jvm.Threads)}, {"JVM Threads", clusterstats.Nodes.Jvm.Threads},
{"JVM Version", vmversion}, {"JVM Version", vmversion},
{"CPUs", fmt.Sprintf("%d", clusterstats.Nodes.Os.AllocatedProcessors)}, {"CPUs", clusterstats.Nodes.Os.AllocatedProcessors},
{"CPU Usage", fmt.Sprintf("%d%%", clusterstats.Nodes.Process.Cpu.Percent)}, {"CPU Usage", fmt.Sprintf("%d%%", clusterstats.Nodes.Process.Cpu.Percent)},
{"Open FDs", fmt.Sprintf("%d", clusterstats.Nodes.Process.OpenFileDescriptors.Avg)}, {"Open FDs", clusterstats.Nodes.Process.OpenFileDescriptors.Avg},
}...) }...)
return table return table

View File

@@ -40,7 +40,7 @@ func ClusterSettingsList(conf *cfg.Config) error {
table := printer.NewTable(conf, 2, 0) table := printer.NewTable(conf, 2, 0)
table.Addheaders("setting", "value") table.Addheaders("setting", "value")
entries := [][]string{} entries := [][]any{}
settingshash := res.Persistent // == map[string]json.RawMessage settingshash := res.Persistent // == map[string]json.RawMessage
@@ -52,7 +52,7 @@ func ClusterSettingsList(conf *cfg.Config) error {
} }
for topic, val := range settingshash { for topic, val := range settingshash {
entries = append(entries, []string{topic, string(val)}) entries = append(entries, []any{topic, string(val)})
} }
table.Entries = entries table.Entries = entries

View File

@@ -72,27 +72,27 @@ func checkClusterStatus(conf *cfg.Config, leader, follower string) bool {
table.Addheaders("setting", "leader:"+leader, "follower:"+follower) table.Addheaders("setting", "leader:"+leader, "follower:"+follower)
table.Entries = [][]string{ table.Entries = [][]any{
{"Cluster Name", status[leader].ClusterName, status[follower].ClusterName}, {"Cluster Name", status[leader].ClusterName, status[follower].ClusterName},
{"Cluster Status", {"Cluster Status",
printer.Colorize(conf, status[leader].Status.Name, status[leader].Status.Name), printer.Colorize(conf, status[leader].Status.Name, status[leader].Status.Name),
printer.Colorize(conf, status[follower].Status.Name, status[follower].Status.Name), printer.Colorize(conf, status[follower].Status.Name, status[follower].Status.Name),
}, },
{"Active Shards", {"Active Shards",
fmt.Sprintf("%d", status[leader].ActiveShards), status[leader].ActiveShards,
fmt.Sprintf("%d", status[follower].ActiveShards), status[follower].ActiveShards,
}, },
{"Active Primary Shards", {"Active Primary Shards",
fmt.Sprintf("%d", status[leader].ActivePrimaryShards), status[leader].ActivePrimaryShards,
fmt.Sprintf("%d", status[follower].ActivePrimaryShards), status[follower].ActivePrimaryShards,
}, },
{"Indicies", {"Indicies",
fmt.Sprintf("%d", len(status[leader].Indices)), len(status[leader].Indices),
fmt.Sprintf("%d", len(status[follower].Indices)), len(status[follower].Indices),
}, },
{"Nodes", {"Nodes",
fmt.Sprintf("%d", status[leader].NumberOfNodes), status[leader].NumberOfNodes,
fmt.Sprintf("%d", status[follower].NumberOfNodes), status[follower].NumberOfNodes,
}, },
} }
@@ -112,7 +112,7 @@ func checkClusterStatus(conf *cfg.Config, leader, follower string) bool {
// finds indices on both clusters which have ilm errors // finds indices on both clusters which have ilm errors
func findIlmErrors(conf *cfg.Config, leader, follower string) bool { func findIlmErrors(conf *cfg.Config, leader, follower string) bool {
failed := map[string]map[string]string{} failed := map[string]map[string]any{}
for _, cluster := range []string{leader, follower} { for _, cluster := range []string{leader, follower} {
ilm, err := conf.Clusters[cluster].ES().Ilm.ExplainLifecycle("_all"). ilm, err := conf.Clusters[cluster].ES().Ilm.ExplainLifecycle("_all").
@@ -123,13 +123,13 @@ func findIlmErrors(conf *cfg.Config, leader, follower string) bool {
return false return false
} }
failed[cluster] = map[string]string{} failed[cluster] = map[string]any{}
for name, ilmstate := range ilm.Indices { for name, ilmstate := range ilm.Indices {
count := ilmstate.(*types.LifecycleExplainManaged).FailedStepRetryCount count := ilmstate.(*types.LifecycleExplainManaged).FailedStepRetryCount
if count != nil && *count > 0 { if count != nil && *count > 0 {
failed[cluster][name] = fmt.Sprintf("%d", *count) failed[cluster][name] = *count
} }
} }
} }
@@ -150,7 +150,7 @@ func findIlmErrors(conf *cfg.Config, leader, follower string) bool {
table.Addheaders("ilm errors on "+which, "errors") table.Addheaders("ilm errors on "+which, "errors")
for name, count := range failed[cluster] { for name, count := range failed[cluster] {
table.Entries[idx] = []string{name, count} table.Entries[idx] = []any{name, count}
idx++ idx++
} }
@@ -222,7 +222,7 @@ func findIndicesOnlyOnLeader(conf *cfg.Config, indices ClusterIndices, leader, f
for name, index := range indexOnlyOnLeader { for name, index := range indexOnlyOnLeader {
name := printer.Colorize(conf, "red", name) name := printer.Colorize(conf, "red", name)
table.Entries[idx] = []string{name, *index.DatasetSize, *index.DocsCount} table.Entries[idx] = []any{name, *index.DatasetSize, *index.DocsCount}
idx++ idx++
} }
@@ -270,7 +270,7 @@ func findOrphanedIndices(conf *cfg.Config, indices ClusterIndices, leader, follo
for name, index := range orphaned { for name, index := range orphaned {
name := printer.Colorize(conf, "red", name) name := printer.Colorize(conf, "red", name)
table.Entries[idx] = []string{name, *index.DatasetSize, *index.DocsCount} table.Entries[idx] = []any{name, *index.DatasetSize, *index.DocsCount}
idx++ idx++
} }
@@ -304,7 +304,7 @@ func findFailedFollowerIndices(conf *cfg.Config, indices ClusterIndices, followe
for name, index := range red { for name, index := range red {
name := printer.Colorize(conf, "red", name) name := printer.Colorize(conf, "red", name)
table.Entries[idx] = []string{name, *index.DatasetSize, *index.DocsCount} table.Entries[idx] = []any{name, *index.DatasetSize, *index.DocsCount}
idx++ idx++
} }

View File

@@ -25,7 +25,6 @@ import (
"codeberg.org/scip/esctl/pkg/cfg" "codeberg.org/scip/esctl/pkg/cfg"
"codeberg.org/scip/esctl/pkg/printer" "codeberg.org/scip/esctl/pkg/printer"
"github.com/dustin/go-humanize"
"github.com/elastic/go-elasticsearch/v9/typedapi/types" "github.com/elastic/go-elasticsearch/v9/typedapi/types"
) )
@@ -73,13 +72,13 @@ func DatastreamList(conf *cfg.Config) error {
policy = *ds.IlmPolicy policy = *ds.IlmPolicy
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{
name, name,
policy, policy,
fmt.Sprintf("%t", ds.Hidden), ds.Hidden,
fmt.Sprintf("%t", *ds.System), *ds.System,
fmt.Sprintf("%t", *ds.Replicated), *ds.Replicated,
fmt.Sprintf("%d", ds.Generation), ds.Generation,
ds.TimestampField.Name, ds.TimestampField.Name,
} }
@@ -156,18 +155,18 @@ func DatastreamShow(conf *cfg.Config, dsname string) error {
policy = *ds.IlmPolicy policy = *ds.IlmPolicy
} }
table.Entries = [][]string{ table.Entries = [][]any{
{"name", name}, {"name", name},
{"ilm policy", policy}, {"ilm policy", policy},
{"hidden", fmt.Sprintf("%t", ds.Hidden)}, {"hidden", ds.Hidden},
{"system", fmt.Sprintf("%t", *ds.System)}, {"system", *ds.System},
{"replicated", fmt.Sprintf("%t", *ds.Replicated)}, {"replicated", *ds.Replicated},
{"generation", fmt.Sprintf("%d", ds.Generation)}, {"generation", ds.Generation},
{"timestamp field", ds.TimestampField.Name}, {"timestamp field", ds.TimestampField.Name},
{"backing indices", fmt.Sprintf("%d", stats.BackingIndices)}, {"backing indices", stats.BackingIndices},
{"size", humanize.Bytes(uint64(stats.TotalStoreSizeBytes))}, {"size", printer.Bytes(stats.TotalStoreSizeBytes)},
{"shards-failed", fmt.Sprintf("%d", stats.Shards_.Failed)}, {"shards-failed", stats.Shards_.Failed},
{"shards-successful", fmt.Sprintf("%d", stats.Shards_.Successful)}, {"shards-successful", stats.Shards_.Successful},
} }
if err := table.Print(); err != nil { if err := table.Print(); err != nil {
@@ -183,10 +182,10 @@ func DatastreamShow(conf *cfg.Config, dsname string) error {
policy = *ds.IlmPolicy policy = *ds.IlmPolicy
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{
index.IndexName, index.IndexName,
index.IndexUuid, index.IndexUuid,
fmt.Sprintf("%t", *index.PreferIlm), *index.PreferIlm,
policy, policy,
index.ManagedBy.Name, index.ManagedBy.Name,
} }
@@ -235,10 +234,10 @@ func DatastreamRollover(conf *cfg.Config, ds string) error {
table := printer.NewTable(conf, 2, 5) table := printer.NewTable(conf, 2, 5)
table.Addheaders("rollover response", "value") table.Addheaders("rollover response", "value")
table.Entries = [][]string{ table.Entries = [][]any{
{"acknowledged", fmt.Sprintf("%t", res.Acknowledged)}, {"acknowledged", res.Acknowledged},
{"rolled over", fmt.Sprintf("%t", res.RolledOver)}, {"rolled over", res.RolledOver},
{"shards acknowledged", fmt.Sprintf("%t", res.ShardsAcknowledged)}, {"shards acknowledged", res.ShardsAcknowledged},
{"old index", res.OldIndex}, {"old index", res.OldIndex},
{"new index", res.NewIndex}, {"new index", res.NewIndex},
} }

View File

@@ -129,7 +129,7 @@ func IlmShow(conf *cfg.Config, policy string) error {
table := printer.NewTable(conf, 2, 5) table := printer.NewTable(conf, 2, 5)
table.Addheaders("ilm policy setting", "value") table.Addheaders("ilm policy setting", "value")
table.Entries = [][]string{ table.Entries = [][]any{
{"policy", policy}, {"policy", policy},
{"hot phase", ilmPhaseString(ilm.Policy.Phases.Hot, false)}, {"hot phase", ilmPhaseString(ilm.Policy.Phases.Hot, false)},
{"warm phase", ilmPhaseString(ilm.Policy.Phases.Warm, false)}, {"warm phase", ilmPhaseString(ilm.Policy.Phases.Warm, false)},
@@ -291,17 +291,17 @@ func IlmExplain(conf *cfg.Config, index string) error {
return fmt.Errorf("failed to unmarshal step info: %w", err) return fmt.Errorf("failed to unmarshal step info: %w", err)
} }
table.Entries = [][]string{ table.Entries = [][]any{
{"index", ilm.Index}, {"index", ilm.Index},
{"ilm policy", *ilm.Policy}, {"ilm policy", *ilm.Policy},
{"action", *ilm.Action}, {"action", *ilm.Action},
{"age", fmt.Sprintf("%s", ilm.Age)}, {"age", ilm.Age},
{"managed", fmt.Sprintf("%t", ilm.Managed)}, {"managed", ilm.Managed},
{"phase", *ilm.Phase}, {"phase", *ilm.Phase},
{"phase execution", ilmPhaseString(ilm.PhaseExecution.PhaseDefinition, false)}, {"phase execution", ilmPhaseString(ilm.PhaseExecution.PhaseDefinition, false)},
{"step", *ilm.Step}, {"step", *ilm.Step},
{"failed step", *ilm.FailedStep}, {"failed step", *ilm.FailedStep},
{"failed step retry count", fmt.Sprintf("%d", ilm.FailedStepRetryCount)}, {"failed step retry count", ilm.FailedStepRetryCount},
} }
if err := table.Print(); err != nil { if err := table.Print(); err != nil {

View File

@@ -119,13 +119,13 @@ func IlmForecastList(conf *cfg.Config, filter string) error {
virtualAge := virtualAge(&phase) virtualAge := virtualAge(&phase)
row := []string{ row := []any{
phase.index, phase.index,
humanize.Bytes(uint64(phase.size)), printer.Bytes(phase.size),
formatDuration(phase.age), formatDuration(phase.age),
formatDuration(virtualAge), formatDuration(virtualAge),
formatDuration(phase.minage), formatDuration(phase.minage),
humanize.Bytes(uint64(phase.minsize)), printer.Bytes(phase.minsize),
phase.currentPhase, phase.currentPhase,
phase.nextPhase, phase.nextPhase,
} }

View File

@@ -118,7 +118,7 @@ func IndexList(conf *cfg.Config) error {
for idx, index := range list { for idx, index := range list {
name := printer.Colorize(conf, *index.Health, *index.Index) name := printer.Colorize(conf, *index.Health, *index.Index)
table.Entries[idx] = []string{name, *index.DatasetSize, *index.DocsCount} table.Entries[idx] = []any{name, *index.DatasetSize, *index.DocsCount}
if idx == size-1 { if idx == size-1 {
break break
@@ -156,18 +156,18 @@ func IndexShow(conf *cfg.Config, indexpattern string) error {
created := time.Unix(ts/1000, 0) created := time.Unix(ts/1000, 0)
table.Entries = [][]string{ table.Entries = [][]any{
{"name", name}, {"name", name},
{"replicas", *index.Settings.Index.NumberOfReplicas}, {"replicas", *index.Settings.Index.NumberOfReplicas},
{"shards", *index.Settings.Index.NumberOfShards}, {"shards", *index.Settings.Index.NumberOfShards},
{"created", created.Format("2006-01-02 15:04:05")}, {"created", created},
{"uuid", *index.Settings.Index.Uuid}, {"uuid", *index.Settings.Index.Uuid},
{"version", *index.Settings.Index.Version.Created}, {"version", *index.Settings.Index.Version.Created},
{"fields", strings.Join(fields, ",")}, {"fields", fields},
} }
if index.Settings.Index.Lifecycle != nil { if index.Settings.Index.Lifecycle != nil {
table.Entries = append(table.Entries, [][]string{ table.Entries = append(table.Entries, [][]any{
{"ilm policy", *index.Settings.Index.Lifecycle.Name}, {"ilm policy", *index.Settings.Index.Lifecycle.Name},
{"ilm rollover alias", *index.Settings.Index.Lifecycle.RolloverAlias}, {"ilm rollover alias", *index.Settings.Index.Lifecycle.RolloverAlias},
}...) }...)
@@ -283,14 +283,14 @@ func IndexAllocation(conf *cfg.Config, index string) error {
roles[idx] = role.Name roles[idx] = role.Name
} }
table.Entries = [][]string{ table.Entries = [][]any{
{"Index", index}, {"Index", index},
{"Current node", currentNode.Name}, {"Current node", currentNode.Name},
{"Current k8s node", currentNode.Attributes["k8s_node_name"]}, {"Current k8s node", currentNode.Attributes["k8s_node_name"]},
{"Current node address", currentNode.TransportAddress}, {"Current node address", currentNode.TransportAddress},
{"Current node id", currentNode.Id}, {"Current node id", currentNode.Id},
{"Current node weight", fmt.Sprintf("%d", currentNode.WeightRanking)}, {"Current node weight", currentNode.WeightRanking},
{"Current node roles", strings.Join(roles, ",")}, {"Current node roles", roles},
{"Can rebalance cluster", res.CanRebalanceCluster.Name}, {"Can rebalance cluster", res.CanRebalanceCluster.Name},
{"Can rebalance to another node", res.CanRebalanceToOtherNode.Name}, {"Can rebalance to another node", res.CanRebalanceToOtherNode.Name},
{"Can remain on current node", res.CanRemainOnCurrentNode.Name}, {"Can remain on current node", res.CanRemainOnCurrentNode.Name},
@@ -344,10 +344,11 @@ func IndexFields(conf *cfg.Config, index string) error {
continue continue
} }
table.Entries = append(table.Entries, []string{name, fieldtype, table.AddRow(name, fieldtype,
fmt.Sprintf("%t", caps.Searchable), caps.Searchable,
fmt.Sprintf("%t", caps.Aggregatable), caps.Aggregatable,
fmt.Sprintf("%t", *caps.MetadataField)}) *caps.MetadataField)
break break
} }

View File

@@ -78,7 +78,7 @@ func IndexAliasList(conf *cfg.Config) error {
idx := 0 idx := 0
for index, aliases := range aliaslist { for index, aliases := range aliaslist {
table.Entries[idx] = []string{ table.Entries[idx] = []any{
index, index,
strings.Join(aliases, ","), strings.Join(aliases, ","),
} }
@@ -117,10 +117,10 @@ func IndexAliasRollover(conf *cfg.Config, alias string) error {
table := printer.NewTable(conf, 2, 5) table := printer.NewTable(conf, 2, 5)
table.Addheaders("rollover response", "value") table.Addheaders("rollover response", "value")
table.Entries = [][]string{ table.Entries = [][]any{
{"acknowledged", fmt.Sprintf("%t", res.Acknowledged)}, {"acknowledged", res.Acknowledged},
{"rolled over", fmt.Sprintf("%t", res.RolledOver)}, {"rolled over", res.RolledOver},
{"shards acknowledged", fmt.Sprintf("%t", res.ShardsAcknowledged)}, {"shards acknowledged", res.ShardsAcknowledged},
{"old index", res.OldIndex}, {"old index", res.OldIndex},
{"new index", res.NewIndex}, {"new index", res.NewIndex},
} }

View File

@@ -51,11 +51,7 @@ func IndexTemplateList(conf *cfg.Config) error {
return fmt.Errorf("failed to unmarshal meta json data: %w", err) return fmt.Errorf("failed to unmarshal meta json data: %w", err)
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{tpl.Name, desc, tpl.IndexTemplate.Priority}
tpl.Name,
string(desc),
fmt.Sprintf("%d", tpl.IndexTemplate.Priority),
}
} }
table.Sort() table.Sort()
@@ -94,13 +90,13 @@ func IndexTemplateShow(conf *cfg.Config, tplname string) error {
aliases = append(aliases, alias) aliases = append(aliases, alias)
} }
table.Entries = [][]string{ table.Entries = [][]any{
{"name", tpl.Name}, {"name", tpl.Name},
{"description", string(desc)}, {"description", desc},
{"index patterns", strings.Join(tpl.IndexTemplate.IndexPatterns, ",")}, {"index patterns", tpl.IndexTemplate.IndexPatterns},
{"composed of", strings.Join(tpl.IndexTemplate.ComposedOf, ",")}, {"composed of", tpl.IndexTemplate.ComposedOf},
{"data stream enabled", fmt.Sprintf("%t", hasds)}, {"data stream enabled", hasds},
{"aliases", strings.Join(aliases, ",")}, {"aliases", aliases},
} }
if err := table.Print(); err != nil { if err := table.Print(); err != nil {
@@ -136,9 +132,7 @@ func IndexTemplateShow(conf *cfg.Config, tplname string) error {
typeval = val.Type typeval = val.Type
} }
table.Entries = append(table.Entries, []string{ table.AddRow(name, typeval)
name, typeval,
})
} }
fmt.Println() fmt.Println()
@@ -414,12 +408,7 @@ func rolloverAliasIndexTemplate(conf *cfg.Config, name string) error {
return err return err
} }
table.Entries = append(table.Entries, []string{ table.AddRow(alias, res.RolledOver, res.Acknowledged, res.NewIndex)
alias,
fmt.Sprintf("%t", res.RolledOver),
fmt.Sprintf("%t", res.Acknowledged),
res.NewIndex,
})
if err := table.Print(); err != nil { if err := table.Print(); err != nil {
return err return err

View File

@@ -52,7 +52,7 @@ func getIndexTemplateSettings(conf *cfg.Config, tplname string, table *printer.T
tpl := data.IndexTemplates[0].IndexTemplate.Template.Settings tpl := data.IndexTemplates[0].IndexTemplate.Template.Settings
for topic, val := range tpl { for topic, val := range tpl {
table.Entries = append(table.Entries, []string{topic, fmt.Sprintf("%v", val)}) table.AddRow(topic, val)
} }
return nil return nil

View File

@@ -54,11 +54,11 @@ func LicenseShow(conf *cfg.Config) error {
maxunits = fmt.Sprintf("%d", *lic.MaxResourceUnits) maxunits = fmt.Sprintf("%d", *lic.MaxResourceUnits)
} }
table.Entries = [][]string{ table.Entries = [][]any{
{"UID", lic.Uid}, {"UID", lic.Uid},
{"Issued to", lic.IssuedTo}, {"Issued to", lic.IssuedTo},
{"Expires", expire}, {"Expires", expire},
{"Issued", lic.IssueDate.(string)}, {"Issued", lic.IssueDate},
{"Max nodes", maxnodes}, {"Max nodes", maxnodes},
{"Max resource units", maxunits}, {"Max resource units", maxunits},
{"Type", lic.Type.Name}, {"Type", lic.Type.Name},

View File

@@ -41,14 +41,14 @@ func NodeList(conf *cfg.Config) error {
table.Addheaders("name", "ip", "load1m", "load5m", "load15m", "ram %", "heap %") table.Addheaders("name", "ip", "load1m", "load5m", "load15m", "ram %", "heap %")
for idx, node := range nodes { for idx, node := range nodes {
table.Entries[idx] = []string{ table.Entries[idx] = []any{
*node.Name, *node.Name,
*node.Ip, *node.Ip,
*node.Load1M, *node.Load1M,
*node.Load5M, *node.Load5M,
*node.Load15M, *node.Load15M,
node.RamPercent.(string), node.RamPercent,
node.HeapPercent.(string), node.HeapPercent,
} }
} }
@@ -113,25 +113,25 @@ func NodeShow(conf *cfg.Config, nodename string) error {
k8snode := info.Attributes["k8s_node_name"] k8snode := info.Attributes["k8s_node_name"]
table.Entries = [][]string{ table.Entries = [][]any{
{"Id", id}, {"Id", id},
{"Name", nodename}, {"Name", nodename},
{"Kubernetes node", k8snode}, {"Kubernetes node", k8snode},
{"Ip address", info.Ip}, {"Ip address", info.Ip},
{"Node rank", *stat.AdaptiveSelection[id].Rank}, {"Node rank", *stat.AdaptiveSelection[id].Rank},
{"JVM", info.Jvm.VmName + " " + info.Jvm.Version}, {"JVM", info.Jvm.VmName + " " + info.Jvm.Version},
{"JVM Started", time.UnixMilli(info.Jvm.StartTimeInMillis).String()}, {"JVM Started", time.UnixMilli(info.Jvm.StartTimeInMillis)},
{"OS", info.Os.PrettyName + " " + info.Os.Version}, {"OS", info.Os.PrettyName + " " + info.Os.Version},
{"Node roles", strings.Join(roles, ",")}, {"Node roles", roles},
{"Node version", info.Version}, {"Node version", info.Version},
{"HTTP clients", fmt.Sprintf("%d", *stat.Http.CurrentOpen)}, {"HTTP clients", *stat.Http.CurrentOpen},
{"CPUs", fmt.Sprintf("%d", *info.Os.AllocatedProcessors)}, {"CPUs", *info.Os.AllocatedProcessors},
{"Load 15m/5m/1m", fmt.Sprintf("%.2f/%.2f/%.2f", {"Load 15m/5m/1m", fmt.Sprintf("%.2f/%.2f/%.2f",
stat.Os.Cpu.LoadAverage["15m"], stat.Os.Cpu.LoadAverage["15m"],
stat.Os.Cpu.LoadAverage["5m"], stat.Os.Cpu.LoadAverage["5m"],
stat.Os.Cpu.LoadAverage["1m"], stat.Os.Cpu.LoadAverage["1m"],
)}, )},
{"Open FD's", fmt.Sprintf("%d", *stat.Process.OpenFileDescriptors)}, {"Open FD's", *stat.Process.OpenFileDescriptors},
{"Response time avg", fmt.Sprintf("%dns", *stat.AdaptiveSelection[id].AvgResponseTimeNs)}, {"Response time avg", fmt.Sprintf("%dns", *stat.AdaptiveSelection[id].AvgResponseTimeNs)},
{"Memory usage (used/avail)", {"Memory usage (used/avail)",
humanize.Bytes(uint64(*stat.Os.Mem.UsedInBytes)) + " / " + humanize.Bytes(uint64(*stat.Os.Mem.TotalInBytes))}, humanize.Bytes(uint64(*stat.Os.Mem.UsedInBytes)) + " / " + humanize.Bytes(uint64(*stat.Os.Mem.TotalInBytes))},
@@ -139,7 +139,7 @@ func NodeShow(conf *cfg.Config, nodename string) error {
if len(stat.Fs.Data) > 0 { if len(stat.Fs.Data) > 0 {
fs := stat.Fs.Data[0] fs := stat.Fs.Data[0]
table.Entries = append(table.Entries, [][]string{ table.Entries = append(table.Entries, [][]any{
{"Storage usage (used/avail)", {"Storage usage (used/avail)",
humanize.Bytes(uint64(*fs.AvailableInBytes)) + " / " + humanize.Bytes(uint64(*fs.TotalInBytes))}, humanize.Bytes(uint64(*fs.AvailableInBytes)) + " / " + humanize.Bytes(uint64(*fs.TotalInBytes))},
{"Storage mount", *fs.Mount}, {"Storage mount", *fs.Mount},

View File

@@ -20,7 +20,6 @@ import (
"context" "context"
"fmt" "fmt"
"log/slog" "log/slog"
"strings"
"codeberg.org/scip/esctl/pkg/cfg" "codeberg.org/scip/esctl/pkg/cfg"
"codeberg.org/scip/esctl/pkg/printer" "codeberg.org/scip/esctl/pkg/printer"
@@ -58,10 +57,10 @@ func RoleList(conf *cfg.Config) error {
idx := 0 idx := 0
for name, role := range res { for name, role := range res {
table.Entries[idx] = []string{ table.Entries[idx] = []any{
name, name,
fmt.Sprintf("%d", len(role.Cluster)), role.Cluster,
fmt.Sprintf("%d", len(role.Indices)), role.Indices,
} }
idx++ idx++
} }
@@ -140,10 +139,8 @@ func roleRemoteClusters(conf *cfg.Config, role types.Role) error {
perms = append(perms, perm.Name) perms = append(perms, perm.Name)
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{priv.Clusters, perms}
strings.Join(priv.Clusters, ","),
strings.Join(perms, ","),
}
idx++ idx++
} }
@@ -160,7 +157,7 @@ func roleClusters(conf *cfg.Config, role types.Role) error {
table.Addheaders("cluster rights") table.Addheaders("cluster rights")
idx := 0 idx := 0
for _, cluster := range role.Cluster { for _, cluster := range role.Cluster {
table.Entries[idx] = []string{cluster.Name} table.Entries[idx] = []any{cluster.Name}
idx++ idx++
} }
@@ -182,11 +179,7 @@ func roleRemoteIndices(conf *cfg.Config, role types.Role) error {
perms = append(perms, perm.Name) perms = append(perms, perm.Name)
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{priv.Names, perms, *priv.AllowRestrictedIndices}
strings.Join(priv.Names, ", "),
strings.Join(perms, ", "),
fmt.Sprintf("%t", *priv.AllowRestrictedIndices),
}
idx++ idx++
} }
@@ -209,11 +202,7 @@ func roleIndices(conf *cfg.Config, role types.Role) error {
perms = append(perms, perm.Name) perms = append(perms, perm.Name)
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{priv.Names, perms, *priv.AllowRestrictedIndices}
strings.Join(priv.Names, ", "),
strings.Join(perms, ", "),
fmt.Sprintf("%t", *priv.AllowRestrictedIndices),
}
idx++ idx++
} }
@@ -231,10 +220,10 @@ func roleApplications(conf *cfg.Config, role types.Role) error {
table.Addheaders("application", "privileges", "resources") table.Addheaders("application", "privileges", "resources")
idx := 0 idx := 0
for _, priv := range role.Applications { for _, priv := range role.Applications {
table.Entries[idx] = []string{ table.Entries[idx] = []any{
priv.Application, priv.Application,
strings.Join(priv.Privileges, ", "), priv.Privileges,
strings.Join(priv.Resources, ", "), priv.Resources,
} }
idx++ idx++

View File

@@ -229,7 +229,7 @@ func RoleDiff(conf *cfg.Config, csvfile, role string) error {
defined = printer.Colorize(conf, "red", "undefined") defined = printer.Colorize(conf, "red", "undefined")
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{
row.name, row.name,
deployed, deployed,
defined, defined,

View File

@@ -107,7 +107,7 @@ func printShards(conf *cfg.Config, shardlist shards.Response) error {
for idx, shard := range shardlist { for idx, shard := range shardlist {
name := colorzizeShard(conf, *shard.State, *shard.Index) name := colorzizeShard(conf, *shard.State, *shard.Index)
table.Entries[idx] = []string{ table.Entries[idx] = []any{
name, name,
*shard.Shard, *shard.Shard,
resolvePrirep(*shard.Prirep), resolvePrirep(*shard.Prirep),

View File

@@ -88,7 +88,7 @@ func SnapshotList(conf *cfg.Config) error {
table.Addheaders("name", "index", "start", "orphaned", "status") table.Addheaders("name", "index", "start", "orphaned", "status")
for idx, snap := range snapshots { for idx, snap := range snapshots {
table.Entries[idx] = []string{ table.Entries[idx] = []any{
snap.Name, snap.Name,
snap.Forindex, snap.Forindex,
snap.Start, snap.Start,
@@ -122,20 +122,20 @@ func SnapshotShow(conf *cfg.Config, snapshot string) error {
snap := res.Snapshots[0] snap := res.Snapshots[0]
table.Entries = [][]string{ table.Entries = [][]any{
{"snapshot", snapshot}, {"snapshot", snapshot},
{"uuid", snap.Uuid}, {"uuid", snap.Uuid},
{"repository", *snap.Repository}, {"repository", *snap.Repository},
{"version_id", fmt.Sprintf("%d", snap.VersionId)}, {"version_id", snap.VersionId},
{"version", *snap.Version}, {"version", *snap.Version},
{"include_global_state", fmt.Sprintf("%t", *snap.IncludeGlobalState)}, {"include_global_state", *snap.IncludeGlobalState},
{"state", *snap.State}, {"state", *snap.State},
{"start_time", fmt.Sprintf("%s", snap.StartTime)}, {"start_time", snap.StartTime},
{"end_time", fmt.Sprintf("%s", snap.EndTime)}, {"end_time", snap.EndTime},
{"duration_in_millis", fmt.Sprintf("%d", *snap.DurationInMillis)}, {"duration_in_millis", *snap.DurationInMillis},
{"shards-total", fmt.Sprintf("%d", snap.Shards.Total)}, {"shards-total", snap.Shards.Total},
{"shards-failed", fmt.Sprintf("%d", snap.Shards.Failed)}, {"shards-failed", snap.Shards.Failed},
{"shards-successful", fmt.Sprintf("%d", snap.Shards.Successful)}, {"shards-successful", snap.Shards.Successful},
} }
if err := table.Print(); err != nil { if err := table.Print(); err != nil {

View File

@@ -49,10 +49,10 @@ func TaskList(conf *cfg.Config) error {
ts = time.Unix(int64(epc/1000), 0) ts = time.Unix(int64(epc/1000), 0)
} }
table.Entries[idx] = []string{ table.Entries[idx] = []any{
*task.TaskId, *task.TaskId,
*task.Action, *task.Action,
ts.Format("2006-01-02T15:04:05"), ts,
*task.RunningTime, *task.RunningTime,
*task.Node, *task.Node,
*task.Type, *task.Type,

31
pkg/printer/bytes.go Normal file
View File

@@ -0,0 +1,31 @@
/*
Copyright © 2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package printer
import "github.com/dustin/go-humanize"
type ByteSize struct {
size uint64
}
func Bytes(size int64) ByteSize {
return ByteSize{size: uint64(size)}
}
func (b *ByteSize) String() string {
return humanize.Bytes(b.size)
}

97
pkg/printer/cast.go Normal file
View File

@@ -0,0 +1,97 @@
/*
Copyright © 2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package printer
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/elastic/go-elasticsearch/v9/typedapi/types"
)
func any2string(in any) string {
switch val := in.(type) {
case string:
return val
case bool:
return strconv.FormatBool(val)
case int64:
return strconv.FormatInt(val, 10)
case int:
return strconv.Itoa(val)
case float64:
return fmt.Sprintf("%.2f", val)
case []string:
return strings.Join(val, ",")
case ByteSize:
return val.String()
case time.Time:
return val.Format("2006-01-02 15:04:05")
case []byte:
return string(val)
case types.DateTime, types.Percentage:
return val.(string)
case nil:
return "null"
}
return ""
}
func (data *Table) preprocessRows() {
if data.processed {
// only do it once
return
}
// convert entries to strings
data.rows = make([][]string, len(data.Entries))
for rowidx, entries := range data.Entries {
data.rows[rowidx] = make([]string, len(entries))
for colidx, entry := range data.Entries[rowidx] {
data.rows[rowidx][colidx] = any2string(entry)
}
}
// determine header lenght's
for idx, head := range data.Headers {
data.lenHeaders[idx] = visibleLen(head)
}
// determine max width per column
for _, entries := range data.rows {
currentWidth := 0
for idx, entry := range entries {
length := visibleLen(entry)
if data.lenHeaders[idx] < length {
if length > currentWidth+data.maxwidth {
data.lenHeaders[idx] = data.maxwidth - currentWidth
} else {
data.lenHeaders[idx] = length
}
}
currentWidth += data.lenHeaders[idx]
}
}
data.processed = true
}

View File

@@ -25,18 +25,17 @@ import (
"strings" "strings"
"codeberg.org/scip/esctl/pkg/cfg" "codeberg.org/scip/esctl/pkg/cfg"
"github.com/olekukonko/tablewriter"
"github.com/olekukonko/tablewriter/renderer"
"github.com/olekukonko/tablewriter/tw"
"github.com/seeruk/go-wordwrap" "github.com/seeruk/go-wordwrap"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
type Table struct { type Table struct {
Mode string // table, markdown, json Mode string // tsv, json, yaml
Headers []string Headers []string
Entries [][]string Entries [][]any
rows [][]string // representation used for printing
processed bool
lenHeaders []int lenHeaders []int
alignInts bool alignInts bool
maxwidth int maxwidth int
@@ -46,7 +45,7 @@ func NewTable(conf *cfg.Config, columns, rows int) *Table {
table := Table{Mode: conf.Output, maxwidth: cfg.GetTermWidth()} table := Table{Mode: conf.Output, maxwidth: cfg.GetTermWidth()}
table.Headers = make([]string, columns) table.Headers = make([]string, columns)
table.Entries = make([][]string, rows) table.Entries = make([][]any, rows)
table.lenHeaders = make([]int, columns) table.lenHeaders = make([]int, columns)
table.alignInts = conf.AlignInts table.alignInts = conf.AlignInts
@@ -62,7 +61,7 @@ func NewTableEmpty(conf *cfg.Config) *Table {
func (table *Table) WithHeaders(headers ...string) *Table { func (table *Table) WithHeaders(headers ...string) *Table {
count := len(headers) count := len(headers)
table.Entries = [][]string{} table.Entries = [][]any{}
table.lenHeaders = make([]int, count) table.lenHeaders = make([]int, count)
table.Headers = make([]string, count) table.Headers = make([]string, count)
@@ -73,8 +72,6 @@ func (table *Table) WithHeaders(headers ...string) *Table {
func (data *Table) Print() error { func (data *Table) Print() error {
switch data.Mode { switch data.Mode {
case "markdown", "md":
return data.PrintMarkdown()
case "json": case "json":
return data.PrintJSON() return data.PrintJSON()
case "yaml": case "yaml":
@@ -89,11 +86,11 @@ var (
) )
// needed for json and yaml output // needed for json and yaml output
func (data *Table) toMap() []map[string]string { func (data *Table) toMap() []map[string]any {
raw := make([]map[string]string, len(data.Entries)) raw := make([]map[string]any, len(data.Entries))
for idx, entries := range data.Entries { for idx, entries := range data.Entries {
raw[idx] = make(map[string]string, len(data.Headers)) raw[idx] = make(map[string]any, len(data.Headers))
for eidx, entry := range entries { for eidx, entry := range entries {
raw[idx][data.Headers[eidx]] = entry raw[idx][data.Headers[eidx]] = entry
} }
@@ -128,31 +125,9 @@ func (data *Table) PrintJSON() error {
return nil return nil
} }
// Well. tablewriter should be able to print in TSV mode, but it
// doesn't work because of the various ansic color escapes we're
// using. Therefore we do it the hard way and use our own TSV printer.
func (data *Table) PrintTSV() error { func (data *Table) PrintTSV() error {
// determine lenght's // length's, convert cell types
for idx, head := range data.Headers { data.preprocessRows()
data.lenHeaders[idx] = visibleLen(head)
}
for _, entries := range data.Entries {
currentWidth := 0
for idx, entry := range entries {
length := visibleLen(entry)
if data.lenHeaders[idx] < length {
if length > currentWidth+data.maxwidth {
data.lenHeaders[idx] = data.maxwidth - currentWidth
} else {
data.lenHeaders[idx] = length
}
}
currentWidth += data.lenHeaders[idx]
}
}
// output headers // output headers
for idx, header := range data.Headers { for idx, header := range data.Headers {
@@ -169,7 +144,7 @@ func (data *Table) PrintTSV() error {
} }
fmt.Println() fmt.Println()
for _, entries := range data.Entries { for _, entries := range data.rows {
currentWidth := 0 currentWidth := 0
for idx, entry := range entries { for idx, entry := range entries {
@@ -213,130 +188,16 @@ func (data *Table) PrintTSV() error {
return nil return nil
} }
func (data *Table) PrintTabularFail() error {
OFS := " "
tableString := &strings.Builder{}
styleTSV := tw.NewSymbolCustom("space").WithColumn("\t")
table := tablewriter.NewTable(tableString,
tablewriter.WithRenderer(
renderer.NewBlueprint(tw.Rendition{
Borders: tw.BorderNone,
Symbols: styleTSV,
Settings: tw.Settings{
Separators: tw.SeparatorsNone,
Lines: tw.LinesNone,
},
})),
tablewriter.WithConfig(tablewriter.Config{
Header: tw.CellConfig{
Formatting: tw.CellFormatting{
AutoFormat: tw.Off,
},
Padding: tw.CellPadding{Global: tw.Padding{Left: "", Right: OFS}},
},
Row: tw.CellConfig{
Formatting: tw.CellFormatting{
AutoWrap: tw.WrapNone,
Alignment: tw.AlignLeft,
},
Padding: tw.CellPadding{Global: tw.Padding{Right: OFS}},
},
Debug: true,
}),
)
table.Header(data.Headers)
if err := table.Bulk(data.Entries); err != nil {
return fmt.Errorf("failed to add data to table renderer: %s", err)
}
if err := table.Render(); err != nil {
return fmt.Errorf("failed to render table: %s", err)
}
// we need to trim our output here, because tablewriter appends
// excess whitespace to our rows.
cleanedString := &strings.Builder{}
for _, row := range strings.Split(strings.TrimSpace(tableString.String()), "\n") {
cleanedString.WriteString(strings.TrimSpace(row))
cleanedString.WriteString("\n")
}
fmt.Println(cleanedString.String())
return nil
}
func (data *Table) PrintMarkdown() error {
tableString := &strings.Builder{}
table := tablewriter.NewTable(tableString,
tablewriter.WithRenderer(
renderer.NewBlueprint(
tw.Rendition{
Borders: tw.Border{
Left: tw.On,
Right: tw.On,
Top: tw.Off,
Bottom: tw.Off,
},
Settings: tw.Settings{
Separators: tw.Separators{
ShowHeader: tw.On,
ShowFooter: tw.Off,
BetweenRows: tw.Off,
BetweenColumns: 0,
},
},
Symbols: tw.NewSymbols(tw.StyleMarkdown),
})),
tablewriter.WithConfig(
tablewriter.Config{
Header: tw.CellConfig{
Formatting: tw.CellFormatting{
Alignment: tw.AlignLeft,
AutoFormat: tw.Off,
},
},
Row: tw.CellConfig{
Formatting: tw.CellFormatting{
Alignment: tw.AlignLeft,
},
},
},
),
)
table.Header(data.Headers)
if err := table.Bulk(data.Entries); err != nil {
return fmt.Errorf("failed to add data to table renderer: %s", err)
}
if err := table.Render(); err != nil {
return fmt.Errorf("failed to render table: %s", err)
}
fmt.Println(tableString.String())
return nil
}
func (data *Table) Sort() { func (data *Table) Sort() {
// sanity checks // sanity checks
if len(data.Entries) == 0 { if len(data.Entries) == 0 {
return return
} }
sort.Slice(data.Entries, func(i, j int) bool { data.preprocessRows()
return data.Entries[i][0] < data.Entries[j][0]
sort.Slice(data.rows, func(i, j int) bool {
return data.rows[i][0] < data.rows[j][0]
}) })
} }
@@ -351,7 +212,7 @@ func (data *Table) Addheaders(headers ...string) {
} }
} }
func (data *Table) AddRow(fields ...string) { func (data *Table) AddRow(fields ...any) {
data.Entries = append(data.Entries, fields) data.Entries = append(data.Entries, fields)
} }