From 1a84a6473632eacffb79a6e228aa2430e44b6307 Mon Sep 17 00:00:00 2001 From: Maciej Lisiewski Date: Wed, 10 Aug 2022 23:12:40 -0400 Subject: [PATCH] Make summary respect -smallscreen, improve package shortening (#81) --- internal/app/app.go | 5 ++- internal/app/table_summary.go | 74 ++++++++++++++++++++++++++++++++++- internal/app/table_tests.go | 20 ++++------ main.go | 3 ++ 4 files changed, 86 insertions(+), 16 deletions(-) diff --git a/internal/app/app.go b/internal/app/app.go index f9b8892..d1ea43e 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -19,7 +19,8 @@ type Options struct { FileName string // Test table options - TestTableOptions TestTableOptions + TestTableOptions TestTableOptions + SummaryTableOptions SummaryTableOptions // TODO(mf): implement Progress bool @@ -83,5 +84,5 @@ func display(w io.Writer, summary *parse.GoTestSummary, option Options) { } // Failures (if any) and summary table are always printed. cw.printFailed(packages) - cw.summaryTable(packages, option.ShowNoTests) + cw.summaryTable(packages, option.ShowNoTests, option.SummaryTableOptions) } diff --git a/internal/app/table_summary.go b/internal/app/table_summary.go index d80cb33..c094b8e 100644 --- a/internal/app/table_summary.go +++ b/internal/app/table_summary.go @@ -2,6 +2,7 @@ package app import ( "fmt" + "path" "strconv" "strings" @@ -10,7 +11,18 @@ import ( "github.com/olekukonko/tablewriter" ) -func (c *consoleWriter) summaryTable(packages []*parse.Package, showNoTests bool) { +type SummaryTableOptions struct { + // For narrow screens, remove common prefix and trim long package names vertically. Example: + // github.com/mfridman/tparse/app + // github.com/mfridman/tparse/internal/seed-up-down-to-zero + // + // tparse/app + // tparse + // /seed-up-down-to-zero + Trim bool +} + +func (c *consoleWriter) summaryTable(packages []*parse.Package, showNoTests bool, options SummaryTableOptions) { var tableString strings.Builder tbl := newTableWriter(&tableString, c.format) tbl.SetColumnAlignment([]int{ @@ -38,12 +50,14 @@ func (c *consoleWriter) summaryTable(packages []*parse.Package, showNoTests bool // is almost always the user matching on the wrong package. var passed, notests []summaryRow + packagePrefix := findCommonPackagePrefix(packages) + for _, pkg := range packages { elapsed := strconv.FormatFloat(pkg.Summary.Elapsed, 'f', 2, 64) + "s" if pkg.Cached { elapsed = "(cached)" } - packageName := pkg.Summary.Package + packageName := shortenPackageName(pkg.Summary.Package, packagePrefix, 32, options.Trim) if pkg.HasPanic { row := summaryRow{ status: c.red("PANIC"), @@ -194,3 +208,59 @@ func (r summaryRow) toRow() []string { r.skip, } } + +func findCommonPackagePrefix(packages []*parse.Package) string { + if len(packages) < 2 { + return "" + } + + prefixLength := 0 + for prefixLength = 0; prefixLength < len(packages[0].Summary.Package); prefixLength++ { + for i := 0; i < len(packages); i++ { + if len(packages[i].Summary.Package) == (prefixLength - 1) { + goto End + } + if packages[0].Summary.Package[prefixLength] != packages[i].Summary.Package[prefixLength] { + prefixLength-- + + goto End + } + } + } + +End: + if prefixLength <= 0 { + return "" + } + + prefix := packages[0].Summary.Package[0:prefixLength] + lastSlash := strings.LastIndex(prefix, "/") + if lastSlash >= 0 { + prefix = prefix[0:lastSlash] + } + + return prefix +} + +func shortenPackageName(name string, prefix string, maxLength int, trim bool) string { + if !trim { + return name + } + + if prefix == "" { + dir, name := path.Split(name) + // For SIV-style imports show the last non-versioned path identifer. + // Example: github.com/foo/bar/helper/v3 returns helper/v3 + if dir != "" && versionMajorRe.MatchString(name) { + _, subpath := path.Split(path.Clean(dir)) + name = path.Join(subpath, name) + } + return name + } + + name = strings.TrimPrefix(name, prefix) + name = strings.TrimLeft(name, "/") + name = shortenTestName(name, true, maxLength) + + return name +} diff --git a/internal/app/table_tests.go b/internal/app/table_tests.go index 85e58ae..1e8ca5b 100644 --- a/internal/app/table_tests.go +++ b/internal/app/table_tests.go @@ -2,7 +2,6 @@ package app import ( "fmt" - "path" "regexp" "sort" "strconv" @@ -51,6 +50,8 @@ func (c *consoleWriter) testsTable(packages []*parse.Package, option TestTableOp } tbl.SetHeader(header.toRow()) + packagePrefix := findCommonPackagePrefix(packages) + for i, pkg := range packages { // Discard packages where we cannot generate a sensible test summary. if pkg.NoTestFiles || pkg.NoTests || pkg.HasPanic { @@ -65,7 +66,7 @@ func (c *consoleWriter) testsTable(packages []*parse.Package, option TestTableOp // TODO(mf): why are we sorting this? t.SortEvents() - testName := shortenTestName(t.Name, option.Trim) + testName := shortenTestName(t.Name, option.Trim, 32) status := strings.ToUpper(t.Status().String()) switch t.Status() { @@ -77,13 +78,8 @@ func (c *consoleWriter) testsTable(packages []*parse.Package, option TestTableOp status = c.red(status) } - dir, packageName := path.Split(t.Package) - // For SIV-style imports show the last non-versioned path identifer. - // Example: github.com/foo/bar/helper/v3 returns helper/v3 - if dir != "" && versionMajorRe.MatchString(packageName) { - _, subpath := path.Split(path.Clean(dir)) - packageName = path.Join(subpath, packageName) - } + packageName := shortenPackageName(t.Package, packagePrefix, 16, true) + row := testRow{ status: status, elapsed: strconv.FormatFloat(t.Elapsed(), 'f', 2, 64), @@ -138,7 +134,7 @@ func (c *consoleWriter) testsTableMarkdown(packages []*parse.Package, option Tes // TODO(mf): why are we sorting this? t.SortEvents() - testName := shortenTestName(t.Name, option.Trim) + testName := shortenTestName(t.Name, option.Trim, 32) status := strings.ToUpper(t.Status().String()) switch t.Status() { @@ -203,10 +199,10 @@ func getTestsFromPackages(pkg *parse.Package, option TestTableOptions) *packageT return tests } -func shortenTestName(s string, trim bool) string { +func shortenTestName(s string, trim bool, maxLength int) string { var testName strings.Builder testName.WriteString(s) - if trim && testName.Len() > 32 && strings.Count(testName.String(), "/") > 0 { + if trim && testName.Len() > maxLength && strings.Count(testName.String(), "/") > 0 { testName.Reset() ss := strings.Split(s, "/") testName.WriteString(ss[0] + "\n") diff --git a/main.go b/main.go index f167db4..cdbd819 100644 --- a/main.go +++ b/main.go @@ -130,6 +130,9 @@ func main() { Trim: *smallScreenPtr, Slow: *slowPtr, }, + SummaryTableOptions: app.SummaryTableOptions{ + Trim: *smallScreenPtr, + }, Format: format, Sorter: sorter, ShowNoTests: *showNoTestsPtr,