Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use charmbracelet/lipgloss and remove tablewriter #136

Merged
merged 8 commits into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

- Add a `-follow-output` flag to allow writing go test output directly into a file. This will be
useful (especially in CI jobs) for outputting overly verbose testing output into a file instead of
the standard stream. (#133)
the standard stream. (#134)

| flag combination | `go test` output destination |
| ------------------------ | ---------------------------- |
Expand All @@ -18,6 +18,12 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
| `-follow-output` | Write to file |
| `-follow -follow-output` | Write to file |

- Use [charmbracelet/lipgloss](https://github.com/charmbracelet/lipgloss) for table rendering.
- This will allow for more control over the output and potentially more features in the future.
(#136)
- Minor changes to the output format are expected, but the overall content should remain the same.
If you have any feedback, please let me know.

## [v0.15.0]

- Add `-trimpath` flag, which removes the path prefix from package names in the output, simplifying
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
module github.com/mfridman/tparse

go 1.18
go 1.21

toolchain go1.23.2

require (
github.com/charmbracelet/lipgloss v1.0.0
github.com/mfridman/buildversion v0.3.0
github.com/muesli/termenv v0.15.2
github.com/olekukonko/tablewriter v0.0.5
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a
github.com/stretchr/testify v1.9.0
)

Expand All @@ -16,7 +17,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/sys v0.26.0 // indirect
Expand Down
14 changes: 6 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
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-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
github.com/charmbracelet/x/ansi v0.4.2 h1:0JM6Aj/g/KC154/gOP4vfxun0ff6itogDYk41kof+qk=
github.com/charmbracelet/x/ansi v0.4.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
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/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
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/mfridman/buildversion v0.3.0 h1:hehEX3IbBZJBqquXctUEOWJfIM46P0ku9naK9h1BGuY=
github.com/mfridman/buildversion v0.3.0/go.mod h1:sfXvYxwfmLvkklTJLv9xJ0Wffw57z9ZFOK4KOGJYafU=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
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/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg=
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ=
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/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
Expand Down
45 changes: 45 additions & 0 deletions internal/app/table.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package app

import (
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table"
)

func newTable(
format OutputFormat,
override func(style lipgloss.Style, row, col int) lipgloss.Style,
) *table.Table {
tbl := table.New()
switch format {
case OutputFormatPlain:
tbl.Border(lipgloss.HiddenBorder()).BorderTop(false).BorderBottom(false)
case OutputFormatMarkdown:
tbl.Border(markdownBorder).BorderBottom(false).BorderTop(false)
case OutputFormatBasic:
tbl.Border(lipgloss.RoundedBorder())
}
return tbl.StyleFunc(func(row, col int) lipgloss.Style {
// Default style, may be overridden.
style := lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).Align(lipgloss.Center)
if override != nil {
style = override(style, row, col)
}
return style
})
}

var markdownBorder = lipgloss.Border{
Top: "-",
Bottom: "-",
Left: "|",
Right: "|",
TopLeft: "", // empty for markdown
TopRight: "", // empty for markdown
BottomLeft: "", // empty for markdown
BottomRight: "", // empty for markdown
MiddleLeft: "|",
MiddleRight: "|",
Middle: "|",
MiddleTop: "|",
MiddleBottom: "|",
}
53 changes: 23 additions & 30 deletions internal/app/table_summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/olekukonko/tablewriter"
"github.com/charmbracelet/lipgloss/table"

"github.com/mfridman/tparse/internal/utils"
"github.com/mfridman/tparse/parse"
Expand All @@ -33,16 +33,16 @@ func (c *consoleWriter) summaryTable(
options SummaryTableOptions,
against *parse.GoTestSummary,
) {
var tableString strings.Builder
tbl := newTableWriter(&tableString, c.format)
tbl.SetColumnAlignment([]int{
tablewriter.ALIGN_LEFT,
tablewriter.ALIGN_CENTER,
tablewriter.ALIGN_LEFT,
tablewriter.ALIGN_CENTER,
tablewriter.ALIGN_CENTER,
tablewriter.ALIGN_CENTER,
tablewriter.ALIGN_CENTER,
tbl := newTable(c.format, func(style lipgloss.Style, row, col int) lipgloss.Style {
switch row {
case table.HeaderRow:
default:
if col == 2 {
// Package name
style = style.Align(lipgloss.Left)
}
}
return style
})
header := summaryRow{
status: "Status",
Expand All @@ -53,7 +53,8 @@ func (c *consoleWriter) summaryTable(
fail: "Fail",
skip: "Skip",
}
tbl.SetHeader(header.toRow())
tbl.Headers(header.toRow()...)
data := table.NewStringData()

// Capture as separate slices because notests are optional when passed tests are available.
// The only exception is if passed=0 and notests=1, then we display them regardless. This
Expand All @@ -80,7 +81,7 @@ func (c *consoleWriter) summaryTable(
packageName: packageName,
cover: "--", pass: "--", fail: "--", skip: "--",
}
tbl.Append(row.toRow())
data.Append(row.toRow())
continue
}
if pkg.HasFailedBuildOrSetup {
Expand All @@ -90,7 +91,7 @@ func (c *consoleWriter) summaryTable(
packageName: packageName + "\n[" + pkg.Summary.Output + "]",
cover: "--", pass: "--", fail: "--", skip: "--",
}
tbl.Append(row.toRow())
data.Append(row.toRow())
continue
}
if pkg.NoTestFiles {
Expand Down Expand Up @@ -187,32 +188,24 @@ func (c *consoleWriter) summaryTable(
passed = append(passed, row)
}

if tbl.NumLines() == 0 && len(passed) == 0 && len(notests) == 0 {
if data.Rows() == 0 && len(passed) == 0 && len(notests) == 0 {
return
}

for _, p := range passed {
tbl.Append(p.toRow())
for _, r := range passed {
data.Append(r.toRow())
}

// Only display the "no tests to run" cases if users want to see them when passed
// tests are available.
// An exception is made if there are no passed tests and only a single no test files
// package. This is almost always because the user forgot to match one or more packages.
if showNoTests || (len(passed) == 0 && len(notests) == 1) {
for _, p := range notests {
tbl.Append(p.toRow())
for _, r := range notests {
data.Append(r.toRow())
}
}
// The table gets written to a strings builder so we can further modify the output
// with lipgloss.
tbl.Render()
output := tableString.String()
if c.format == OutputFormatBasic {
output = lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
Render(strings.TrimSuffix(tableString.String(), "\n"))
}
fmt.Fprintln(c.w, output)

fmt.Fprintln(c.w, tbl.Data(data).Render())
}

type summaryRow struct {
Expand Down
76 changes: 45 additions & 31 deletions internal/app/table_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table"

"github.com/mfridman/tparse/internal/utils"
"github.com/mfridman/tparse/parse"
Expand Down Expand Up @@ -44,16 +45,25 @@ type packageTests struct {

func (c *consoleWriter) testsTable(packages []*parse.Package, option TestTableOptions) {
// Print passed tests, sorted by elapsed DESC. Grouped by alphabetically sorted packages.
var tableString strings.Builder
tbl := newTableWriter(&tableString, c.format)

tbl := newTable(c.format, func(style lipgloss.Style, row, col int) lipgloss.Style {
switch row {
case table.HeaderRow:
default:
if col == 2 || col == 3 {
// Test name and package name
style = style.Align(lipgloss.Left)
}
}
return style
})
header := testRow{
status: "Status",
elapsed: "Elapsed",
testName: "Test",
packageName: "Package",
}
tbl.SetHeader(header.toRow())
tbl.Headers(header.toRow()...)
data := table.NewStringData()

names := make([]string, 0, len(packages))
for _, pkg := range packages {
Expand Down Expand Up @@ -95,40 +105,40 @@ func (c *consoleWriter) testsTable(packages []*parse.Package, option TestTableOp
testName: testName,
packageName: packageName,
}
tbl.Append(row.toRow())
data.Append(row.toRow())
}
if i != (len(packages) - 1) {
// TODO(mf): is it possible to add a custom separator with tablewriter instead of empty space?
tbl.Append(testRow{}.toRow())
// Add a blank row between packages.
data.Append(testRow{}.toRow())
}
}

if tbl.NumLines() > 0 {
// The table gets written to a strings builder so we can further modify the output
// with lipgloss.
tbl.Render()
output := tableString.String()
if c.format == OutputFormatBasic {
output = lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
Render(strings.TrimSuffix(output, "\n"))
}
fmt.Fprintln(c.w, output)
if data.Rows() > 0 {
fmt.Fprintln(c.w, tbl.Data(data).Render())
}
}

func (c *consoleWriter) testsTableMarkdown(packages []*parse.Package, option TestTableOptions) {
for _, pkg := range packages {
// Print passed tests, sorted by elapsed DESC. Grouped by alphabetically sorted packages.
var tableString strings.Builder
tbl := newTableWriter(&tableString, c.format)

tbl := newTable(c.format, func(style lipgloss.Style, row, col int) lipgloss.Style {
switch row {
case table.HeaderRow:
default:
if col == 2 {
// Test name
style = style.Align(lipgloss.Left)
}
}
return style
})
header := []string{
"Status",
"Elapsed",
"Test",
}
tbl.SetHeader(header)
tbl.Headers(header...)
data := table.NewStringData()

// Discard packages where we cannot generate a sensible test summary.
if pkg.NoTestFiles || pkg.NoTests || pkg.HasPanic {
Expand All @@ -154,30 +164,34 @@ func (c *consoleWriter) testsTableMarkdown(packages []*parse.Package, option Tes
case parse.ActionFail:
status = c.red(status)
}
tbl.Append([]string{
data.Append([]string{
status,
strconv.FormatFloat(t.Elapsed(), 'f', 2, 64),
testName,
})
}
if tbl.NumLines() > 0 {
tbl.Render()

if data.Rows() > 0 {
fmt.Fprintf(c.w, "## 📦 Package **`%s`**\n", pkg.Summary.Package)
fmt.Fprintln(c.w)
fmt.Fprintf(c.w,
"**%d passed** tests (out of %d) | **%d skipped** tests (out of %d)\n",
len(pkgTests.passed),

msg := fmt.Sprintf("Tests: ✓ %d passed | %d skipped\n",
pkgTests.passedCount,
len(pkgTests.skipped),
pkgTests.skippedCount,
)
if option.Slow > 0 && option.Slow < pkgTests.passedCount {
msg += fmt.Sprintf("↓ Slowest %d passed tests shown (of %d)\n",
option.Slow,
pkgTests.passedCount,
)
}
fmt.Fprint(c.w, msg)

fmt.Fprintln(c.w)
fmt.Fprintln(c.w, "<details>")
fmt.Fprintln(c.w)
fmt.Fprintln(c.w, "<summary>Click for test summary</summary>")
fmt.Fprintln(c.w)
fmt.Fprintln(c.w, tableString.String())
fmt.Fprintln(c.w, tbl.Data(data).Render())
fmt.Fprintln(c.w, "</details>")
fmt.Fprintln(c.w)
}
Expand Down
Loading