From 111ca05483b66fcd548cc9e7d3018f53d289a452 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Wed, 27 Mar 2024 08:25:24 +1300 Subject: [PATCH 01/13] feat: add "vertical" output format --- cmd/osv-scanner/__snapshots__/main_test.snap | 2 +- go.mod | 2 + go.sum | 6 + .../output/__snapshots__/vertical_test.snap | 528 ++++++++++++++++++ internal/output/vertical.go | 135 +++++ internal/output/vertical_test.go | 49 ++ pkg/reporter/format.go | 4 +- pkg/reporter/vertical_reporter.go | 68 +++ pkg/reporter/vertical_reporter_test.go | 98 ++++ 9 files changed, 890 insertions(+), 2 deletions(-) create mode 100755 internal/output/__snapshots__/vertical_test.snap create mode 100644 internal/output/vertical.go create mode 100644 internal/output/vertical_test.go create mode 100644 pkg/reporter/vertical_reporter.go create mode 100644 pkg/reporter/vertical_reporter_test.go diff --git a/cmd/osv-scanner/__snapshots__/main_test.snap b/cmd/osv-scanner/__snapshots__/main_test.snap index d48f890e2e..17f9525d48 100755 --- a/cmd/osv-scanner/__snapshots__/main_test.snap +++ b/cmd/osv-scanner/__snapshots__/main_test.snap @@ -77,7 +77,7 @@ Scanned /fixtures/locks-many/package-lock.json file and found 1 package --- [TestRun/#06 - 2] -unsupported output format "unknown" - must be one of: table, json, markdown, sarif, gh-annotations, cyclonedx-1-4, cyclonedx-1-5 +unsupported output format "unknown" - must be one of: table, vertical, json, markdown, sarif, gh-annotations, cyclonedx-1-4, cyclonedx-1-5 --- diff --git a/go.mod b/go.mod index 9c41de1c1b..66cd33400f 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/charmbracelet/glamour v0.7.0 github.com/charmbracelet/lipgloss v0.11.0 github.com/dghubble/trie v0.1.0 + github.com/fatih/color v1.15.0 github.com/gkampitakis/go-snaps v0.5.4 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 @@ -77,6 +78,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.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-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect diff --git a/go.sum b/go.sum index db1941210d..709677926d 100644 --- a/go.sum +++ b/go.sum @@ -87,6 +87,8 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8= github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= @@ -140,6 +142,9 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 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-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -293,6 +298,7 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap new file mode 100755 index 0000000000..fc93ff8914 --- /dev/null +++ b/internal/output/__snapshots__/vertical_test.snap @@ -0,0 +1,528 @@ + +[TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_no_license_violations - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + +path/to/my/second/lockfile: found 2 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 2 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + +path/to/my/second/lockfile: found 2 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 2 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations#01 - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + +path/to/my/second/lockfile: found 2 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 2 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_some_license_violations - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + +path/to/my/second/lockfile: found 2 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 2 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_and_groups,_some_license_violations - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + +path/to/my/second/lockfile: found 2 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 2 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_no_packages - 1] +path/to/my/first/lockfile: found 0 packages + no known vulnerabilities found + +path/to/my/second/lockfile: found 0 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 0 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/no_sources - 1] + +--- + +[TestPrintVerticalResults_WithLicenseViolations/one_source_with_no_packages - 1] +path/to/my/first/lockfile: found 0 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_license_violations - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_licenses - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_an_unknown_license - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_multiple_license_violations - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation_(dev) - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithLicenseViolations/two_sources_with_packages,_one_license_violation - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + +path/to/my/second/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_called_vulnerabilities_and_license_violations - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 2 packages + + mine2@3.2.5 is affected by the following vulnerabilities: + OSV-2: Something less scary! (https://osv.dev/OSV-2) + + 1 known vulnerability found in path/to/my/second/lockfile + +path/to/my/third/lockfile: found 2 packages + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/third/lockfile + + +--- + +[TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities_and_license_violations - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 2 packages + + mine2@3.2.5 is affected by the following vulnerabilities: + OSV-2: Something less scary! (https://osv.dev/OSV-2) + + 1 known vulnerability found in path/to/my/second/lockfile + +path/to/my/third/lockfile: found 2 packages + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/third/lockfile + + +--- + +[TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_called_vulnerability,_and_one_license_violation - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_license_violation - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_vulnerability,_and_one_license_violation - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithMixedIssues/two_sources_with_packages,_one_vulnerability,_one_license_violation - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_grouped_packages,_and_multiple_vulnerabilities - 1] +path/to/my/first/lockfile: found 2 packages + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + mine1@1.2.2 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 3 known vulnerabilities found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 2 packages + + mine2@3.2.5 is affected by the following vulnerabilities: + OSV-2: Something less scary! (https://osv.dev/OSV-2) + mine3@0.4.1 is affected by the following vulnerabilities: + OSV-3: Something mildly scary! (https://osv.dev/OSV-3) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + + 3 known vulnerabilities found in path/to/my/second/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_and_multiple_vulnerabilities - 1] +path/to/my/first/lockfile: found 2 packages + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + mine1@1.2.2 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 3 known vulnerabilities found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 2 packages + + mine2@3.2.5 is affected by the following vulnerabilities: + OSV-2: Something less scary! (https://osv.dev/OSV-2) + mine3@0.4.1 is affected by the following vulnerabilities: + OSV-3: Something mildly scary! (https://osv.dev/OSV-3) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + + 3 known vulnerabilities found in path/to/my/second/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_no_vulnerabilities - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + +path/to/my/second/lockfile: found 2 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 2 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 2 packages + + mine2@3.2.5 is affected by the following vulnerabilities: + OSV-2: Something less scary! (https://osv.dev/OSV-2) + + 1 known vulnerability found in path/to/my/second/lockfile + +path/to/my/third/lockfile: found 2 packages + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/third/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities - 1] +path/to/my/first/lockfile: found 2 packages + + author1/mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + mine1@1.2.2 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 3 known vulnerabilities found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 2 packages + + mine2@3.2.5 is affected by the following vulnerabilities: + OSV-2: Something less scary! (https://osv.dev/OSV-2) + author3/mine3@0.4.1 is affected by the following vulnerabilities: + OSV-3: Something mildly scary! (https://osv.dev/OSV-3) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + + 3 known vulnerabilities found in path/to/my/second/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities,_but_some_uncalled - 1] +path/to/my/first/lockfile: found 2 packages + + author1/mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + mine1@1.2.2 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 3 known vulnerabilities found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 2 packages + + mine2@3.2.5 is affected by the following vulnerabilities: + OSV-2: Something less scary! (https://osv.dev/OSV-2) + author3/mine3@0.4.1 is affected by the following vulnerabilities: + OSV-3: Something mildly scary! (https://osv.dev/OSV-3) + OSV-5: Something scarier! (https://osv.dev/OSV-5) + + 3 known vulnerabilities found in path/to/my/second/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_no_packages - 1] +path/to/my/first/lockfile: found 0 packages + no known vulnerabilities found + +path/to/my/second/lockfile: found 0 packages + no known vulnerabilities found + +path/to/my/third/lockfile: found 0 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/no_sources - 1] + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_no_packages - 1] +path/to/my/first/lockfile: found 0 packages + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package,_no_vulnerabilities - 1] +path/to/my/first/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_called_vulnerability - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + GHSA-123: Something scarier! (https://osv.dev/GHSA-123) + + 2 known vulnerabilities found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_called_vulnerability - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_uncalled_vulnerability - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability_(dev) - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_uncalled_vulnerability - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + GHSA-123: Something scary! (https://osv.dev/GHSA-123) + + 2 known vulnerabilities found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_vulnerability - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + GHSA-123: Something scary! (https://osv.dev/GHSA-123) + + 2 known vulnerabilities found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/one_source_with_vulnerabilities,_some_missing_content - 1] +path/to/my/first/lockfile: found 2 packages + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: This vulnerability allows for some very scary stuff to happen - seriously,... (https://osv.dev/OSV-1) + mine3@0.10.2-rc is affected by the following vulnerabilities: + OSV-2: (no details available) (https://osv.dev/OSV-2) + + 2 known vulnerabilities found in path/to/my/first/lockfile + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/two_sources_with_packages,_one_vulnerability - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 1 package + no known vulnerabilities found + + +--- + +[TestPrintVerticalResults_WithVulnerabilities/two_sources_with_the_same_vulnerable_package - 1] +path/to/my/first/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/first/lockfile + +path/to/my/second/lockfile: found 1 package + + mine1@1.2.3 is affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 known vulnerability found in path/to/my/second/lockfile + + +--- diff --git a/internal/output/vertical.go b/internal/output/vertical.go new file mode 100644 index 0000000000..ea65095b73 --- /dev/null +++ b/internal/output/vertical.go @@ -0,0 +1,135 @@ +package output + +import ( + "fmt" + "io" + "strings" + "unicode" + + "github.com/fatih/color" + "github.com/google/osv-scanner/pkg/models" +) + +func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) { + for _, result := range vulnResult.Results { + fmt.Fprintln(outputWriter, toString(result)) + } +} + +func countVulnerabilities(result models.PackageSource) int { + count := 0 + + for _, pkg := range result.Packages { + count += len(pkg.Vulnerabilities) + } + + return count +} + +// truncate ensures that the given string is shorter than the provided limit. +// +// If the string is longer than the limit, it's trimmed and suffixed with an ellipsis. +// Ideally the string will be trimmed at the space that's closest to the limit to +// preserve whole words; if a string has no spaces before the limit, it'll be forcefully truncated. +func truncate(str string, limit int) string { + count := 0 + truncateAt := -1 + + for i, c := range str { + if unicode.IsSpace(c) { + truncateAt = i + } + + count++ + + if count >= limit { + // ideally we want to keep words whole when truncating, + // but if we can't find a space just truncate at the limit + if truncateAt == -1 { + truncateAt = limit + } + + return str[:truncateAt] + "..." + } + } + + return str +} + +func describe(vulnerability models.Vulnerability) string { + description := vulnerability.Summary + + if description == "" { + description += truncate(vulnerability.Details, 80) + } + + if description == "" { + description += "(no details available)" + } + + description += " (" + OSVBaseVulnerabilityURL + vulnerability.ID + ")" + + return description +} + +func formatLineByLine(result models.PackageSource) string { + lines := make([]string, 0, len(result.Packages)) + + for _, pkg := range result.Packages { + if len(pkg.Vulnerabilities) == 0 { + continue + } + + lines = append(lines, fmt.Sprintf( + " %s %s", + color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), + color.RedString("is affected by the following vulnerabilities:"), + )) + + for _, vulnerability := range pkg.Vulnerabilities { + lines = append(lines, fmt.Sprintf( + " %s %s", + color.CyanString("%s:", vulnerability.ID), + describe(vulnerability), + )) + } + } + + return strings.Join(lines, "\n") +} + +func toString(result models.PackageSource) string { + count := countVulnerabilities(result) + word := "known" + + out := "" + out += fmt.Sprintf( + "%s: found %s %s\n", + color.MagentaString("%s", result.Source.Path), + color.YellowString("%d", len(result.Packages)), + Form(len(result.Packages), "package", "packages"), + ) + + if count == 0 { + return out + fmt.Sprintf( + " %s\n", + color.GreenString("no %s vulnerabilities found", word), + ) + } + + out += "\n" + out += formatLineByLine(result) + out += "\n" + + out += fmt.Sprintf("\n %s\n", + color.RedString( + "%d %s %s found in %s", + count, + word, + Form(count, "vulnerability", "vulnerabilities"), + result.Source.Path, + ), + ) + + return out +} diff --git a/internal/output/vertical_test.go b/internal/output/vertical_test.go new file mode 100644 index 0000000000..22fe1a9bce --- /dev/null +++ b/internal/output/vertical_test.go @@ -0,0 +1,49 @@ +package output_test + +import ( + "bytes" + "testing" + + "github.com/google/osv-scanner/internal/output" + "github.com/google/osv-scanner/internal/testutility" + "github.com/jedib0t/go-pretty/v6/text" +) + +func TestPrintVerticalResults_WithVulnerabilities(t *testing.T) { + t.Parallel() + + testOutputWithVulnerabilities(t, func(t *testing.T, args outputTestCaseArgs) { + t.Helper() + + outputWriter := &bytes.Buffer{} + output.PrintVerticalResults(args.vulnResult, outputWriter) + + testutility.NewSnapshot().MatchText(t, text.StripEscape(outputWriter.String())) + }) +} + +func TestPrintVerticalResults_WithLicenseViolations(t *testing.T) { + t.Parallel() + + testOutputWithLicenseViolations(t, func(t *testing.T, args outputTestCaseArgs) { + t.Helper() + + outputWriter := &bytes.Buffer{} + output.PrintVerticalResults(args.vulnResult, outputWriter) + + testutility.NewSnapshot().MatchText(t, text.StripEscape(outputWriter.String())) + }) +} + +func TestPrintVerticalResults_WithMixedIssues(t *testing.T) { + t.Parallel() + + testOutputWithMixedIssues(t, func(t *testing.T, args outputTestCaseArgs) { + t.Helper() + + outputWriter := &bytes.Buffer{} + output.PrintVerticalResults(args.vulnResult, outputWriter) + + testutility.NewSnapshot().MatchText(t, text.StripEscape(outputWriter.String())) + }) +} diff --git a/pkg/reporter/format.go b/pkg/reporter/format.go index d6956f76dc..365ff9ca41 100644 --- a/pkg/reporter/format.go +++ b/pkg/reporter/format.go @@ -7,7 +7,7 @@ import ( "github.com/google/osv-scanner/pkg/models" ) -var format = []string{"table", "json", "markdown", "sarif", "gh-annotations", "cyclonedx-1-4", "cyclonedx-1-5"} +var format = []string{"table", "vertical", "json", "markdown", "sarif", "gh-annotations", "cyclonedx-1-4", "cyclonedx-1-5"} func Format() []string { return format @@ -19,6 +19,8 @@ func New(format string, stdout, stderr io.Writer, level VerbosityLevel, terminal switch format { case "json": return NewJSONReporter(stdout, stderr, level), nil + case "vertical": + return NewVerticalReporter(stdout, stderr, level, false, terminalWidth), nil case "table": return NewTableReporter(stdout, stderr, level, false, terminalWidth), nil case "markdown": diff --git a/pkg/reporter/vertical_reporter.go b/pkg/reporter/vertical_reporter.go new file mode 100644 index 0000000000..e5d44c596c --- /dev/null +++ b/pkg/reporter/vertical_reporter.go @@ -0,0 +1,68 @@ +package reporter + +import ( + "fmt" + "io" + + "github.com/google/osv-scanner/internal/output" + "github.com/google/osv-scanner/pkg/models" +) + +type VerticalReporter struct { + hasErrored bool + stdout io.Writer + stderr io.Writer + level VerbosityLevel + markdown bool + // 0 indicates not a terminal output + terminalWidth int +} + +func NewVerticalReporter(stdout io.Writer, stderr io.Writer, level VerbosityLevel, markdown bool, terminalWidth int) *VerticalReporter { + return &VerticalReporter{ + stdout: stdout, + stderr: stderr, + hasErrored: false, + level: level, + markdown: markdown, + terminalWidth: terminalWidth, + } +} + +func (r *VerticalReporter) Errorf(format string, a ...any) { + fmt.Fprintf(r.stderr, format, a...) + r.hasErrored = true +} + +func (r *VerticalReporter) HasErrored() bool { + return r.hasErrored +} + +func (r *VerticalReporter) Warnf(format string, a ...any) { + if WarnLevel <= r.level { + fmt.Fprintf(r.stdout, format, a...) + } +} + +func (r *VerticalReporter) Infof(format string, a ...any) { + if InfoLevel <= r.level { + fmt.Fprintf(r.stdout, format, a...) + } +} + +func (r *VerticalReporter) Verbosef(format string, a ...any) { + if VerboseLevel <= r.level { + fmt.Fprintf(r.stdout, format, a...) + } +} + +func (r *VerticalReporter) PrintResult(vulnResult *models.VulnerabilityResults) error { + if len(vulnResult.Results) == 0 && !r.hasErrored { + fmt.Fprintf(r.stdout, "No issues found\n") + return nil + } + + output.PrintVerticalResults(vulnResult, r.stdout) + + return nil +} diff --git a/pkg/reporter/vertical_reporter_test.go b/pkg/reporter/vertical_reporter_test.go new file mode 100644 index 0000000000..1187e63e0e --- /dev/null +++ b/pkg/reporter/vertical_reporter_test.go @@ -0,0 +1,98 @@ +package reporter_test + +import ( + "bytes" + "io" + "testing" + + "github.com/google/osv-scanner/pkg/reporter" +) + +func TestVerticalReporter_Errorf(t *testing.T) { + t.Parallel() + + writer := &bytes.Buffer{} + r := reporter.NewVerticalReporter(io.Discard, writer, reporter.ErrorLevel, false, 0) + text := "hello world!" + + r.Errorf(text) + + if writer.String() != text { + t.Error("Error level message should have been printed") + } + if !r.HasErrored() { + t.Error("HasErrored() should have returned true") + } +} + +func TestVerticalReporter_Warnf(t *testing.T) { + t.Parallel() + + text := "hello world!" + tests := []struct { + lvl reporter.VerbosityLevel + expectedPrintout string + }{ + {lvl: reporter.WarnLevel, expectedPrintout: text}, + {lvl: reporter.ErrorLevel, expectedPrintout: ""}, + } + + for _, test := range tests { + writer := &bytes.Buffer{} + r := reporter.NewVerticalReporter(writer, io.Discard, test.lvl, false, 0) + + r.Warnf(text) + + if writer.String() != test.expectedPrintout { + t.Errorf("expected \"%s\", got \"%s\"", test.expectedPrintout, writer.String()) + } + } +} + +func TestVerticalReporter_Infof(t *testing.T) { + t.Parallel() + + text := "hello world!" + tests := []struct { + lvl reporter.VerbosityLevel + expectedPrintout string + }{ + {lvl: reporter.InfoLevel, expectedPrintout: text}, + {lvl: reporter.WarnLevel, expectedPrintout: ""}, + } + + for _, test := range tests { + writer := &bytes.Buffer{} + r := reporter.NewVerticalReporter(writer, io.Discard, test.lvl, false, 0) + + r.Infof(text) + + if writer.String() != test.expectedPrintout { + t.Errorf("expected \"%s\", got \"%s\"", test.expectedPrintout, writer.String()) + } + } +} + +func TestVerticalReporter_Verbosef(t *testing.T) { + t.Parallel() + + text := "hello world!" + tests := []struct { + lvl reporter.VerbosityLevel + expectedPrintout string + }{ + {lvl: reporter.VerboseLevel, expectedPrintout: text}, + {lvl: reporter.InfoLevel, expectedPrintout: ""}, + } + + for _, test := range tests { + writer := &bytes.Buffer{} + r := reporter.NewVerticalReporter(writer, io.Discard, test.lvl, false, 0) + + r.Verbosef(text) + + if writer.String() != test.expectedPrintout { + t.Errorf("expected \"%s\", got \"%s\"", test.expectedPrintout, writer.String()) + } + } +} From a50d50e0ce3108eb0c38347484fcbe0ad011bc11 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 29 Mar 2024 08:46:50 +1300 Subject: [PATCH 02/13] refactor: change how vertical printing is done --- .../output/__snapshots__/vertical_test.snap | 69 ---------- internal/output/vertical.go | 122 +++++++++--------- 2 files changed, 58 insertions(+), 133 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index fc93ff8914..30cc5afd05 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -2,79 +2,61 @@ [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_no_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - path/to/my/second/lockfile: found 2 packages no known vulnerabilities found - path/to/my/third/lockfile: found 2 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - path/to/my/second/lockfile: found 2 packages no known vulnerabilities found - path/to/my/third/lockfile: found 2 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations#01 - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - path/to/my/second/lockfile: found 2 packages no known vulnerabilities found - path/to/my/third/lockfile: found 2 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - path/to/my/second/lockfile: found 2 packages no known vulnerabilities found - path/to/my/third/lockfile: found 2 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_and_groups,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - path/to/my/second/lockfile: found 2 packages no known vulnerabilities found - path/to/my/third/lockfile: found 2 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_no_packages - 1] path/to/my/first/lockfile: found 0 packages no known vulnerabilities found - path/to/my/second/lockfile: found 0 packages no known vulnerabilities found - path/to/my/third/lockfile: found 0 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/no_sources - 1] @@ -85,59 +67,50 @@ path/to/my/third/lockfile: found 0 packages path/to/my/first/lockfile: found 0 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_licenses - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_an_unknown_license - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_multiple_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation_(dev) - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithLicenseViolations/two_sources_with_packages,_one_license_violation - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - path/to/my/second/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_called_vulnerabilities_and_license_violations - 1] @@ -147,14 +120,12 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile - path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: @@ -162,7 +133,6 @@ path/to/my/third/lockfile: found 2 packages 1 known vulnerability found in path/to/my/third/lockfile - --- [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities_and_license_violations - 1] @@ -172,14 +142,12 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile - path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: @@ -187,7 +155,6 @@ path/to/my/third/lockfile: found 2 packages 1 known vulnerability found in path/to/my/third/lockfile - --- [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_called_vulnerability,_and_one_license_violation - 1] @@ -198,7 +165,6 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_license_violation - 1] @@ -209,7 +175,6 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_vulnerability,_and_one_license_violation - 1] @@ -220,7 +185,6 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithMixedIssues/two_sources_with_packages,_one_vulnerability,_one_license_violation - 1] @@ -230,11 +194,9 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_grouped_packages,_and_multiple_vulnerabilities - 1] @@ -247,7 +209,6 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -258,7 +219,6 @@ path/to/my/second/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/second/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_and_multiple_vulnerabilities - 1] @@ -271,7 +231,6 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -282,20 +241,16 @@ path/to/my/second/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/second/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_no_vulnerabilities - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - path/to/my/second/lockfile: found 2 packages no known vulnerabilities found - path/to/my/third/lockfile: found 2 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities - 1] @@ -305,14 +260,12 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile - path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: @@ -320,7 +273,6 @@ path/to/my/third/lockfile: found 2 packages 1 known vulnerability found in path/to/my/third/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities - 1] @@ -333,7 +285,6 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -344,7 +295,6 @@ path/to/my/second/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/second/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities,_but_some_uncalled - 1] @@ -357,7 +307,6 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -368,20 +317,16 @@ path/to/my/second/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/second/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_no_packages - 1] path/to/my/first/lockfile: found 0 packages no known vulnerabilities found - path/to/my/second/lockfile: found 0 packages no known vulnerabilities found - path/to/my/third/lockfile: found 0 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithVulnerabilities/no_sources - 1] @@ -392,14 +337,12 @@ path/to/my/third/lockfile: found 0 packages path/to/my/first/lockfile: found 0 packages no known vulnerabilities found - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package,_no_vulnerabilities - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_called_vulnerability - 1] @@ -411,7 +354,6 @@ path/to/my/first/lockfile: found 1 package 2 known vulnerabilities found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_called_vulnerability - 1] @@ -422,7 +364,6 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_uncalled_vulnerability - 1] @@ -433,7 +374,6 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability - 1] @@ -444,7 +384,6 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability_(dev) - 1] @@ -455,7 +394,6 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_uncalled_vulnerability - 1] @@ -467,7 +405,6 @@ path/to/my/first/lockfile: found 1 package 2 known vulnerabilities found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_vulnerability - 1] @@ -479,7 +416,6 @@ path/to/my/first/lockfile: found 1 package 2 known vulnerabilities found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_vulnerabilities,_some_missing_content - 1] @@ -492,7 +428,6 @@ path/to/my/first/lockfile: found 2 packages 2 known vulnerabilities found in path/to/my/first/lockfile - --- [TestPrintVerticalResults_WithVulnerabilities/two_sources_with_packages,_one_vulnerability - 1] @@ -502,11 +437,9 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 1 package no known vulnerabilities found - --- [TestPrintVerticalResults_WithVulnerabilities/two_sources_with_the_same_vulnerable_package - 1] @@ -516,7 +449,6 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile - path/to/my/second/lockfile: found 1 package mine1@1.2.3 is affected by the following vulnerabilities: @@ -524,5 +456,4 @@ path/to/my/second/lockfile: found 1 package 1 known vulnerability found in path/to/my/second/lockfile - --- diff --git a/internal/output/vertical.go b/internal/output/vertical.go index ea65095b73..40a2a2c5e0 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -3,7 +3,6 @@ package output import ( "fmt" "io" - "strings" "unicode" "github.com/fatih/color" @@ -12,10 +11,67 @@ import ( func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) { for _, result := range vulnResult.Results { - fmt.Fprintln(outputWriter, toString(result)) + printVerticalResult(result, outputWriter) } } +func printVerticalResult(result models.PackageSource, out io.Writer) { + fmt.Fprintf( + out, + "%s: found %s %s\n", + color.MagentaString("%s", result.Source.Path), + color.YellowString("%d", len(result.Packages)), + Form(len(result.Packages), "package", "packages"), + ) + + printVerticalVulnerabilities(result, out) +} + +func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { + count := countVulnerabilities(result) + + if count == 0 { + fmt.Fprintf( + out, + " %s\n", + color.GreenString("no known vulnerabilities found"), + ) + + return + } + + fmt.Fprintln(out) + + for _, pkg := range result.Packages { + if len(pkg.Vulnerabilities) == 0 { + continue + } + + fmt.Fprintf(out, + " %s %s\n", + color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), + color.RedString("is affected by the following vulnerabilities:"), + ) + + for _, vulnerability := range pkg.Vulnerabilities { + fmt.Fprintf(out, + " %s %s\n", + color.CyanString("%s:", vulnerability.ID), + describe(vulnerability), + ) + } + } + + fmt.Fprintf(out, "\n %s\n", + color.RedString( + "%d known %s found in %s", + count, + Form(count, "vulnerability", "vulnerabilities"), + result.Source.Path, + ), + ) +} + func countVulnerabilities(result models.PackageSource) int { count := 0 @@ -71,65 +127,3 @@ func describe(vulnerability models.Vulnerability) string { return description } - -func formatLineByLine(result models.PackageSource) string { - lines := make([]string, 0, len(result.Packages)) - - for _, pkg := range result.Packages { - if len(pkg.Vulnerabilities) == 0 { - continue - } - - lines = append(lines, fmt.Sprintf( - " %s %s", - color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), - color.RedString("is affected by the following vulnerabilities:"), - )) - - for _, vulnerability := range pkg.Vulnerabilities { - lines = append(lines, fmt.Sprintf( - " %s %s", - color.CyanString("%s:", vulnerability.ID), - describe(vulnerability), - )) - } - } - - return strings.Join(lines, "\n") -} - -func toString(result models.PackageSource) string { - count := countVulnerabilities(result) - word := "known" - - out := "" - out += fmt.Sprintf( - "%s: found %s %s\n", - color.MagentaString("%s", result.Source.Path), - color.YellowString("%d", len(result.Packages)), - Form(len(result.Packages), "package", "packages"), - ) - - if count == 0 { - return out + fmt.Sprintf( - " %s\n", - color.GreenString("no %s vulnerabilities found", word), - ) - } - - out += "\n" - out += formatLineByLine(result) - out += "\n" - - out += fmt.Sprintf("\n %s\n", - color.RedString( - "%d %s %s found in %s", - count, - word, - Form(count, "vulnerability", "vulnerabilities"), - result.Source.Path, - ), - ) - - return out -} From c0ec374697b9f60dbfb0e41330fb8ad73680b43d Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 25 May 2024 07:46:47 +1200 Subject: [PATCH 03/13] feat: print license violations --- .../output/__snapshots__/vertical_test.snap | 79 +++++++++++++++++++ internal/output/vertical.go | 58 +++++++++++++- 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index 30cc5afd05..fa3de53410 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -2,20 +2,32 @@ [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_no_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + no license violations found path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + no license violations found path/to/my/third/lockfile: found 2 packages no known vulnerabilities found + no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + mine2@3.2.5 is using an incompatible license: Apache-2.0 + + 1 license violation found in path/to/my/second/lockfile path/to/my/third/lockfile: found 2 packages no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/third/lockfile --- @@ -32,30 +44,51 @@ path/to/my/third/lockfile: found 2 packages [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + author1/mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + mine2@3.2.5 is using an incompatible license: Apache-2.0 + + 1 license violation found in path/to/my/second/lockfile path/to/my/third/lockfile: found 2 packages no known vulnerabilities found + author1/mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/third/lockfile --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_and_groups,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + mine2@3.2.5 is using an incompatible license: Apache-2.0 + + 1 license violation found in path/to/my/second/lockfile path/to/my/third/lockfile: found 2 packages no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/third/lockfile --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_no_packages - 1] path/to/my/first/lockfile: found 0 packages no known vulnerabilities found + no license violations found path/to/my/second/lockfile: found 0 packages no known vulnerabilities found + no license violations found path/to/my/third/lockfile: found 0 packages no known vulnerabilities found + no license violations found --- @@ -66,50 +99,67 @@ path/to/my/third/lockfile: found 0 packages [TestPrintVerticalResults_WithLicenseViolations/one_source_with_no_packages - 1] path/to/my/first/lockfile: found 0 packages no known vulnerabilities found + no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_licenses - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_an_unknown_license - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_multiple_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 2 license violations found in path/to/my/first/lockfile --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation_(dev) - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile --- [TestPrintVerticalResults_WithLicenseViolations/two_sources_with_packages,_one_license_violation - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 1 package no known vulnerabilities found + no license violations found --- @@ -120,18 +170,26 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile + no license violations found path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/third/lockfile + mine1@1.3.5 is using an incompatible license: MIT + mine1@1.2.3 is using an incompatible license: Apache-2.0 + + 2 license violations found in path/to/my/third/lockfile --- @@ -142,18 +200,26 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile + no license violations found path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/third/lockfile + mine1@1.3.5 is using an incompatible license: MIT + mine1@1.2.3 is using an incompatible license: Apache-2.0 + + 2 license violations found in path/to/my/third/lockfile --- @@ -164,6 +230,9 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile --- @@ -174,6 +243,9 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile --- @@ -184,6 +256,9 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT + + 1 license violation found in path/to/my/first/lockfile --- @@ -194,8 +269,12 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + no license violations found path/to/my/second/lockfile: found 1 package no known vulnerabilities found + mine2@5.9.0 is using an incompatible license: MIT + + 1 license violation found in path/to/my/second/lockfile --- diff --git a/internal/output/vertical.go b/internal/output/vertical.go index 40a2a2c5e0..8c13e0d1c3 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -11,11 +11,16 @@ import ( func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) { for _, result := range vulnResult.Results { - printVerticalResult(result, outputWriter) + printVerticalHeader(result, outputWriter) + printVerticalVulnerabilities(result, outputWriter) + + if len(vulnResult.ExperimentalAnalysisConfig.Licenses.Allowlist) > 0 { + printVerticalLicenseViolations(result, outputWriter) + } } } -func printVerticalResult(result models.PackageSource, out io.Writer) { +func printVerticalHeader(result models.PackageSource, out io.Writer) { fmt.Fprintf( out, "%s: found %s %s\n", @@ -23,8 +28,6 @@ func printVerticalResult(result models.PackageSource, out io.Writer) { color.YellowString("%d", len(result.Packages)), Form(len(result.Packages), "package", "packages"), ) - - printVerticalVulnerabilities(result, out) } func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { @@ -72,6 +75,43 @@ func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { ) } +func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) { + count := countLicenseViolations(result) + + if count == 0 { + fmt.Fprintf( + out, + " %s\n", + color.GreenString("no license violations found"), + ) + + return + } + + for _, pkg := range result.Packages { + if len(pkg.LicenseViolations) == 0 { + continue + } + + fmt.Fprintf(out, + " %s %s %s\n", + color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), + color.RedString("is using an incompatible license:"), + // todo: handle multiple licenses + color.CyanString(string(pkg.LicenseViolations[0])), + ) + } + + fmt.Fprintf(out, "\n %s\n", + color.RedString( + "%d license %s found in %s", + count, + Form(count, "violation", "violations"), + result.Source.Path, + ), + ) +} + func countVulnerabilities(result models.PackageSource) int { count := 0 @@ -82,6 +122,16 @@ func countVulnerabilities(result models.PackageSource) int { return count } +func countLicenseViolations(result models.PackageSource) int { + count := 0 + + for _, pkg := range result.Packages { + count += len(pkg.LicenseViolations) + } + + return count +} + // truncate ensures that the given string is shorter than the provided limit. // // If the string is longer than the limit, it's trimmed and suffixed with an ellipsis. From 616071567ef1d82ef76738c6640dfee938c20a59 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 25 May 2024 07:47:05 +1200 Subject: [PATCH 04/13] fix: support multiple license violations --- internal/output/__snapshots__/vertical_test.snap | 2 +- internal/output/vertical.go | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index fa3de53410..6770edbaaa 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -127,7 +127,7 @@ path/to/my/first/lockfile: found 1 package [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_multiple_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + mine1@1.2.3 is using incompatible licenses: MIT, Apache-2.0 2 license violations found in path/to/my/first/lockfile diff --git a/internal/output/vertical.go b/internal/output/vertical.go index 8c13e0d1c3..c050d8c3fa 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -3,6 +3,7 @@ package output import ( "fmt" "io" + "strings" "unicode" "github.com/fatih/color" @@ -93,12 +94,19 @@ func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) continue } + violations := make([]string, len(pkg.LicenseViolations)) + for i, l := range pkg.LicenseViolations { + violations[i] = string(l) + } + fmt.Fprintf(out, " %s %s %s\n", color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), - color.RedString("is using an incompatible license:"), - // todo: handle multiple licenses - color.CyanString(string(pkg.LicenseViolations[0])), + color.RedString(Form(len(violations), + "is using an incompatible license:", + "is using incompatible licenses:", + )), + color.CyanString(strings.Join(violations, ", ")), ) } From 83257cf9cc9e72d6e88c2aaf90c95bc46b04473e Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 25 May 2024 07:47:17 +1200 Subject: [PATCH 05/13] fix: add some spacing to vertical output blocks --- .../output/__snapshots__/vertical_test.snap | 51 +++++++++++++++++++ internal/output/vertical.go | 8 ++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index 6770edbaaa..b752fedbb1 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -3,9 +3,11 @@ path/to/my/first/lockfile: found 1 package no known vulnerabilities found no license violations found + path/to/my/second/lockfile: found 2 packages no known vulnerabilities found no license violations found + path/to/my/third/lockfile: found 2 packages no known vulnerabilities found no license violations found @@ -15,16 +17,21 @@ path/to/my/third/lockfile: found 2 packages [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + mine2@3.2.5 is using an incompatible license: Apache-2.0 1 license violation found in path/to/my/second/lockfile + path/to/my/third/lockfile: found 2 packages no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/third/lockfile @@ -34,8 +41,10 @@ path/to/my/third/lockfile: found 2 packages [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations#01 - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + path/to/my/third/lockfile: found 2 packages no known vulnerabilities found @@ -44,16 +53,21 @@ path/to/my/third/lockfile: found 2 packages [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + author1/mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + mine2@3.2.5 is using an incompatible license: Apache-2.0 1 license violation found in path/to/my/second/lockfile + path/to/my/third/lockfile: found 2 packages no known vulnerabilities found + author1/mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/third/lockfile @@ -63,16 +77,21 @@ path/to/my/third/lockfile: found 2 packages [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_and_groups,_some_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + mine2@3.2.5 is using an incompatible license: Apache-2.0 1 license violation found in path/to/my/second/lockfile + path/to/my/third/lockfile: found 2 packages no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/third/lockfile @@ -83,9 +102,11 @@ path/to/my/third/lockfile: found 2 packages path/to/my/first/lockfile: found 0 packages no known vulnerabilities found no license violations found + path/to/my/second/lockfile: found 0 packages no known vulnerabilities found no license violations found + path/to/my/third/lockfile: found 0 packages no known vulnerabilities found no license violations found @@ -127,6 +148,7 @@ path/to/my/first/lockfile: found 1 package [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_multiple_license_violations - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using incompatible licenses: MIT, Apache-2.0 2 license violations found in path/to/my/first/lockfile @@ -136,6 +158,7 @@ path/to/my/first/lockfile: found 1 package [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile @@ -145,6 +168,7 @@ path/to/my/first/lockfile: found 1 package [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation_(dev) - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile @@ -154,9 +178,11 @@ path/to/my/first/lockfile: found 1 package [TestPrintVerticalResults_WithLicenseViolations/two_sources_with_packages,_one_license_violation - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 1 package no known vulnerabilities found no license violations found @@ -170,9 +196,11 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -180,12 +208,14 @@ path/to/my/second/lockfile: found 2 packages 1 known vulnerability found in path/to/my/second/lockfile no license violations found + path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/third/lockfile + mine1@1.3.5 is using an incompatible license: MIT mine1@1.2.3 is using an incompatible license: Apache-2.0 @@ -200,9 +230,11 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -210,12 +242,14 @@ path/to/my/second/lockfile: found 2 packages 1 known vulnerability found in path/to/my/second/lockfile no license violations found + path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/third/lockfile + mine1@1.3.5 is using an incompatible license: MIT mine1@1.2.3 is using an incompatible license: Apache-2.0 @@ -230,6 +264,7 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile @@ -243,6 +278,7 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile @@ -256,6 +292,7 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile @@ -270,8 +307,10 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile no license violations found + path/to/my/second/lockfile: found 1 package no known vulnerabilities found + mine2@5.9.0 is using an incompatible license: MIT 1 license violation found in path/to/my/second/lockfile @@ -288,6 +327,7 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -310,6 +350,7 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -325,8 +366,10 @@ path/to/my/second/lockfile: found 2 packages [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_no_vulnerabilities - 1] path/to/my/first/lockfile: found 1 package no known vulnerabilities found + path/to/my/second/lockfile: found 2 packages no known vulnerabilities found + path/to/my/third/lockfile: found 2 packages no known vulnerabilities found @@ -339,12 +382,14 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile + path/to/my/third/lockfile: found 2 packages mine1@1.2.3 is affected by the following vulnerabilities: @@ -364,6 +409,7 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -386,6 +432,7 @@ path/to/my/first/lockfile: found 2 packages OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages mine2@3.2.5 is affected by the following vulnerabilities: @@ -401,8 +448,10 @@ path/to/my/second/lockfile: found 2 packages [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_no_packages - 1] path/to/my/first/lockfile: found 0 packages no known vulnerabilities found + path/to/my/second/lockfile: found 0 packages no known vulnerabilities found + path/to/my/third/lockfile: found 0 packages no known vulnerabilities found @@ -516,6 +565,7 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 1 package no known vulnerabilities found @@ -528,6 +578,7 @@ path/to/my/first/lockfile: found 1 package OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 1 package mine1@1.2.3 is affected by the following vulnerabilities: diff --git a/internal/output/vertical.go b/internal/output/vertical.go index c050d8c3fa..aa10120a37 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -11,13 +11,17 @@ import ( ) func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) { - for _, result := range vulnResult.Results { + for i, result := range vulnResult.Results { printVerticalHeader(result, outputWriter) printVerticalVulnerabilities(result, outputWriter) if len(vulnResult.ExperimentalAnalysisConfig.Licenses.Allowlist) > 0 { printVerticalLicenseViolations(result, outputWriter) } + + if i < len(vulnResult.Results) - 1 { + fmt.Fprintln(outputWriter) + } } } @@ -89,6 +93,8 @@ func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) return } + fmt.Fprintln(out) + for _, pkg := range result.Packages { if len(pkg.LicenseViolations) == 0 { continue From a21df506208da70a462683d4e10a0c98d9a0030c Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 25 May 2024 07:47:30 +1200 Subject: [PATCH 06/13] fix: specify the count of packages is of those "with issues" --- .../output/__snapshots__/vertical_test.snap | 138 +++++++++--------- internal/output/vertical.go | 2 +- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index b752fedbb1..4bbf355c4b 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -1,35 +1,35 @@ [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_no_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found no license violations found -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found no license violations found -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found mine2@3.2.5 is using an incompatible license: Apache-2.0 1 license violation found in path/to/my/second/lockfile -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found mine1@1.2.3 is using an incompatible license: MIT @@ -39,33 +39,33 @@ path/to/my/third/lockfile: found 2 packages --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages,_some_license_violations#01 - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_some_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found author1/mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found mine2@3.2.5 is using an incompatible license: Apache-2.0 1 license violation found in path/to/my/second/lockfile -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found author1/mine1@1.2.3 is using an incompatible license: MIT @@ -75,21 +75,21 @@ path/to/my/third/lockfile: found 2 packages --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_a_mixed_count_of_packages_and_groups,_some_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found mine2@3.2.5 is using an incompatible license: Apache-2.0 1 license violation found in path/to/my/second/lockfile -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found mine1@1.2.3 is using an incompatible license: MIT @@ -99,15 +99,15 @@ path/to/my/third/lockfile: found 2 packages --- [TestPrintVerticalResults_WithLicenseViolations/multiple_sources_with_no_packages - 1] -path/to/my/first/lockfile: found 0 packages +path/to/my/first/lockfile: found 0 packages with issues no known vulnerabilities found no license violations found -path/to/my/second/lockfile: found 0 packages +path/to/my/second/lockfile: found 0 packages with issues no known vulnerabilities found no license violations found -path/to/my/third/lockfile: found 0 packages +path/to/my/third/lockfile: found 0 packages with issues no known vulnerabilities found no license violations found @@ -118,35 +118,35 @@ path/to/my/third/lockfile: found 0 packages --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_no_packages - 1] -path/to/my/first/lockfile: found 0 packages +path/to/my/first/lockfile: found 0 packages with issues no known vulnerabilities found no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package,_no_licenses - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_an_unknown_license - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found no license violations found --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_multiple_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found mine1@1.2.3 is using incompatible licenses: MIT, Apache-2.0 @@ -156,7 +156,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found mine1@1.2.3 is using an incompatible license: MIT @@ -166,7 +166,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithLicenseViolations/one_source_with_one_package_and_one_license_violation_(dev) - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found mine1@1.2.3 is using an incompatible license: MIT @@ -176,21 +176,21 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithLicenseViolations/two_sources_with_packages,_one_license_violation - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found mine1@1.2.3 is using an incompatible license: MIT 1 license violation found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 1 package +path/to/my/second/lockfile: found 1 package with issues no known vulnerabilities found no license violations found --- [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_called_vulnerabilities_and_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -201,7 +201,7 @@ path/to/my/first/lockfile: found 1 package 1 license violation found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) @@ -209,7 +209,7 @@ path/to/my/second/lockfile: found 2 packages 1 known vulnerability found in path/to/my/second/lockfile no license violations found -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -224,7 +224,7 @@ path/to/my/third/lockfile: found 2 packages --- [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities_and_license_violations - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -235,7 +235,7 @@ path/to/my/first/lockfile: found 1 package 1 license violation found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) @@ -243,7 +243,7 @@ path/to/my/second/lockfile: found 2 packages 1 known vulnerability found in path/to/my/second/lockfile no license violations found -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -258,7 +258,7 @@ path/to/my/third/lockfile: found 2 packages --- [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_called_vulnerability,_and_one_license_violation - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -272,7 +272,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_license_violation - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -286,7 +286,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_vulnerability,_and_one_license_violation - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -300,7 +300,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithMixedIssues/two_sources_with_packages,_one_vulnerability,_one_license_violation - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -308,7 +308,7 @@ path/to/my/first/lockfile: found 1 package 1 known vulnerability found in path/to/my/first/lockfile no license violations found -path/to/my/second/lockfile: found 1 package +path/to/my/second/lockfile: found 1 package with issues no known vulnerabilities found mine2@5.9.0 is using an incompatible license: MIT @@ -318,7 +318,7 @@ path/to/my/second/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_grouped_packages,_and_multiple_vulnerabilities - 1] -path/to/my/first/lockfile: found 2 packages +path/to/my/first/lockfile: found 2 packages with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -328,7 +328,7 @@ path/to/my/first/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) @@ -341,7 +341,7 @@ path/to/my/second/lockfile: found 2 packages --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_and_multiple_vulnerabilities - 1] -path/to/my/first/lockfile: found 2 packages +path/to/my/first/lockfile: found 2 packages with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -351,7 +351,7 @@ path/to/my/first/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) @@ -364,33 +364,33 @@ path/to/my/second/lockfile: found 2 packages --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_no_vulnerabilities - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile -path/to/my/third/lockfile: found 2 packages +path/to/my/third/lockfile: found 2 packages with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -400,7 +400,7 @@ path/to/my/third/lockfile: found 2 packages --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities - 1] -path/to/my/first/lockfile: found 2 packages +path/to/my/first/lockfile: found 2 packages with issues author1/mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -410,7 +410,7 @@ path/to/my/first/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) @@ -423,7 +423,7 @@ path/to/my/second/lockfile: found 2 packages --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities,_but_some_uncalled - 1] -path/to/my/first/lockfile: found 2 packages +path/to/my/first/lockfile: found 2 packages with issues author1/mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -433,7 +433,7 @@ path/to/my/first/lockfile: found 2 packages 3 known vulnerabilities found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 2 packages +path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) @@ -446,13 +446,13 @@ path/to/my/second/lockfile: found 2 packages --- [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_no_packages - 1] -path/to/my/first/lockfile: found 0 packages +path/to/my/first/lockfile: found 0 packages with issues no known vulnerabilities found -path/to/my/second/lockfile: found 0 packages +path/to/my/second/lockfile: found 0 packages with issues no known vulnerabilities found -path/to/my/third/lockfile: found 0 packages +path/to/my/third/lockfile: found 0 packages with issues no known vulnerabilities found --- @@ -462,19 +462,19 @@ path/to/my/third/lockfile: found 0 packages --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_no_packages - 1] -path/to/my/first/lockfile: found 0 packages +path/to/my/first/lockfile: found 0 packages with issues no known vulnerabilities found --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package,_no_vulnerabilities - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_called_vulnerability - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -485,7 +485,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_called_vulnerability - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -495,7 +495,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_uncalled_vulnerability - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -505,7 +505,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -515,7 +515,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability_(dev) - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -525,7 +525,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_uncalled_vulnerability - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -536,7 +536,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_vulnerability - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) @@ -547,7 +547,7 @@ path/to/my/first/lockfile: found 1 package --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_vulnerabilities,_some_missing_content - 1] -path/to/my/first/lockfile: found 2 packages +path/to/my/first/lockfile: found 2 packages with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: This vulnerability allows for some very scary stuff to happen - seriously,... (https://osv.dev/OSV-1) @@ -559,27 +559,27 @@ path/to/my/first/lockfile: found 2 packages --- [TestPrintVerticalResults_WithVulnerabilities/two_sources_with_packages,_one_vulnerability - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 1 package +path/to/my/second/lockfile: found 1 package with issues no known vulnerabilities found --- [TestPrintVerticalResults_WithVulnerabilities/two_sources_with_the_same_vulnerable_package - 1] -path/to/my/first/lockfile: found 1 package +path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile -path/to/my/second/lockfile: found 1 package +path/to/my/second/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) diff --git a/internal/output/vertical.go b/internal/output/vertical.go index aa10120a37..c73dc301c7 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -28,7 +28,7 @@ func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter func printVerticalHeader(result models.PackageSource, out io.Writer) { fmt.Fprintf( out, - "%s: found %s %s\n", + "%s: found %s %s with issues\n", color.MagentaString("%s", result.Source.Path), color.YellowString("%d", len(result.Packages)), Form(len(result.Packages), "package", "packages"), From 82381c5dcb55f9f8b3708f6af83c74587155c3ea Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 25 May 2024 07:47:44 +1200 Subject: [PATCH 07/13] feat: restructure how license violations are printed to be more consistent --- .../output/__snapshots__/vertical_test.snap | 67 ++++++++++++------- internal/output/vertical.go | 10 +-- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index 4bbf355c4b..2f9838895a 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -18,21 +18,24 @@ path/to/my/third/lockfile: found 2 packages with issues path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found - mine2@3.2.5 is using an incompatible license: Apache-2.0 + license violations found: + mine2@3.2.5 (Apache-2.0) 1 license violation found in path/to/my/second/lockfile path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/third/lockfile @@ -54,21 +57,24 @@ path/to/my/third/lockfile: found 2 packages with issues path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found - author1/mine1@1.2.3 is using an incompatible license: MIT + license violations found: + author1/mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found - mine2@3.2.5 is using an incompatible license: Apache-2.0 + license violations found: + mine2@3.2.5 (Apache-2.0) 1 license violation found in path/to/my/second/lockfile path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found - author1/mine1@1.2.3 is using an incompatible license: MIT + license violations found: + author1/mine1@1.2.3 (MIT) 1 license violation found in path/to/my/third/lockfile @@ -78,21 +84,24 @@ path/to/my/third/lockfile: found 2 packages with issues path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues no known vulnerabilities found - mine2@3.2.5 is using an incompatible license: Apache-2.0 + license violations found: + mine2@3.2.5 (Apache-2.0) 1 license violation found in path/to/my/second/lockfile path/to/my/third/lockfile: found 2 packages with issues no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/third/lockfile @@ -149,7 +158,8 @@ path/to/my/first/lockfile: found 1 package with issues path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found - mine1@1.2.3 is using incompatible licenses: MIT, Apache-2.0 + license violations found: + mine1@1.2.3 (MIT, Apache-2.0) 2 license violations found in path/to/my/first/lockfile @@ -159,7 +169,8 @@ path/to/my/first/lockfile: found 1 package with issues path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -169,7 +180,8 @@ path/to/my/first/lockfile: found 1 package with issues path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -179,7 +191,8 @@ path/to/my/first/lockfile: found 1 package with issues path/to/my/first/lockfile: found 1 package with issues no known vulnerabilities found - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -197,7 +210,8 @@ path/to/my/first/lockfile: found 1 package with issues 1 known vulnerability found in path/to/my/first/lockfile - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -216,8 +230,9 @@ path/to/my/third/lockfile: found 2 packages with issues 1 known vulnerability found in path/to/my/third/lockfile - mine1@1.3.5 is using an incompatible license: MIT - mine1@1.2.3 is using an incompatible license: Apache-2.0 + license violations found: + mine1@1.3.5 (MIT) + mine1@1.2.3 (Apache-2.0) 2 license violations found in path/to/my/third/lockfile @@ -231,7 +246,8 @@ path/to/my/first/lockfile: found 1 package with issues 1 known vulnerability found in path/to/my/first/lockfile - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -250,8 +266,9 @@ path/to/my/third/lockfile: found 2 packages with issues 1 known vulnerability found in path/to/my/third/lockfile - mine1@1.3.5 is using an incompatible license: MIT - mine1@1.2.3 is using an incompatible license: Apache-2.0 + license violations found: + mine1@1.3.5 (MIT) + mine1@1.2.3 (Apache-2.0) 2 license violations found in path/to/my/third/lockfile @@ -265,7 +282,8 @@ path/to/my/first/lockfile: found 1 package with issues 1 known vulnerability found in path/to/my/first/lockfile - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -279,7 +297,8 @@ path/to/my/first/lockfile: found 1 package with issues 1 known vulnerability found in path/to/my/first/lockfile - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -293,7 +312,8 @@ path/to/my/first/lockfile: found 1 package with issues 1 known vulnerability found in path/to/my/first/lockfile - mine1@1.2.3 is using an incompatible license: MIT + license violations found: + mine1@1.2.3 (MIT) 1 license violation found in path/to/my/first/lockfile @@ -311,7 +331,8 @@ path/to/my/first/lockfile: found 1 package with issues path/to/my/second/lockfile: found 1 package with issues no known vulnerabilities found - mine2@5.9.0 is using an incompatible license: MIT + license violations found: + mine2@5.9.0 (MIT) 1 license violation found in path/to/my/second/lockfile diff --git a/internal/output/vertical.go b/internal/output/vertical.go index c73dc301c7..7e6604ce2f 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -19,7 +19,7 @@ func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter printVerticalLicenseViolations(result, outputWriter) } - if i < len(vulnResult.Results) - 1 { + if i < len(vulnResult.Results)-1 { fmt.Fprintln(outputWriter) } } @@ -93,7 +93,7 @@ func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) return } - fmt.Fprintln(out) + fmt.Fprintf(out, "\n %s\n", color.RedString("license violations found:")) for _, pkg := range result.Packages { if len(pkg.LicenseViolations) == 0 { @@ -106,12 +106,8 @@ func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) } fmt.Fprintf(out, - " %s %s %s\n", + " %s (%s)\n", color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), - color.RedString(Form(len(violations), - "is using an incompatible license:", - "is using incompatible licenses:", - )), color.CyanString(strings.Join(violations, ", ")), ) } From 0a615f25311c0e9e595ed01eb1ced879ad9a6c2b Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Tue, 28 May 2024 12:22:42 +1200 Subject: [PATCH 08/13] refactor: replace `fatih/color` with `go-pretty` --- go.mod | 2 -- go.sum | 6 ------ internal/output/vertical.go | 26 +++++++++++++------------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 66cd33400f..9c41de1c1b 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( github.com/charmbracelet/glamour v0.7.0 github.com/charmbracelet/lipgloss v0.11.0 github.com/dghubble/trie v0.1.0 - github.com/fatih/color v1.15.0 github.com/gkampitakis/go-snaps v0.5.4 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 @@ -78,7 +77,6 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.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-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect diff --git a/go.sum b/go.sum index 709677926d..db1941210d 100644 --- a/go.sum +++ b/go.sum @@ -87,8 +87,6 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8= github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= @@ -142,9 +140,6 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 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-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -298,7 +293,6 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/output/vertical.go b/internal/output/vertical.go index 7e6604ce2f..4b24c3d461 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -6,8 +6,8 @@ import ( "strings" "unicode" - "github.com/fatih/color" "github.com/google/osv-scanner/pkg/models" + "github.com/jedib0t/go-pretty/v6/text" ) func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) { @@ -29,8 +29,8 @@ func printVerticalHeader(result models.PackageSource, out io.Writer) { fmt.Fprintf( out, "%s: found %s %s with issues\n", - color.MagentaString("%s", result.Source.Path), - color.YellowString("%d", len(result.Packages)), + text.FgMagenta.Sprintf("%s", result.Source.Path), + text.FgYellow.Sprintf("%d", len(result.Packages)), Form(len(result.Packages), "package", "packages"), ) } @@ -42,7 +42,7 @@ func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { fmt.Fprintf( out, " %s\n", - color.GreenString("no known vulnerabilities found"), + text.FgGreen.Sprintf("no known vulnerabilities found"), ) return @@ -57,21 +57,21 @@ func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { fmt.Fprintf(out, " %s %s\n", - color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), - color.RedString("is affected by the following vulnerabilities:"), + text.FgYellow.Sprintf("%s@%s", pkg.Package.Name, pkg.Package.Version), + text.FgRed.Sprintf("is affected by the following vulnerabilities:"), ) for _, vulnerability := range pkg.Vulnerabilities { fmt.Fprintf(out, " %s %s\n", - color.CyanString("%s:", vulnerability.ID), + text.FgCyan.Sprintf("%s:", vulnerability.ID), describe(vulnerability), ) } } fmt.Fprintf(out, "\n %s\n", - color.RedString( + text.FgRed.Sprintf( "%d known %s found in %s", count, Form(count, "vulnerability", "vulnerabilities"), @@ -87,13 +87,13 @@ func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) fmt.Fprintf( out, " %s\n", - color.GreenString("no license violations found"), + text.FgGreen.Sprintf("no license violations found"), ) return } - fmt.Fprintf(out, "\n %s\n", color.RedString("license violations found:")) + fmt.Fprintf(out, "\n %s\n", text.FgRed.Sprintf("license violations found:")) for _, pkg := range result.Packages { if len(pkg.LicenseViolations) == 0 { @@ -107,13 +107,13 @@ func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) fmt.Fprintf(out, " %s (%s)\n", - color.YellowString("%s@%s", pkg.Package.Name, pkg.Package.Version), - color.CyanString(strings.Join(violations, ", ")), + text.FgYellow.Sprintf("%s@%s", pkg.Package.Name, pkg.Package.Version), + text.FgCyan.Sprintf(strings.Join(violations, ", ")), ) } fmt.Fprintf(out, "\n %s\n", - color.RedString( + text.FgRed.Sprintf( "%d license %s found in %s", count, Form(count, "violation", "violations"), From 85f44e3605283803481bbb3f53bbf2156bbea425 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Tue, 2 Jul 2024 16:35:14 +1200 Subject: [PATCH 09/13] fix: disable color output if we're not being called from a terminal --- pkg/reporter/vertical_reporter.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/reporter/vertical_reporter.go b/pkg/reporter/vertical_reporter.go index e5d44c596c..755c9809f7 100644 --- a/pkg/reporter/vertical_reporter.go +++ b/pkg/reporter/vertical_reporter.go @@ -6,6 +6,7 @@ import ( "github.com/google/osv-scanner/internal/output" "github.com/google/osv-scanner/pkg/models" + "github.com/jedib0t/go-pretty/v6/text" ) type VerticalReporter struct { @@ -62,6 +63,10 @@ func (r *VerticalReporter) PrintResult(vulnResult *models.VulnerabilityResults) return nil } + if r.terminalWidth <= 0 { + text.DisableColors() + } + output.PrintVerticalResults(vulnResult, r.stdout) return nil From 76f25fabdaf6ef484d4032cc07d7dbe96b82b819 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Wed, 3 Jul 2024 12:19:31 +1200 Subject: [PATCH 10/13] fix: omit uncalled vulnerabilities --- .../output/__snapshots__/vertical_test.snap | 37 ++++--------------- internal/output/vertical.go | 36 +++++++++++++++--- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index 2f9838895a..572c13271e 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -204,11 +204,7 @@ path/to/my/second/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_called_vulnerabilities_and_license_violations - 1] path/to/my/first/lockfile: found 1 package with issues - - mine1@1.2.3 is affected by the following vulnerabilities: - OSV-1: Something scary! (https://osv.dev/OSV-1) - - 1 known vulnerability found in path/to/my/first/lockfile + no known vulnerabilities found license violations found: mine1@1.2.3 (MIT) @@ -224,11 +220,7 @@ path/to/my/second/lockfile: found 2 packages with issues no license violations found path/to/my/third/lockfile: found 2 packages with issues - - mine1@1.2.3 is affected by the following vulnerabilities: - OSV-1: Something scary! (https://osv.dev/OSV-1) - - 1 known vulnerability found in path/to/my/third/lockfile + no known vulnerabilities found license violations found: mine1@1.3.5 (MIT) @@ -291,11 +283,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package with issues - - mine1@1.2.3 is affected by the following vulnerabilities: - OSV-1: Something scary! (https://osv.dev/OSV-1) - - 1 known vulnerability found in path/to/my/first/lockfile + no known vulnerabilities found license violations found: mine1@1.2.3 (MIT) @@ -447,12 +435,11 @@ path/to/my/second/lockfile: found 2 packages with issues path/to/my/first/lockfile: found 2 packages with issues author1/mine1@1.2.3 is affected by the following vulnerabilities: - OSV-1: Something scary! (https://osv.dev/OSV-1) OSV-5: Something scarier! (https://osv.dev/OSV-5) mine1@1.2.2 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) - 3 known vulnerabilities found in path/to/my/first/lockfile + 2 known vulnerabilities found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues @@ -499,9 +486,8 @@ path/to/my/first/lockfile: found 1 package with issues mine1@1.2.3 is affected by the following vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) - GHSA-123: Something scarier! (https://osv.dev/GHSA-123) - 2 known vulnerabilities found in path/to/my/first/lockfile + 1 known vulnerability found in path/to/my/first/lockfile --- @@ -517,11 +503,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_uncalled_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - - mine1@1.2.3 is affected by the following vulnerabilities: - OSV-1: Something scary! (https://osv.dev/OSV-1) - - 1 known vulnerability found in path/to/my/first/lockfile + no known vulnerabilities found --- @@ -547,12 +529,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_uncalled_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - - mine1@1.2.3 is affected by the following vulnerabilities: - OSV-1: Something scary! (https://osv.dev/OSV-1) - GHSA-123: Something scary! (https://osv.dev/GHSA-123) - - 2 known vulnerabilities found in path/to/my/first/lockfile + no known vulnerabilities found --- diff --git a/internal/output/vertical.go b/internal/output/vertical.go index 4b24c3d461..6f9d35d41f 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -13,7 +13,7 @@ import ( func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) { for i, result := range vulnResult.Results { printVerticalHeader(result, outputWriter) - printVerticalVulnerabilities(result, outputWriter) + printVerticalVulnerabilities(result, outputWriter, true) if len(vulnResult.ExperimentalAnalysisConfig.Licenses.Allowlist) > 0 { printVerticalLicenseViolations(result, outputWriter) @@ -35,7 +35,27 @@ func printVerticalHeader(result models.PackageSource, out io.Writer) { ) } -func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { +func collectVulns(pkg models.PackageVulns, called bool) []models.Vulnerability { + vulns := make([]models.Vulnerability, 0) + + for _, group := range pkg.Groups { + if group.IsCalled() != called { + continue + } + + for _, ids := range group.IDs { + for _, v := range pkg.Vulnerabilities { + if v.ID == ids { + vulns = append(vulns, v) + } + } + } + } + + return vulns +} + +func printVerticalVulnerabilities(result models.PackageSource, out io.Writer, called bool) { count := countVulnerabilities(result) if count == 0 { @@ -51,7 +71,9 @@ func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { fmt.Fprintln(out) for _, pkg := range result.Packages { - if len(pkg.Vulnerabilities) == 0 { + vulns := collectVulns(pkg, called) + + if len(vulns) == 0 { continue } @@ -61,7 +83,7 @@ func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { text.FgRed.Sprintf("is affected by the following vulnerabilities:"), ) - for _, vulnerability := range pkg.Vulnerabilities { + for _, vulnerability := range vulns { fmt.Fprintf(out, " %s %s\n", text.FgCyan.Sprintf("%s:", vulnerability.ID), @@ -126,7 +148,11 @@ func countVulnerabilities(result models.PackageSource) int { count := 0 for _, pkg := range result.Packages { - count += len(pkg.Vulnerabilities) + for _, g := range pkg.Groups { + if g.IsCalled() { + count += len(g.IDs) + } + } } return count From d89b096343e05025f7a1b401756857aae618caea Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Thu, 11 Jul 2024 07:50:20 +1200 Subject: [PATCH 11/13] fix: include uncalled vulnerabilities in vertical output --- .../output/__snapshots__/vertical_test.snap | 41 ++++++- internal/output/vertical.go | 102 ++++++++++++------ 2 files changed, 103 insertions(+), 40 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index 572c13271e..191540aed3 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -204,7 +204,11 @@ path/to/my/second/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_called_vulnerabilities_and_license_violations - 1] path/to/my/first/lockfile: found 1 package with issues - no known vulnerabilities found + + mine1@1.2.3 may be affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 uncalled vulnerability found in path/to/my/first/lockfile license violations found: mine1@1.2.3 (MIT) @@ -220,7 +224,11 @@ path/to/my/second/lockfile: found 2 packages with issues no license violations found path/to/my/third/lockfile: found 2 packages with issues - no known vulnerabilities found + + mine1@1.2.3 may be affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 uncalled vulnerability found in path/to/my/third/lockfile license violations found: mine1@1.3.5 (MIT) @@ -283,7 +291,11 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package with issues - no known vulnerabilities found + + mine1@1.2.3 may be affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 uncalled vulnerability found in path/to/my/first/lockfile license violations found: mine1@1.2.3 (MIT) @@ -441,6 +453,11 @@ path/to/my/first/lockfile: found 2 packages with issues 2 known vulnerabilities found in path/to/my/first/lockfile + author1/mine1@1.2.3 may be affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 uncalled vulnerability found in path/to/my/first/lockfile + path/to/my/second/lockfile: found 2 packages with issues mine2@3.2.5 is affected by the following vulnerabilities: @@ -489,6 +506,11 @@ path/to/my/first/lockfile: found 1 package with issues 1 known vulnerability found in path/to/my/first/lockfile + mine1@1.2.3 may be affected by the following vulnerabilities: + GHSA-123: Something scarier! (https://osv.dev/GHSA-123) + + 1 uncalled vulnerability found in path/to/my/first/lockfile + --- [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_called_vulnerability - 1] @@ -503,7 +525,11 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_uncalled_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - no known vulnerabilities found + + mine1@1.2.3 may be affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + + 1 uncalled vulnerability found in path/to/my/first/lockfile --- @@ -529,7 +555,12 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_uncalled_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - no known vulnerabilities found + + mine1@1.2.3 may be affected by the following vulnerabilities: + OSV-1: Something scary! (https://osv.dev/OSV-1) + GHSA-123: Something scary! (https://osv.dev/GHSA-123) + + 2 uncalled vulnerabilities found in path/to/my/first/lockfile --- diff --git a/internal/output/vertical.go b/internal/output/vertical.go index 6f9d35d41f..e071db66a6 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -13,7 +13,7 @@ import ( func PrintVerticalResults(vulnResult *models.VulnerabilityResults, outputWriter io.Writer) { for i, result := range vulnResult.Results { printVerticalHeader(result, outputWriter) - printVerticalVulnerabilities(result, outputWriter, true) + printVerticalVulnerabilities(result, outputWriter) if len(vulnResult.ExperimentalAnalysisConfig.Licenses.Allowlist) > 0 { printVerticalLicenseViolations(result, outputWriter) @@ -43,9 +43,9 @@ func collectVulns(pkg models.PackageVulns, called bool) []models.Vulnerability { continue } - for _, ids := range group.IDs { + for _, id := range group.IDs { for _, v := range pkg.Vulnerabilities { - if v.ID == ids { + if v.ID == id { vulns = append(vulns, v) } } @@ -55,32 +55,23 @@ func collectVulns(pkg models.PackageVulns, called bool) []models.Vulnerability { return vulns } -func printVerticalVulnerabilities(result models.PackageSource, out io.Writer, called bool) { - count := countVulnerabilities(result) - - if count == 0 { - fmt.Fprintf( - out, - " %s\n", - text.FgGreen.Sprintf("no known vulnerabilities found"), - ) - - return - } - - fmt.Fprintln(out) - +func printVerticalVulnerabilitiesForPackages(result models.PackageSource, out io.Writer, printingCalled bool) { for _, pkg := range result.Packages { - vulns := collectVulns(pkg, called) + vulns := collectVulns(pkg, printingCalled) if len(vulns) == 0 { continue } + state := "is" + if !printingCalled { + state = "may be" + } + fmt.Fprintf(out, " %s %s\n", text.FgYellow.Sprintf("%s@%s", pkg.Package.Name, pkg.Package.Version), - text.FgRed.Sprintf("is affected by the following vulnerabilities:"), + text.FgRed.Sprintf("%s affected by the following vulnerabilities:", state), ) for _, vulnerability := range vulns { @@ -91,15 +82,50 @@ func printVerticalVulnerabilities(result models.PackageSource, out io.Writer, ca ) } } +} - fmt.Fprintf(out, "\n %s\n", - text.FgRed.Sprintf( - "%d known %s found in %s", - count, - Form(count, "vulnerability", "vulnerabilities"), - result.Source.Path, - ), - ) +func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { + countCalled, countUncalled := countVulnerabilities(result) + + if countCalled == 0 && countUncalled == 0 { + fmt.Fprintf( + out, + " %s\n", + text.FgGreen.Sprintf("no known vulnerabilities found"), + ) + + return + } + + if countCalled > 0 { + fmt.Fprintln(out) + + printVerticalVulnerabilitiesForPackages(result, out, true) + + fmt.Fprintf(out, "\n %s\n", + text.FgRed.Sprintf( + "%d known %s found in %s", + countCalled, + Form(countCalled, "vulnerability", "vulnerabilities"), + result.Source.Path, + ), + ) + } + + if countUncalled > 0 { + fmt.Fprintln(out) + + printVerticalVulnerabilitiesForPackages(result, out, false) + + fmt.Fprintf(out, "\n %s\n", + text.FgRed.Sprintf( + "%d uncalled %s found in %s", + countUncalled, + Form(countUncalled, "vulnerability", "vulnerabilities"), + result.Source.Path, + ), + ) + } } func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) { @@ -144,18 +170,24 @@ func printVerticalLicenseViolations(result models.PackageSource, out io.Writer) ) } -func countVulnerabilities(result models.PackageSource) int { - count := 0 - +func countVulnerabilities(result models.PackageSource) (called int, uncalled int) { for _, pkg := range result.Packages { - for _, g := range pkg.Groups { - if g.IsCalled() { - count += len(g.IDs) + for _, group := range pkg.Groups { + for _, id := range group.IDs { + for _, v := range pkg.Vulnerabilities { + if v.ID == id { + if group.IsCalled() { + called++ + } else { + uncalled++ + } + } + } } } } - return count + return } func countLicenseViolations(result models.PackageSource) int { From d1b1b866ee115f6f27ccb818ea6fa04aa7745151 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Thu, 11 Jul 2024 08:02:16 +1200 Subject: [PATCH 12/13] refactor: pull out vulnerabilities count summary printing into dedicated function --- internal/output/vertical.go | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/internal/output/vertical.go b/internal/output/vertical.go index e071db66a6..f8b4462937 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -35,6 +35,18 @@ func printVerticalHeader(result models.PackageSource, out io.Writer) { ) } +func printVerticalVulnerabilitiesCountSummary(count int, state string, sourcePath string, out io.Writer) { + fmt.Fprintf(out, "\n %s\n", + text.FgRed.Sprintf( + "%d %s %s found in %s", + count, + state, + Form(count, "vulnerability", "vulnerabilities"), + sourcePath, + ), + ) +} + func collectVulns(pkg models.PackageVulns, called bool) []models.Vulnerability { vulns := make([]models.Vulnerability, 0) @@ -101,30 +113,14 @@ func printVerticalVulnerabilities(result models.PackageSource, out io.Writer) { fmt.Fprintln(out) printVerticalVulnerabilitiesForPackages(result, out, true) - - fmt.Fprintf(out, "\n %s\n", - text.FgRed.Sprintf( - "%d known %s found in %s", - countCalled, - Form(countCalled, "vulnerability", "vulnerabilities"), - result.Source.Path, - ), - ) + printVerticalVulnerabilitiesCountSummary(countCalled, "known", result.Source.Path, out) } if countUncalled > 0 { fmt.Fprintln(out) printVerticalVulnerabilitiesForPackages(result, out, false) - - fmt.Fprintf(out, "\n %s\n", - text.FgRed.Sprintf( - "%d uncalled %s found in %s", - countUncalled, - Form(countUncalled, "vulnerability", "vulnerabilities"), - result.Source.Path, - ), - ) + printVerticalVulnerabilitiesCountSummary(countUncalled, "uncalled", result.Source.Path, out) } } From 347ca611bffafaea9a1106716a451540f31d6a60 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Thu, 11 Jul 2024 08:02:32 +1200 Subject: [PATCH 13/13] fix: adjust phrasing of "called" vs "uncalled" vulnerabilities --- .../output/__snapshots__/vertical_test.snap | 86 +++++++++---------- internal/output/vertical.go | 8 +- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/internal/output/__snapshots__/vertical_test.snap b/internal/output/__snapshots__/vertical_test.snap index 191540aed3..4282a97015 100755 --- a/internal/output/__snapshots__/vertical_test.snap +++ b/internal/output/__snapshots__/vertical_test.snap @@ -205,7 +205,7 @@ path/to/my/second/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_called_vulnerabilities_and_license_violations - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 may be affected by the following vulnerabilities: + mine1@1.2.3 has the following uncalled vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 uncalled vulnerability found in path/to/my/first/lockfile @@ -217,7 +217,7 @@ path/to/my/first/lockfile: found 1 package with issues path/to/my/second/lockfile: found 2 packages with issues - mine2@3.2.5 is affected by the following vulnerabilities: + mine2@3.2.5 has the following known vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile @@ -225,7 +225,7 @@ path/to/my/second/lockfile: found 2 packages with issues path/to/my/third/lockfile: found 2 packages with issues - mine1@1.2.3 may be affected by the following vulnerabilities: + mine1@1.2.3 has the following uncalled vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 uncalled vulnerability found in path/to/my/third/lockfile @@ -241,7 +241,7 @@ path/to/my/third/lockfile: found 2 packages with issues [TestPrintVerticalResults_WithMixedIssues/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities_and_license_violations - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -253,7 +253,7 @@ path/to/my/first/lockfile: found 1 package with issues path/to/my/second/lockfile: found 2 packages with issues - mine2@3.2.5 is affected by the following vulnerabilities: + mine2@3.2.5 has the following known vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile @@ -261,7 +261,7 @@ path/to/my/second/lockfile: found 2 packages with issues path/to/my/third/lockfile: found 2 packages with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/third/lockfile @@ -277,7 +277,7 @@ path/to/my/third/lockfile: found 2 packages with issues [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_called_vulnerability,_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -292,7 +292,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 may be affected by the following vulnerabilities: + mine1@1.2.3 has the following uncalled vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 uncalled vulnerability found in path/to/my/first/lockfile @@ -307,7 +307,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/one_source_with_one_package,_one_vulnerability,_and_one_license_violation - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -322,7 +322,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithMixedIssues/two_sources_with_packages,_one_vulnerability,_one_license_violation - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -341,19 +341,19 @@ path/to/my/second/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_grouped_packages,_and_multiple_vulnerabilities - 1] path/to/my/first/lockfile: found 2 packages with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) OSV-5: Something scarier! (https://osv.dev/OSV-5) - mine1@1.2.2 is affected by the following vulnerabilities: + mine1@1.2.2 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues - mine2@3.2.5 is affected by the following vulnerabilities: + mine2@3.2.5 has the following known vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) - mine3@0.4.1 is affected by the following vulnerabilities: + mine3@0.4.1 has the following known vulnerabilities: OSV-3: Something mildly scary! (https://osv.dev/OSV-3) OSV-5: Something scarier! (https://osv.dev/OSV-5) @@ -364,19 +364,19 @@ path/to/my/second/lockfile: found 2 packages with issues [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_and_multiple_vulnerabilities - 1] path/to/my/first/lockfile: found 2 packages with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) OSV-5: Something scarier! (https://osv.dev/OSV-5) - mine1@1.2.2 is affected by the following vulnerabilities: + mine1@1.2.2 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues - mine2@3.2.5 is affected by the following vulnerabilities: + mine2@3.2.5 has the following known vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) - mine3@0.4.1 is affected by the following vulnerabilities: + mine3@0.4.1 has the following known vulnerabilities: OSV-3: Something mildly scary! (https://osv.dev/OSV-3) OSV-5: Something scarier! (https://osv.dev/OSV-5) @@ -399,21 +399,21 @@ path/to/my/third/lockfile: found 2 packages with issues [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages,_some_vulnerabilities - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues - mine2@3.2.5 is affected by the following vulnerabilities: + mine2@3.2.5 has the following known vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) 1 known vulnerability found in path/to/my/second/lockfile path/to/my/third/lockfile: found 2 packages with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/third/lockfile @@ -423,19 +423,19 @@ path/to/my/third/lockfile: found 2 packages with issues [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities - 1] path/to/my/first/lockfile: found 2 packages with issues - author1/mine1@1.2.3 is affected by the following vulnerabilities: + author1/mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) OSV-5: Something scarier! (https://osv.dev/OSV-5) - mine1@1.2.2 is affected by the following vulnerabilities: + mine1@1.2.2 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 3 known vulnerabilities found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues - mine2@3.2.5 is affected by the following vulnerabilities: + mine2@3.2.5 has the following known vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) - author3/mine3@0.4.1 is affected by the following vulnerabilities: + author3/mine3@0.4.1 has the following known vulnerabilities: OSV-3: Something mildly scary! (https://osv.dev/OSV-3) OSV-5: Something scarier! (https://osv.dev/OSV-5) @@ -446,23 +446,23 @@ path/to/my/second/lockfile: found 2 packages with issues [TestPrintVerticalResults_WithVulnerabilities/multiple_sources_with_a_mixed_count_of_packages_across_ecosystems,_and_multiple_vulnerabilities,_but_some_uncalled - 1] path/to/my/first/lockfile: found 2 packages with issues - author1/mine1@1.2.3 is affected by the following vulnerabilities: + author1/mine1@1.2.3 has the following known vulnerabilities: OSV-5: Something scarier! (https://osv.dev/OSV-5) - mine1@1.2.2 is affected by the following vulnerabilities: + mine1@1.2.2 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 2 known vulnerabilities found in path/to/my/first/lockfile - author1/mine1@1.2.3 may be affected by the following vulnerabilities: + author1/mine1@1.2.3 has the following uncalled vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 uncalled vulnerability found in path/to/my/first/lockfile path/to/my/second/lockfile: found 2 packages with issues - mine2@3.2.5 is affected by the following vulnerabilities: + mine2@3.2.5 has the following known vulnerabilities: OSV-2: Something less scary! (https://osv.dev/OSV-2) - author3/mine3@0.4.1 is affected by the following vulnerabilities: + author3/mine3@0.4.1 has the following known vulnerabilities: OSV-3: Something mildly scary! (https://osv.dev/OSV-3) OSV-5: Something scarier! (https://osv.dev/OSV-5) @@ -501,12 +501,12 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package,_one_uncalled_vulnerability,_and_one_called_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile - mine1@1.2.3 may be affected by the following vulnerabilities: + mine1@1.2.3 has the following uncalled vulnerabilities: GHSA-123: Something scarier! (https://osv.dev/GHSA-123) 1 uncalled vulnerability found in path/to/my/first/lockfile @@ -516,7 +516,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_called_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -526,7 +526,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_uncalled_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 may be affected by the following vulnerabilities: + mine1@1.2.3 has the following uncalled vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 uncalled vulnerability found in path/to/my/first/lockfile @@ -536,7 +536,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -546,7 +546,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_one_vulnerability_(dev) - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -556,7 +556,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_uncalled_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 may be affected by the following vulnerabilities: + mine1@1.2.3 has the following uncalled vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) GHSA-123: Something scary! (https://osv.dev/GHSA-123) @@ -567,7 +567,7 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_one_package_and_two_aliases_of_a_single_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) GHSA-123: Something scary! (https://osv.dev/GHSA-123) @@ -578,9 +578,9 @@ path/to/my/first/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/one_source_with_vulnerabilities,_some_missing_content - 1] path/to/my/first/lockfile: found 2 packages with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: This vulnerability allows for some very scary stuff to happen - seriously,... (https://osv.dev/OSV-1) - mine3@0.10.2-rc is affected by the following vulnerabilities: + mine3@0.10.2-rc has the following known vulnerabilities: OSV-2: (no details available) (https://osv.dev/OSV-2) 2 known vulnerabilities found in path/to/my/first/lockfile @@ -590,7 +590,7 @@ path/to/my/first/lockfile: found 2 packages with issues [TestPrintVerticalResults_WithVulnerabilities/two_sources_with_packages,_one_vulnerability - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile @@ -603,14 +603,14 @@ path/to/my/second/lockfile: found 1 package with issues [TestPrintVerticalResults_WithVulnerabilities/two_sources_with_the_same_vulnerable_package - 1] path/to/my/first/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/first/lockfile path/to/my/second/lockfile: found 1 package with issues - mine1@1.2.3 is affected by the following vulnerabilities: + mine1@1.2.3 has the following known vulnerabilities: OSV-1: Something scary! (https://osv.dev/OSV-1) 1 known vulnerability found in path/to/my/second/lockfile diff --git a/internal/output/vertical.go b/internal/output/vertical.go index f8b4462937..044eaa867e 100644 --- a/internal/output/vertical.go +++ b/internal/output/vertical.go @@ -75,15 +75,15 @@ func printVerticalVulnerabilitiesForPackages(result models.PackageSource, out io continue } - state := "is" - if !printingCalled { - state = "may be" + state := "uncalled" + if printingCalled { + state = "known" } fmt.Fprintf(out, " %s %s\n", text.FgYellow.Sprintf("%s@%s", pkg.Package.Name, pkg.Package.Version), - text.FgRed.Sprintf("%s affected by the following vulnerabilities:", state), + text.FgRed.Sprintf("has the following %s vulnerabilities:", state), ) for _, vulnerability := range vulns {