diff --git a/go.mod b/go.mod index ae83d2b2..fc2afbbb 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,14 @@ go 1.21 require ( github.com/BurntSushi/toml v1.3.2 - github.com/fatih/color v1.16.0 github.com/google/go-cmp v0.6.0 + github.com/jedib0t/go-pretty/v6 v6.6.1 golang.org/x/mod v0.14.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - golang.org/x/sys v0.14.0 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + golang.org/x/sys v0.17.0 // indirect ) diff --git a/go.sum b/go.sum index 4edf1962..678baaa2 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,29 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -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/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU= +github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= +github.com/jedib0t/go-pretty/v6 v6.6.1 h1:iJ65Xjb680rHcikRj6DSIbzCex2huitmc7bDtxYVWyc= +github.com/jedib0t/go-pretty/v6 v6.6.1/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +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/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/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.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/reporter/report.go b/internal/reporter/report.go index a1b3284e..965ddd29 100644 --- a/internal/reporter/report.go +++ b/internal/reporter/report.go @@ -4,10 +4,10 @@ import ( "fmt" "strings" - "github.com/fatih/color" "github.com/g-rath/osv-detector/internal" "github.com/g-rath/osv-detector/pkg/database" "github.com/g-rath/osv-detector/pkg/lockfile" + "github.com/jedib0t/go-pretty/v6/text" ) type PackageDetailsWithVulnerabilities struct { @@ -61,14 +61,14 @@ func (r Report) formatLineByLine() string { lines = append(lines, fmt.Sprintf( " %s %s", - color.YellowString("%s@%s", pkg.Name, pkg.Version), - color.RedString("is affected by the following vulnerabilities:"), + text.FgYellow.Sprintf("%s@%s", pkg.Name, pkg.Version), + text.FgRed.Sprintf("is affected by the following vulnerabilities:"), )) for _, vulnerability := range pkg.Vulnerabilities { lines = append(lines, fmt.Sprintf( " %s %s", - color.CyanString("%s:", vulnerability.ID), + text.FgCyan.Sprintf("%s:", vulnerability.ID), vulnerability.Describe(), )) } @@ -92,7 +92,7 @@ func (r Report) describeIgnores() string { return "" } - return color.YellowString( + return text.FgYellow.Sprintf( " (%d %s ignored)", count, Form(count, "was", "were"), @@ -111,7 +111,7 @@ func (r Report) String() string { if count == 0 { return fmt.Sprintf( " %s%s\n", - color.GreenString("no %s vulnerabilities found", word), + text.FgGreen.Sprintf("no %s vulnerabilities found", word), ignoreMsg, ) } @@ -120,7 +120,7 @@ func (r Report) String() string { out += "\n" out += fmt.Sprintf("\n %s%s\n", - color.RedString( + text.FgRed.Sprintf( "%d %s %s found in %s", count, word, diff --git a/internal/reporter/reporter.go b/internal/reporter/reporter.go index a3486455..7abc1ea6 100644 --- a/internal/reporter/reporter.go +++ b/internal/reporter/reporter.go @@ -6,9 +6,9 @@ import ( "fmt" "io" - "github.com/fatih/color" "github.com/g-rath/osv-detector/pkg/database" "github.com/g-rath/osv-detector/pkg/lockfile" + "github.com/jedib0t/go-pretty/v6/text" ) type Reporter struct { @@ -82,10 +82,10 @@ func (r *Reporter) PrintDatabaseLoadErr(err error) { msg := err.Error() if errors.Is(err, database.ErrOfflineDatabaseNotFound) { - msg = color.RedString("no local version of the database was found, and --offline flag was set") + msg = text.FgRed.Sprintf("no local version of the database was found, and --offline flag was set") } - r.PrintErrorf(" %s\n", color.RedString("failed: %s", msg)) + r.PrintErrorf(" %s\n", text.FgRed.Sprintf("failed: %s", msg)) } func (r *Reporter) PrintKnownEcosystems() { diff --git a/main.go b/main.go index af0d62da..c49b0ef6 100644 --- a/main.go +++ b/main.go @@ -10,12 +10,12 @@ import ( "sort" "strings" - "github.com/fatih/color" "github.com/g-rath/osv-detector/internal" "github.com/g-rath/osv-detector/internal/configer" "github.com/g-rath/osv-detector/internal/reporter" "github.com/g-rath/osv-detector/pkg/database" "github.com/g-rath/osv-detector/pkg/lockfile" + "github.com/jedib0t/go-pretty/v6/text" ) // these come from goreleaser @@ -88,11 +88,11 @@ func (dbs OSVDatabases) check(r *reporter.Reporter, lockf lockfile.Lockfile, ign results, err := db.Check(lockf.Packages) if err != nil { - r.PrintErrorf(color.RedString(fmt.Sprintf( + r.PrintErrorf(text.FgRed.Sprintf( " an api error occurred while trying to check the packages listed in %s: %v\n", lockf.FilePath, err, - ))) + )) continue } @@ -157,13 +157,13 @@ func uniqueDBConfigs(configs []*configer.Config) []database.Config { func describeDB(db database.DB) string { switch tt := db.(type) { case *database.APIDB: - return "using batches of " + color.YellowString("%d", tt.BatchSize) + return "using batches of " + text.FgYellow.Sprintf("%d", tt.BatchSize) case *database.ZipDB: count := tt.VulnerabilitiesCount return fmt.Sprintf( "%s %s, including withdrawn - last updated %s", - color.YellowString("%d", count), + text.FgYellow.Sprintf("%d", count), reporter.Form(count, "vulnerability", "vulnerabilities"), tt.UpdatedAt, ) @@ -172,7 +172,7 @@ func describeDB(db database.DB) string { return fmt.Sprintf( "%s %s, including withdrawn", - color.YellowString("%d", count), + text.FgYellow.Sprintf("%d", count), reporter.Form(count, "vulnerability", "vulnerabilities"), ) } @@ -626,8 +626,8 @@ This flag can be passed multiple times to ignore different vulnerabilities`) r.PrintTextf( "%s: found %s %s\n", - color.MagentaString("%s", lockf.FilePath), - color.YellowString("%d", len(lockf.Packages)), + text.FgMagenta.Sprintf(lockf.FilePath), + text.FgYellow.Sprintf("%d", len(lockf.Packages)), reporter.Form(len(lockf.Packages), "package", "packages"), ) @@ -652,7 +652,7 @@ This flag can be passed multiple times to ignore different vulnerabilities`) ignoresStr = "skipping any ignores" } else { ignores = append(ignores, config.Ignore...) - ignoresStr = color.YellowString("%d %s", + ignoresStr = text.FgYellow.Sprintf("%d %s", len(config.Ignore), reporter.Form(len(config.Ignore), "ignore", "ignores"), ) @@ -660,7 +660,7 @@ This flag can be passed multiple times to ignore different vulnerabilities`) r.PrintTextf( " Using config at %s (%s)\n", - color.MagentaString(config.FilePath), + text.FgMagenta.Sprintf(config.FilePath), ignoresStr, ) } @@ -677,7 +677,7 @@ This flag can be passed multiple times to ignore different vulnerabilities`) r.PrintTextf( " Using db %s%s\n", - color.HiCyanString(db.Name()), + text.FgHiCyan.Sprintf(db.Name()), desc, ) } @@ -740,7 +740,7 @@ func writeUpdatedConfigs(r *reporter.Reporter, vulnsPerConfig map[string]map[str if err == nil { lines = append(lines, fmt.Sprintf( "Updated %s with %d %s\n", - color.MagentaString(configPath), + text.FgMagenta.Sprintf(configPath), len(vulns), reporter.Form(len(vulns), "vulnerability", "vulnerabilities"), ))