diff --git a/go.mod b/go.mod index b6e82134..c0047caa 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,10 @@ require ( github.com/aws/aws-sdk-go v1.49.12 github.com/briandowns/spinner v1.19.0 github.com/c-bata/go-prompt v0.2.3 - github.com/fatih/color v1.13.0 + github.com/fatih/color v1.15.0 github.com/ghodss/yaml v1.0.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/olekukonko/tablewriter v0.0.5 + github.com/olekukonko/tablewriter v1.0.9 github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da github.com/segmentio/kafka-go v0.4.48 github.com/segmentio/kafka-go/sasl/aws_msk_iam v0.0.0-20220211180808-78889264d070 @@ -26,16 +26,19 @@ require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/compress v1.15.9 // indirect - github.com/mattn/go-colorable v0.1.9 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-tty v0.0.3 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/olekukonko/errors v1.1.0 // indirect + github.com/olekukonko/ll v0.0.9 // indirect github.com/onsi/ginkgo v1.6.0 // indirect github.com/onsi/gomega v1.5.0 // indirect github.com/pierrec/lz4/v4 v4.1.15 // indirect github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect diff --git a/go.sum b/go.sum index b8769502..2b37b496 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -42,22 +42,26 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -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.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -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/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM= +github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= +github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI= +github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g= +github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8= +github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo= github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= @@ -70,6 +74,8 @@ github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 h1:pd4YKIqCB0U7O2I4gWHgEU github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03/go.mod h1:Z9+Ul5bCbBKnbCvdOWbLqTHhJiYV414CURZJba6L8qA= 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.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -132,16 +138,15 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= diff --git a/pkg/admin/format.go b/pkg/admin/format.go index 8d2263f9..aa172b91 100644 --- a/pkg/admin/format.go +++ b/pkg/admin/format.go @@ -11,6 +11,7 @@ import ( "github.com/fatih/color" "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/tw" "github.com/segmentio/topicctl/pkg/util" ) @@ -18,8 +19,6 @@ import ( func FormatBrokers(brokers []BrokerInfo, full bool) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - var hasInstances bool for _, broker := range brokers { if broker.InstanceID != "" { @@ -28,7 +27,7 @@ func FormatBrokers(brokers []BrokerInfo, full bool) string { } } - headers := []string{ + headers := []any{ "ID", "Host", "Port", @@ -52,30 +51,25 @@ func FormatBrokers(brokers []BrokerInfo, full bool) string { headers = append(headers, "Config") } - table.SetHeader(headers) - - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + for _, broker := range brokers { row := []string{ fmt.Sprintf("%d", broker.ID), @@ -111,23 +105,22 @@ func FormatBrokers(brokers []BrokerInfo, full bool) string { // FormatControllerID creates a pretty table for controller broker. func FormatControllerID(brokerID int) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - headers := []string{"Active Controller"} - table.SetHeader(headers) - - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header("Active Controller") table.Append([]string{ fmt.Sprintf("%d", brokerID), @@ -140,23 +133,22 @@ func FormatControllerID(brokerID int) string { // FormatClusterID creates a pretty table for cluster ID. func FormatClusterID(clusterID string) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - headers := []string{"Kafka Cluster ID"} - table.SetHeader(headers) - - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header("Kafka Cluster ID") table.Append([]string{ clusterID, @@ -172,12 +164,10 @@ func FormatClusterID(clusterID string) string { func FormatBrokerReplicas(brokers []BrokerInfo, topics []TopicInfo) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - maxReplicas := MaxReplication(topics) hasLeaders := HasLeaders(topics) - headers := []string{ + headers := []any{ "ID", "Rack", } @@ -191,28 +181,25 @@ func FormatBrokerReplicas(brokers []BrokerInfo, topics []TopicInfo) string { } headers = append(headers, "Total") - table.SetHeader(headers) - - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + brokerLeaders := map[int]int{} brokerPositions := map[int][]int{} @@ -269,12 +256,10 @@ func FormatBrokerReplicas(brokers []BrokerInfo, topics []TopicInfo) string { func FormatBrokerRackReplicas(brokers []BrokerInfo, topics []TopicInfo) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - maxReplicas := MaxReplication(topics) hasLeaders := HasLeaders(topics) - headers := []string{ + headers := []any{ "Rack", } @@ -287,28 +272,25 @@ func FormatBrokerRackReplicas(brokers []BrokerInfo, topics []TopicInfo) string { } headers = append(headers, "Total") - table.SetHeader(headers) - - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + rackLeaders := map[string]int{} rackPositions := map[string][]int{} @@ -368,29 +350,25 @@ func FormatBrokerRackReplicas(brokers []BrokerInfo, topics []TopicInfo) string { func FormatBrokersPerRack(brokers []BrokerInfo) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Rack", - "Num Brokers", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header("Rack", "Num Brokers") + brokerCountsPerRack := BrokerCountsPerRack(brokers) racks := DistinctRacks(brokers) @@ -412,7 +390,7 @@ func FormatBrokersPerRack(brokers []BrokerInfo) string { func FormatTopics(topics []TopicInfo, brokers []BrokerInfo, full bool) string { buf := &bytes.Buffer{} - headers := []string{ + headers := []any{ "Name", "Partitions", "Replication", @@ -424,30 +402,25 @@ func FormatTopics(topics []TopicInfo, brokers []BrokerInfo, full bool) string { headers = append(headers, "Config") } - table := tablewriter.NewWriter(buf) - table.SetHeader(headers) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + brokerRacks := BrokerRacks(brokers) for _, topic := range topics { @@ -484,32 +457,28 @@ func FormatTopics(topics []TopicInfo, brokers []BrokerInfo, full bool) string { func FormatTopicPartitions(partitions []PartitionInfo, brokers []BrokerInfo) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "ID", "Leader", "Replicas", "ISR", "Distinct\nRacks", "Racks", "Status", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "ID", "Leader", "Replicas", "ISR", "Distinct\nRacks", "Racks", "Status", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + brokerRacks := BrokerRacks(brokers) maxBrokerWidth := maxValueToMaxWidth(len(brokers)) @@ -569,32 +538,32 @@ func FormatTopicsPartitionsSummary( ) string { buf := &bytes.Buffer{} - headers := []string{ + headers := []any{ "Topic", "Status", "Count", "IDs", } - columnAligment := []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() } - table := tablewriter.NewWriter(buf) - table.SetHeader(headers) - table.SetAutoWrapText(true) - table.SetColumnAlignment(columnAligment) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + topicNames := []string{} tableData := make(map[string][][]string) for topicName, partitionsStatusSummary := range topicsPartitionsStatusSummary { @@ -643,7 +612,7 @@ func FormatTopicsPartitions( ) string { buf := &bytes.Buffer{} - headers := []string{ + headers := []any{ "Topic", "ID", "Leader", @@ -653,30 +622,26 @@ func FormatTopicsPartitions( "Racks", "Status", } - columnAligment := []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() } - table := tablewriter.NewWriter(buf) - table.SetHeader(headers) - table.SetAutoWrapText(false) - table.SetColumnAlignment(columnAligment) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + topicNames := []string{} brokerRacks := BrokerRacks(brokers) tableData := make(map[string][][]string) @@ -766,29 +731,25 @@ func FormatTopicsPartitions( func FormatConfig(configMap map[string]string) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Key", - "Value", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header("Key", "Value") + keys := []string{} for key := range configMap { keys = append(keys, key) @@ -816,28 +777,25 @@ func FormatConfig(configMap map[string]string) string { func FormatTopicLeadersPerRack(topic TopicInfo, brokers []BrokerInfo) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Rack", "Num Leaders", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header("Rack", "Num Leaders") + leadersPerRack := LeadersPerRack(brokers, topic) racks := DistinctRacks(brokers) @@ -863,33 +821,31 @@ func FormatAssignentDiffs( ) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Partition", - "Curr\nReplicas", - "Proposed\nReplicas", - "Diff?", - "New\nLeader?", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Partition", + "Curr\nReplicas", + "Proposed\nReplicas", + "Diff?", + "New\nLeader?", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) diffs := AssignmentDiffs(curr, desired) @@ -934,33 +890,32 @@ func FormatBrokerMaxPartitions( ) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Broker", - "Curr\nPartitions", - "Max\nPartitions", - "Proposed\nPartitions", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Broker", + "Curr\nPartitions", + "Max\nPartitions", + "Proposed\nPartitions", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + startPartitionsPerBroker := MaxPartitionsPerBroker(curr) maxPartitionsPerBroker := MaxPartitionsPerBroker(curr, desired) finalPartitionsPerBroker := MaxPartitionsPerBroker(desired) @@ -1007,7 +962,7 @@ func FormatBrokerMaxPartitions( func FormatACLs(acls []ACLInfo) string { buf := &bytes.Buffer{} - headers := []string{ + headers := []any{ "Resource Type", "Pattern Type", "Resource Name", @@ -1017,29 +972,25 @@ func FormatACLs(acls []ACLInfo) string { "Permission Type", } - table := tablewriter.NewWriter(buf) - table.SetHeader(headers) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + for _, acl := range acls { row := []string{ acl.ResourceType.String(), @@ -1063,30 +1014,32 @@ func FormatACLs(acls []ACLInfo) string { func FormatUsers(users []UserInfo) string { buf := &bytes.Buffer{} - headers := []string{ + headers := []any{ "Name", "Mechanism", "Iterations", } - table := tablewriter.NewWriter(buf) - table.SetHeader(headers) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + ForColumn(2).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + for _, user := range users { for _, credential := range user.CredentialInfos { row := []string{ diff --git a/pkg/apply/format.go b/pkg/apply/format.go index 2cc6361f..1b5c7459 100644 --- a/pkg/apply/format.go +++ b/pkg/apply/format.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/tw" "github.com/segmentio/kafka-go" "github.com/segmentio/topicctl/pkg/config" log "github.com/sirupsen/logrus" @@ -34,31 +35,27 @@ func FormatSettingsDiff( ) (string, error) { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - - headers := []string{ + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + ForColumn(2).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), + ) + table.Header( "Key", "Cluster Value (Curr)", "Config Value (New)", - } - - table.SetHeader(headers) - - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, ) for _, diffKey := range diffKeys { @@ -101,29 +98,25 @@ func FormatMissingKeys( ) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - - headers := []string{ + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), + ) + table.Header( "Key", "Cluster Value", - } - - table.SetHeader(headers) - - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, ) for _, missingKey := range missingKeys { diff --git a/pkg/check/format.go b/pkg/check/format.go index fb6d16e8..2c46dc98 100644 --- a/pkg/check/format.go +++ b/pkg/check/format.go @@ -6,6 +6,7 @@ import ( "github.com/fatih/color" "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/tw" "github.com/segmentio/topicctl/pkg/util" ) @@ -13,30 +14,24 @@ import ( func FormatResults(results TopicCheckResults) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - - table.SetHeader([]string{ - "Name", - "OK", - "Details", - }) - - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_CENTER, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignCenter).Build(). + ForColumn(2).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header("Name", "OK", "Details") for _, result := range results.Results { var checkPrinter func(f string, a ...interface{}) string diff --git a/pkg/cli/repl.go b/pkg/cli/repl.go index f167fd2e..89c44542 100644 --- a/pkg/cli/repl.go +++ b/pkg/cli/repl.go @@ -12,6 +12,7 @@ import ( "github.com/c-bata/go-prompt" "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/tw" "github.com/segmentio/kafka-go" "github.com/segmentio/topicctl/pkg/admin" "github.com/segmentio/topicctl/pkg/groups" @@ -114,7 +115,6 @@ func NewRepl( log.Debug("Loading topic names for auto-complete") topicNames, err := adminClient.GetTopicNames(ctx) - if err != nil { return nil, err } @@ -466,25 +466,25 @@ func (r *Repl) completer(doc prompt.Document) []prompt.Suggest { func helpTable() string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetColumnSeparator("") - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: false, - Right: false, - Bottom: false, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Symbols: tw.NewSymbolCustom("repl").WithColumn(""), + Borders: tw.Border{ + Left: tw.Off, + Top: tw.Off, + Right: tw.Off, + Bottom: tw.Off, + }, + }), ) - table.AppendBulk( + table.Bulk( [][]string{ { " get acls", diff --git a/pkg/groups/format.go b/pkg/groups/format.go index c1ea801c..11ab401d 100644 --- a/pkg/groups/format.go +++ b/pkg/groups/format.go @@ -9,6 +9,7 @@ import ( "github.com/fatih/color" "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/tw" "github.com/segmentio/topicctl/pkg/util" ) @@ -16,31 +17,31 @@ import ( func FormatGroupCoordinators(groupCoordinators []GroupCoordinator) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Group", - "Coordinator", - "Topics", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Group", + "Coordinator", + "Topics", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + for _, groupCoordinator := range groupCoordinators { table.Append( []string{ @@ -59,34 +60,32 @@ func FormatGroupCoordinators(groupCoordinators []GroupCoordinator) string { func FormatGroupMembers(members []MemberInfo, full bool) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Member ID", - "Client Host", - "Num\nPartitions", - "Partition\nAssignments", - }, - ) - table.SetAutoWrapText(true) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Member ID", + "Client Host", + "Num\nPartitions", + "Partition\nAssignments", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + for _, member := range members { var clientHost string if strings.HasPrefix(member.ClientHost, "/") { @@ -127,29 +126,30 @@ func FormatGroupMembers(members []MemberInfo, full bool) string { func FormatMemberPartitionCounts(members []MemberInfo) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Num Partitions", - "Num Members", - }, - ) - table.SetAutoWrapText(true) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Num Partitions", + "Num Members", + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + countKeys := []int{} membersByCount := map[int]int{} @@ -188,41 +188,36 @@ func FormatMemberPartitionCounts(members []MemberInfo) string { func FormatMemberLags(memberLags []MemberPartitionLag, full bool) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Partition", - "Member ID", - "Member Offset", - "Member Time", - "Latest Offset", - "Latest Time", - "Offset Lag", - "Time Lag", - }, - ) - table.SetAutoWrapText(true) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Partition", + "Member ID", + "Member Offset", + "Member Time", + "Latest Offset", + "Latest Time", + "Offset Lag", + "Time Lag", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + for _, memberLag := range memberLags { var memberID string @@ -275,29 +270,25 @@ func FormatMemberLags(memberLags []MemberPartitionLag, full bool) string { func FormatPartitionOffsets(partitionOffsets map[int]int64) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Partition", - "New Offset", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + table := tablewriter.NewTable(buf, + tablewriter.WithConfig( + tablewriter.NewConfigBuilder(). + WithRowAutoWrap(tw.WrapNone). + ForColumn(0).WithAlignment(tw.AlignLeft).Build(). + ForColumn(1).WithAlignment(tw.AlignLeft).Build(). + Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header("Partition", "New Offset") + partitionIDs := []int{} for partitionID := range partitionOffsets { partitionIDs = append(partitionIDs, partitionID) diff --git a/pkg/messages/format.go b/pkg/messages/format.go index 7e800460..75fceb15 100644 --- a/pkg/messages/format.go +++ b/pkg/messages/format.go @@ -7,6 +7,7 @@ import ( "time" "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/tw" "github.com/segmentio/topicctl/pkg/util" ) @@ -14,12 +15,10 @@ import ( func FormatTailStats(stats TailStats, filtered bool) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - - var headerNames []string + var headers []any if filtered { - headerNames = []string{ + headers = []any{ "Partition", "Messages Tailed\n(Total)", "Messages Tailed\n(Filtered)", @@ -29,7 +28,7 @@ func FormatTailStats(stats TailStats, filtered bool) string { "Last Time", } } else { - headerNames = []string{ + headers = []any{ "Partition", "Messages Tailed", "First Offset", @@ -39,28 +38,25 @@ func FormatTailStats(stats TailStats, filtered bool) string { } } - table.SetHeader(headerNames) - - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + partitions := []int{} for partition, partitionStats := range stats.PartitionStats { @@ -109,41 +105,36 @@ func FormatTailStats(stats TailStats, filtered bool) string { func FormatBounds(boundsSlice []Bounds) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Partition", - "First Offset", - "First Time", - "Last Offset", - "Last Time", - "Messages", - "Duration", - "Avg Rate", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Partition", + "First Offset", + "First Time", + "Last Offset", + "Last Time", + "Messages", + "Duration", + "Avg Rate", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + for _, bounds := range boundsSlice { if bounds.FirstOffset == bounds.LastOffset { table.Append( @@ -186,36 +177,33 @@ func FormatBounds(boundsSlice []Bounds) string { func FormatBoundTotals(boundsSlice []Bounds) string { buf := &bytes.Buffer{} - table := tablewriter.NewWriter(buf) - table.SetHeader( - []string{ - "Earliest Time", - "Latest Time", - "Total Messages", - "Duration", - "Avg Rate", - }, - ) - table.SetAutoWrapText(false) - table.SetColumnAlignment( - []int{ - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - tablewriter.ALIGN_LEFT, - }, - ) - table.SetBorders( - tablewriter.Border{ - Left: false, - Top: true, - Right: false, - Bottom: true, - }, + headers := []any{ + "Earliest Time", + "Latest Time", + "Total Messages", + "Duration", + "Avg Rate", + } + + configBuilder := tablewriter.NewConfigBuilder().WithRowAutoWrap(tw.WrapNone) + for i := range headers { + configBuilder = configBuilder.ForColumn(i).WithAlignment(tw.AlignLeft).Build() + } + + table := tablewriter.NewTable(buf, + tablewriter.WithConfig(configBuilder.Build()), + tablewriter.WithRendition(tw.Rendition{ + Borders: tw.Border{ + Left: tw.Off, + Top: tw.On, + Right: tw.Off, + Bottom: tw.On, + }, + }), ) + table.Header(headers...) + var totalMessages int64 var earliestTime time.Time var latestTime time.Time