From 8ac076a0bcd6a35ca7cdfc9dbddc345a2d5191d8 Mon Sep 17 00:00:00 2001 From: Wyatt Alt Date: Fri, 8 Sep 2023 15:46:43 -0700 Subject: [PATCH] Tidy upper part of info table (#967) This aligns the spacing in the upper part of the "mcap info" output. --- go/cli/mcap/cmd/info.go | 33 +++++++++++++++++++++++---------- go/cli/mcap/utils/utils.go | 11 ++++++++++- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/go/cli/mcap/cmd/info.go b/go/cli/mcap/cmd/info.go index d5e57ad5ca..789e32fcf8 100644 --- a/go/cli/mcap/cmd/info.go +++ b/go/cli/mcap/cmd/info.go @@ -8,6 +8,7 @@ import ( "math" "os" "sort" + "strings" "time" "github.com/foxglove/mcap/go/cli/mcap/utils" @@ -48,14 +49,21 @@ func getDurationNs(start uint64, end uint64) float64 { return float64(diff) * signMultiplier } +func addRow(rows [][]string, field string, value string, args ...any) [][]string { + return append(rows, []string{field, fmt.Sprintf(value, args...)}) +} + func printInfo(w io.Writer, info *mcap.Info) error { buf := &bytes.Buffer{} - fmt.Fprintf(buf, "library: %s\n", info.Header.Library) - fmt.Fprintf(buf, "profile: %s\n", info.Header.Profile) + + header := [][]string{ + {"library:", info.Header.Library}, + {"profile:", info.Header.Profile}, + } var start, end uint64 durationInSeconds := float64(0) if info.Statistics != nil { - fmt.Fprintf(buf, "messages: %d\n", info.Statistics.MessageCount) + header = addRow(header, "messages:", "%d", info.Statistics.MessageCount) start = info.Statistics.MessageStartTime end = info.Statistics.MessageEndTime durationNs := getDurationNs(start, end) @@ -65,18 +73,19 @@ func printInfo(w io.Writer, info *mcap.Info) error { if math.Abs(durationNs) > math.MaxInt64 { // time.Duration is an int64 nanosecond count under the hood, but end and start can // be further apart than that. - fmt.Fprintf(buf, "duration: %.3fs\n", durationInSeconds) + header = addRow(header, "duration:", "%.3fs", durationInSeconds) } else { - fmt.Fprintf(buf, "duration: %s\n", endtime.Sub(starttime)) + header = addRow(header, "duration:", "%s", endtime.Sub(starttime)) } if starttime.After(LongAgo) { - fmt.Fprintf(buf, "start: %s (%s)\n", starttime.Format(time.RFC3339Nano), decimalTime(starttime)) - fmt.Fprintf(buf, "end: %s (%s)\n", endtime.Format(time.RFC3339Nano), decimalTime(endtime)) + header = addRow(header, "start:", "%s (%s)", starttime.Format(time.RFC3339Nano), decimalTime(starttime)) + header = addRow(header, "end:", "%s (%s)", endtime.Format(time.RFC3339Nano), decimalTime(endtime)) } else { - fmt.Fprintf(buf, "start: %s\n", decimalTime(starttime)) - fmt.Fprintf(buf, "end: %s\n", decimalTime(endtime)) + header = addRow(header, "start:", "%s", decimalTime(starttime)) + header = addRow(header, "end:", "%s", decimalTime(endtime)) } } + utils.FormatTable(buf, header) if len(info.ChunkIndexes) > 0 { compressionFormatStats := make(map[mcap.CompressionFormat]struct { count int @@ -121,13 +130,17 @@ func printInfo(w io.Writer, info *mcap.Info) error { } } } + + maxChanIDWidth := digits(uint64(chanIDs[len(chanIDs)-1])) + 3 for _, chanID := range chanIDs { channel := info.Channels[chanID] schema := info.Schemas[channel.SchemaID] channelMessageCount := info.Statistics.ChannelMessageCounts[chanID] frequency := 1e9 * float64(channelMessageCount) / float64(end-start) + width := digits(uint64(chanID)) + 2 + padding := strings.Repeat(" ", maxChanIDWidth-width) row := []string{ - fmt.Sprintf("\t(%d) %s", channel.ID, channel.Topic), + fmt.Sprintf("\t(%d)%s%s", channel.ID, padding, channel.Topic), } if info.Statistics != nil { row = append(row, fmt.Sprintf("%*d msgs (%.2f Hz)", maxCountWidth, channelMessageCount, frequency)) diff --git a/go/cli/mcap/utils/utils.go b/go/cli/mcap/utils/utils.go index 07180d9210..16c8ff7344 100644 --- a/go/cli/mcap/utils/utils.go +++ b/go/cli/mcap/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "bufio" "bytes" "context" "encoding/json" @@ -8,6 +9,7 @@ import ( "io" "os" "regexp" + "strings" "cloud.google.com/go/storage" "github.com/foxglove/mcap/go/mcap" @@ -104,7 +106,8 @@ func WithReader(ctx context.Context, filename string, f func(remote bool, rs io. } func FormatTable(w io.Writer, rows [][]string) { - tw := tablewriter.NewWriter(w) + buf := &bytes.Buffer{} + tw := tablewriter.NewWriter(buf) tw.SetBorder(false) tw.SetAutoWrapText(false) tw.SetAlignment(tablewriter.ALIGN_LEFT) @@ -112,6 +115,12 @@ func FormatTable(w io.Writer, rows [][]string) { tw.SetColumnSeparator("") tw.AppendBulk(rows) tw.Render() + // This tablewriter puts a leading space on the lines for some reason, so + // remove it. + scanner := bufio.NewScanner(buf) + for scanner.Scan() { + fmt.Fprintln(w, strings.TrimLeft(scanner.Text(), " ")) + } } func inferWriterOptions(info *mcap.Info) *mcap.WriterOptions {