Repository: google/osv-scanner
Pull request #36 (2022-12-12 04:31:49)

Make grouper public
Grouper now only takes in what's needed, and is public. By limiting the type that grouper takes in it allows much easier usage externally. 


Patch:
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 6c7d446..bb4073b 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -71,7 +71,9 @@ func (c *ConfigManager) Get(r *output.Reporter, targetPath string) Config {
 
 	configPath, err := normalizeConfigLoadPath(targetPath)
 	if err != nil {
-		r.PrintError(fmt.Sprintf("Can't find config path: %s\n", err))
+		// TODO: This can happen when target is not a file (e.g. Docker container, git hash...etc.)
+		// Figure out a more robust way to load config from non files
+		// r.PrintError(fmt.Sprintf("Can't find config path: %s\n", err))
 		return Config{}
 	}
 
diff --git a/internal/grouper/grouper.go b/pkg/grouper/grouper.go
similarity index 92%
rename from internal/grouper/grouper.go
rename to pkg/grouper/grouper.go
index 68cd034..e28f05f 100644
--- a/internal/grouper/grouper.go
+++ b/pkg/grouper/grouper.go
@@ -16,7 +16,7 @@ func min(a, b int) int {
 	return b
 }
 
-func hasAliasIntersection(v1, v2 models.Vulnerability) bool {
+func hasAliasIntersection(v1, v2 IDAliases) bool {
 	// Check if any aliases intersect.
 	for _, alias := range v1.Aliases {
 		if slices.Contains(v2.Aliases, alias) {
@@ -28,7 +28,7 @@ func hasAliasIntersection(v1, v2 models.Vulnerability) bool {
 }
 
 // Group groups vulnerabilities by aliases.
-func Group(vulns []models.Vulnerability) []models.GroupInfo {
+func Group(vulns []IDAliases) []models.GroupInfo {
 	// Mapping of `vulns` index to a group ID. A group ID is just another index in the `vulns` slice.
 	groups := make([]int, len(vulns))
 
diff --git a/pkg/grouper/grouper_models.go b/pkg/grouper/grouper_models.go
new file mode 100644
index 0000000..d919ad4
--- /dev/null
+++ b/pkg/grouper/grouper_models.go
@@ -0,0 +1,20 @@
+package grouper
+
+import "github.com/google/osv-scanner/pkg/models"
+
+type IDAliases struct {
+	ID      string
+	Aliases []string
+}
+
+func ConvertVulnerabilityToIDAliases(c []models.Vulnerability) []IDAliases {
+	output := []IDAliases{}
+	for _, v := range c {
+		idAliases := IDAliases{
+			ID:      v.ID,
+			Aliases: v.Aliases,
+		}
+		output = append(output, idAliases)
+	}
+	return output
+}
diff --git a/pkg/osvscanner/vulnerability_result.go b/pkg/osvscanner/vulnerability_result.go
index d06cacf..2dd0c38 100644
--- a/pkg/osvscanner/vulnerability_result.go
+++ b/pkg/osvscanner/vulnerability_result.go
@@ -3,9 +3,9 @@ package osvscanner
 import (
 	"fmt"
 
-	"github.com/google/osv-scanner/internal/grouper"
 	"github.com/google/osv-scanner/internal/osv"
 	"github.com/google/osv-scanner/internal/output"
+	"github.com/google/osv-scanner/pkg/grouper"
 	"github.com/google/osv-scanner/pkg/models"
 )
 
@@ -46,7 +46,7 @@ func groupResponseBySource(r *output.Reporter, query osv.BatchedQuery, resp *osv
 
 		pkg.Vulnerabilities = response.Vulns
 
-		pkg.Groups = grouper.Group(pkg.Vulnerabilities)
+		pkg.Groups = grouper.Group(grouper.ConvertVulnerabilityToIDAliases(pkg.Vulnerabilities))
 		groupedBySource[query.Source] = append(groupedBySource[query.Source], pkg)
 	}
 


Test patch:
diff --git a/internal/grouper/grouper_test.go b/pkg/grouper/grouper_test.go
similarity index 82%
rename from internal/grouper/grouper_test.go
rename to pkg/grouper/grouper_test.go
index a62a6cb..ebba417 100644
--- a/internal/grouper/grouper_test.go
+++ b/pkg/grouper/grouper_test.go
@@ -9,17 +9,17 @@ import (
 
 func TestGroup(t *testing.T) {
 	// Should be grouped by IDs appearing in alias.
-	v1 := models.Vulnerability{
+	v1 := IDAliases{
 		ID: "CVE-1",
 		Aliases: []string{
 			"FOO-1",
 		},
 	}
-	v2 := models.Vulnerability{
+	v2 := IDAliases{
 		ID:      "FOO-1",
 		Aliases: []string{},
 	}
-	v3 := models.Vulnerability{
+	v3 := IDAliases{
 		ID: "FOO-2",
 		Aliases: []string{
 			"FOO-1",
@@ -27,21 +27,21 @@ func TestGroup(t *testing.T) {
 	}
 
 	// Should be grouped by aliases intersecting.
-	v4 := models.Vulnerability{
+	v4 := IDAliases{
 		ID: "BAR-1",
 		Aliases: []string{
 			"CVE-2",
 			"CVE-3",
 		},
 	}
-	v5 := models.Vulnerability{
+	v5 := IDAliases{
 		ID: "BAR-2",
 		Aliases: []string{
 			"CVE-3",
 			"CVE-4",
 		},
 	}
-	v6 := models.Vulnerability{
+	v6 := IDAliases{
 		ID: "BAR-3",
 		Aliases: []string{
 			"CVE-4",
@@ -49,13 +49,13 @@ func TestGroup(t *testing.T) {
 	}
 
 	// Unrelated.
-	v7 := models.Vulnerability{
+	v7 := IDAliases{
 		ID: "UNRELATED-1",
 		Aliases: []string{
 			"BAR-1337",
 		},
 	}
-	v8 := models.Vulnerability{
+	v8 := IDAliases{
 		ID: "UNRELATED-2",
 		Aliases: []string{
 			"BAR-1338",
@@ -63,11 +63,11 @@ func TestGroup(t *testing.T) {
 	}
 
 	for _, tc := range []struct {
-		vulns []models.Vulnerability
+		vulns []IDAliases
 		want  []models.GroupInfo
 	}{
 		{
-			vulns: []models.Vulnerability{
+			vulns: []IDAliases{
 				v1, v2, v3, v4, v5, v6, v7, v8,
 			},
 			want: []models.GroupInfo{
@@ -86,7 +86,7 @@ func TestGroup(t *testing.T) {
 			},
 		},
 		{
-			vulns: []models.Vulnerability{
+			vulns: []IDAliases{
 				v8, v2, v1, v5, v7, v4, v6, v3,
 			},
 			want: []models.GroupInfo{