From 1217358787e9c0fa70c5c5fc7b5450ae01f3ba40 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Tue, 28 May 2024 12:33:25 +1200 Subject: [PATCH] refactor: replace `fatih/color` with `go-pretty` --- go.mod | 7 ++++--- go.sum | 24 +++++++++++++++--------- internal/reporter/report.go | 14 +++++++------- internal/reporter/reporter.go | 6 +++--- main.go | 24 ++++++++++++------------ 5 files changed, 41 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 37b97ca4..b037e850 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,10 @@ go 1.24.6 require ( github.com/BurntSushi/toml v1.5.0 - github.com/fatih/color v1.18.0 github.com/gkampitakis/go-snaps v0.5.15 github.com/google/go-cmp v0.7.0 github.com/google/osv-scalibr v0.4.1-0.20251202121049-5e7e15f4a036 + github.com/jedib0t/go-pretty/v6 v6.7.5 github.com/tidwall/jsonc v0.3.2 golang.org/x/mod v0.30.0 golang.org/x/sync v0.17.0 @@ -21,12 +21,13 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/maruel/natural v1.1.1 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect ) diff --git a/go.sum b/go.sum index 00a6445a..00fa68d7 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= @@ -15,21 +15,27 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/osv-scalibr v0.4.1-0.20251202121049-5e7e15f4a036 h1:a+w+8ZQYYybXPWI1yJD+mXri5fMLcThlP41rIB7XNns= github.com/google/osv-scalibr v0.4.1-0.20251202121049-5e7e15f4a036/go.mod h1:9Ze2W6nQmu1WX2s95ezOAVZhPDbcA6ZGuEHgFT/sQEU= +github.com/jedib0t/go-pretty/v6 v6.7.5 h1:9dJSWTJnsXJVVAbvxIFxeHf/JxoJd7GUl5o3UzhtuiM= +github.com/jedib0t/go-pretty/v6 v6.7.5/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= -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/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -46,10 +52,10 @@ golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -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.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= 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 59e6390c..9dafad4b 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 { @@ -62,14 +62,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(), )) } @@ -93,7 +93,7 @@ func (r Report) describeIgnores() string { return "" } - return color.YellowString( + return text.FgYellow.Sprintf( " (%d %s ignored)", count, Form(count, "was", "were"), @@ -112,7 +112,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, ) } @@ -121,7 +121,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 f3a7adb9..9f311c94 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 { @@ -90,10 +90,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 21ef194e..6216563e 100644 --- a/main.go +++ b/main.go @@ -10,12 +10,12 @@ import ( "slices" "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 @@ -91,11 +91,11 @@ func (dbs OSVDatabases) check(r *reporter.Reporter, lockf lockfile.Lockfile, ign results, err := db.Check(lockf.Packages) if err != nil { - r.PrintErrorf("%s", color.RedString(fmt.Sprintf( + r.PrintErrorf("%s", text.FgRed.Sprintf( " an api error occurred while trying to check the packages listed in %s: %v\n", lockf.FilePath, err, - ))) + )) continue } @@ -160,13 +160,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, ) @@ -175,7 +175,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"), ) } @@ -644,8 +644,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.Sprint(lockf.FilePath), + text.FgYellow.Sprintf("%d", len(lockf.Packages)), reporter.Form(len(lockf.Packages), "package", "packages"), ) @@ -670,7 +670,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"), ) @@ -678,7 +678,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.Sprint(config.FilePath), ignoresStr, ) } @@ -695,7 +695,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.Sprint(db.Name()), desc, ) } @@ -760,7 +760,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.Sprint(configPath), len(vulns), reporter.Form(len(vulns), "vulnerability", "vulnerabilities"), ))