Skip to content

Commit

Permalink
fix: use correct plural and singular forms based on count (#462)
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Aug 2, 2023
1 parent f16b46c commit 1898ead
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 41 deletions.
68 changes: 34 additions & 34 deletions cmd/osv-scanner/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func TestRun(t *testing.T) {
wantExitCode: 0,
wantStdout: `
Scanning dir ./fixtures/locks-many/composer.lock
Scanned %%/fixtures/locks-many/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand Down Expand Up @@ -184,14 +184,14 @@ func TestRun(t *testing.T) {
wantExitCode: 0,
wantStdout: `
Scanning dir ./fixtures/locks-many
Scanned %%/fixtures/locks-many/Gemfile.lock file and found 1 packages
Scanned %%/fixtures/locks-many/Gemfile.lock file and found 1 package
Scanned %%/fixtures/locks-many/alpine.cdx.xml as CycloneDX SBOM and found 15 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-many/package-lock.json file and found 1 packages
Scanned %%/fixtures/locks-many/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 package
Scanned %%/fixtures/locks-many/package-lock.json file and found 1 package
Scanned %%/fixtures/locks-many/yarn.lock file and found 1 package
Loaded filter from: %%/fixtures/locks-many/osv-scanner.toml
GHSA-whgm-jr23-g3j9 has been filtered out because: Test manifest file
Filtered 1 vulnerabilities from output
Filtered 1 vulnerability from output
No vulnerabilities found
`,
wantStderr: "",
Expand All @@ -203,8 +203,8 @@ func TestRun(t *testing.T) {
wantExitCode: 127,
wantStdout: `
Scanning dir ./fixtures/locks-many-with-invalid
Scanned %%/fixtures/locks-many-with-invalid/Gemfile.lock file and found 1 packages
Scanned %%/fixtures/locks-many-with-invalid/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-many-with-invalid/Gemfile.lock file and found 1 package
Scanned %%/fixtures/locks-many-with-invalid/yarn.lock file and found 1 package
`,
wantStderr: `
Attempted to scan lockfile but failed: %%/fixtures/locks-many-with-invalid/composer.lock
Expand All @@ -217,7 +217,7 @@ func TestRun(t *testing.T) {
wantExitCode: 0,
wantStdout: `
Scanning dir ./fixtures/locks-one-with-nested
Scanned %%/fixtures/locks-one-with-nested/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-one-with-nested/yarn.lock file and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand All @@ -229,8 +229,8 @@ func TestRun(t *testing.T) {
wantExitCode: 0,
wantStdout: `
Scanning dir ./fixtures/locks-one-with-nested
Scanned %%/fixtures/locks-one-with-nested/nested/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-one-with-nested/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-one-with-nested/nested/composer.lock file and found 1 package
Scanned %%/fixtures/locks-one-with-nested/yarn.lock file and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand All @@ -242,8 +242,8 @@ func TestRun(t *testing.T) {
wantExitCode: 0,
wantStdout: `
Scanning dir ./fixtures/locks-gitignore
Scanned %%/fixtures/locks-gitignore/Gemfile.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/subdir/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/Gemfile.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/subdir/yarn.lock file and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand All @@ -255,14 +255,14 @@ func TestRun(t *testing.T) {
wantExitCode: 0,
wantStdout: `
Scanning dir ./fixtures/locks-gitignore
Scanned %%/fixtures/locks-gitignore/Gemfile.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/ignored/Gemfile.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/ignored/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/subdir/Gemfile.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/subdir/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/subdir/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/yarn.lock file and found 1 packages
Scanned %%/fixtures/locks-gitignore/Gemfile.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/composer.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/ignored/Gemfile.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/ignored/yarn.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/subdir/Gemfile.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/subdir/composer.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/subdir/yarn.lock file and found 1 package
Scanned %%/fixtures/locks-gitignore/yarn.lock file and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand All @@ -279,7 +279,7 @@ func TestRun(t *testing.T) {
`,
wantStderr: `
Scanning dir ./fixtures/locks-many/composer.lock
Scanned %%/fixtures/locks-many/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 package
`,
},
{
Expand All @@ -293,7 +293,7 @@ func TestRun(t *testing.T) {
`,
wantStderr: `
Scanning dir ./fixtures/locks-many/composer.lock
Scanned %%/fixtures/locks-many/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 package
`,
},
// output format: sarif
Expand Down Expand Up @@ -328,7 +328,7 @@ func TestRun(t *testing.T) {
`,
wantStderr: `
Scanning dir ./fixtures/locks-many/composer.lock
Scanned %%/fixtures/locks-many/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 package
`,
},
{
Expand Down Expand Up @@ -388,7 +388,7 @@ func TestRun(t *testing.T) {
`,
wantStderr: `
Scanning dir ./fixtures/locks-many/package-lock.json
Scanned %%/fixtures/locks-many/package-lock.json file and found 1 packages
Scanned %%/fixtures/locks-many/package-lock.json file and found 1 package
`,
},
// output format: markdown table
Expand All @@ -398,7 +398,7 @@ func TestRun(t *testing.T) {
wantExitCode: 0,
wantStdout: `
Scanning dir ./fixtures/locks-many/composer.lock
Scanned %%/fixtures/locks-many/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand Down Expand Up @@ -438,7 +438,7 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
},
wantExitCode: 0,
wantStdout: `
Scanned %%/fixtures/locks-many/composer.lock file and found 1 packages
Scanned %%/fixtures/locks-many/composer.lock file and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand Down Expand Up @@ -481,7 +481,7 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
},
wantExitCode: 1,
wantStdout: `
Scanned %%/fixtures/locks-insecure/my-package-lock.json file as a package-lock.json and found 1 packages
Scanned %%/fixtures/locks-insecure/my-package-lock.json file as a package-lock.json and found 1 package
Scanning dir ./fixtures/locks-insecure
Scanned %%/fixtures/locks-insecure/composer.lock file and found 0 packages
+-------------------------------------+------+-----------+-----------+---------+----------------------------------------------+
Expand All @@ -503,8 +503,8 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
},
wantExitCode: 1,
wantStdout: `
Scanned %%/fixtures/locks-insecure/my-package-lock.json file as a package-lock.json and found 1 packages
Scanned %%/fixtures/locks-insecure/my-yarn.lock file as a yarn.lock and found 1 packages
Scanned %%/fixtures/locks-insecure/my-package-lock.json file as a package-lock.json and found 1 package
Scanned %%/fixtures/locks-insecure/my-yarn.lock file as a yarn.lock and found 1 package
Scanning dir ./fixtures/locks-insecure
Scanned %%/fixtures/locks-insecure/composer.lock file and found 0 packages
+-------------------------------------+------+-----------+-----------+---------+----------------------------------------------+
Expand All @@ -526,8 +526,8 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
},
wantExitCode: 1,
wantStdout: `
Scanned %%/fixtures/locks-insecure/my-yarn.lock file as a yarn.lock and found 1 packages
Scanned %%/fixtures/locks-insecure/my-package-lock.json file as a package-lock.json and found 1 packages
Scanned %%/fixtures/locks-insecure/my-yarn.lock file as a yarn.lock and found 1 package
Scanned %%/fixtures/locks-insecure/my-package-lock.json file as a package-lock.json and found 1 package
Scanning dir ./fixtures/locks-insecure
Scanned %%/fixtures/locks-insecure/composer.lock file and found 0 packages
+-------------------------------------+------+-----------+-----------+---------+----------------------------------------------+
Expand Down Expand Up @@ -579,7 +579,7 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
},
wantExitCode: 0,
wantStdout: `
Scanned %%/fixtures/locks-many/installed file as a apk-installed and found 1 packages
Scanned %%/fixtures/locks-many/installed file as a apk-installed and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand All @@ -594,7 +594,7 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
},
wantExitCode: 0,
wantStdout: `
Scanned %%/fixtures/locks-many/status file as a dpkg-status and found 1 packages
Scanned %%/fixtures/locks-many/status file as a dpkg-status and found 1 package
No vulnerabilities found
`,
wantStderr: "",
Expand Down
10 changes: 10 additions & 0 deletions internal/output/form.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package output

// Form returns the singular or plural form that should be used based on the given count
func Form(count int, singular, plural string) string {
if count == 1 {
return singular
}

return plural
}
60 changes: 60 additions & 0 deletions internal/output/form_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package output_test

import (
"testing"

"github.com/google/osv-scanner/internal/output"
)

func TestForm(t *testing.T) {
t.Parallel()

type args struct {
count int
singular string
plural string
}
tests := []struct {
name string
args args
want string
}{
{
name: "",
args: args{
count: 0,
singular: "package",
plural: "packages",
},
want: "packages",
},
{
name: "",
args: args{
count: 1,
singular: "package",
plural: "packages",
},
want: "package",
},
{
name: "",
args: args{
count: 2,
singular: "package",
plural: "packages",
},
want: "packages",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

if got := output.Form(tt.args.count, tt.args.singular, tt.args.plural); got != tt.want {
t.Errorf("Form() = %v, want %v", got, tt.want)
}
})
}
}
8 changes: 7 additions & 1 deletion pkg/lockfile/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"
"testing"

"github.com/google/osv-scanner/internal/output"
"github.com/google/osv-scanner/pkg/lockfile"
)

Expand Down Expand Up @@ -70,7 +71,12 @@ func expectPackages(t *testing.T, actualPackages []lockfile.PackageDetails, expe
t.Helper()

if len(expectedPackages) != len(actualPackages) {
t.Errorf("Expected to get %d packages, but got %d", len(expectedPackages), len(actualPackages))
t.Errorf(
"Expected to get %d %s, but got %d",
len(expectedPackages),
output.Form(len(expectedPackages), "package", "packages"),
len(actualPackages),
)
}

missingActualPackages := findMissingPackages(actualPackages, expectedPackages)
Expand Down
4 changes: 3 additions & 1 deletion pkg/lockfile/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"
"testing"

"github.com/google/osv-scanner/internal/output"
"github.com/google/osv-scanner/pkg/lockfile"
)

Expand All @@ -30,8 +31,9 @@ func expectNumberOfParsersCalled(t *testing.T, numberOfParsersCalled int) {

if numberOfParsersCalled != count {
t.Errorf(
"Expected %d parsers to have been called, but had %d",
"Expected %d %s to have been called, but had %d",
count,
output.Form(count, "parser", "parsers"),
numberOfParsersCalled,
)
}
Expand Down
35 changes: 30 additions & 5 deletions pkg/osvscanner/osvscanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path/filepath"
"strings"

"github.com/google/osv-scanner/internal/output"
"github.com/google/osv-scanner/internal/sbom"
"github.com/google/osv-scanner/pkg/config"
"github.com/google/osv-scanner/pkg/lockfile"
Expand Down Expand Up @@ -205,7 +206,13 @@ func scanLockfile(r reporter.Reporter, query *osv.BatchedQuery, path string, par
parsedAsComment = fmt.Sprintf("as a %s ", parseAs)
}

r.PrintText(fmt.Sprintf("Scanned %s file %sand found %d packages\n", path, parsedAsComment, len(parsedLockfile.Packages)))
r.PrintText(fmt.Sprintf(
"Scanned %s file %sand found %d %s\n",
path,
parsedAsComment,
len(parsedLockfile.Packages),
output.Form(len(parsedLockfile.Packages), "package", "packages"),
))

for _, pkgDetail := range parsedLockfile.Packages {
pkgDetailQuery := osv.MakePkgRequest(pkgDetail)
Expand Down Expand Up @@ -273,9 +280,19 @@ func scanSBOMFile(r reporter.Reporter, query *osv.BatchedQuery, path string, fro

continue
}
r.PrintText(fmt.Sprintf("Scanned %s as %s SBOM and found %d packages\n", path, provider.Name(), count))
r.PrintText(fmt.Sprintf(
"Scanned %s as %s SBOM and found %d %s\n",
path,
provider.Name(),
count,
output.Form(count, "package", "packages"),
))
if ignoredCount > 0 {
r.PrintText(fmt.Sprintf("Ignored %d packages with invalid PURLs\n", ignoredCount))
r.PrintText(fmt.Sprintf(
"Ignored %d %s with invalid PURLs\n",
ignoredCount,
output.Form(ignoredCount, "package", "packages"),
))
}

return nil
Expand Down Expand Up @@ -378,7 +395,11 @@ func scanDebianDocker(r reporter.Reporter, query *osv.BatchedQuery, dockerImageN
query.Queries = append(query.Queries, pkgDetailsQuery)
packages += 1
}
r.PrintText(fmt.Sprintf("Scanned docker image with %d packages\n", packages))
r.PrintText(fmt.Sprintf(
"Scanned docker image with %d %s\n",
packages,
output.Form(packages, "package", "packages"),
))

return nil
}
Expand Down Expand Up @@ -554,7 +575,11 @@ func DoScan(actions ScannerActions, r reporter.Reporter) (models.VulnerabilityRe

filtered := filterResults(r, &vulnerabilityResults, &configManager)
if filtered > 0 {
r.PrintText(fmt.Sprintf("Filtered %d vulnerabilities from output\n", filtered))
r.PrintText(fmt.Sprintf(
"Filtered %d %s from output\n",
filtered,
output.Form(filtered, "vulnerability", "vulnerabilities"),
))
}

// if vulnerability exists it should return error
Expand Down

0 comments on commit 1898ead

Please sign in to comment.