Repository: google/osv-scanner
Pull request #627 (2023-11-01 23:06:05)

test: don't ignore anything from coverage
I'm honestly sure CodeCov isn't bugged (or that somehow we're uploading results from a branch...), but removing this file/ignore increases coverage a little so why not 🤷 

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/google/osv-scanner/pull/627?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
> Merging [#627](https://app.codecov.io/gh/google/osv-scanner/pull/627?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (293ed30) into [main](https://app.codecov.io/gh/google/osv-scanner/commit/ac2897cf3e69379831e4ca583d5a671c827369dd?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (ac2897c) will **decrease** coverage by `1.52%`.
> Report is 1 commits behind head on main.
> The diff coverage is `2.80%`.

```diff
@@            Coverage Diff             @@
##             main     #627      +/-   ##
==========================================
- Coverage   80.33%   78.82%   -1.52%     
==========================================
  Files          78       78              
  Lines        5406     5511     +105     
==========================================
+ Hits         4343     4344       +1     
- Misses        887      990     +103     
- Partials      176      177       +1     
```


| [Files](https://app.codecov.io/gh/google/osv-scanner/pull/627?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) | Coverage Δ | |
|---|---|---|
| [pkg/osv/osv.go](https://app.codecov.io/gh/google/osv-scanner/pull/627?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-cGtnL29zdi9vc3YuZ28=) | `52.87% <0.00%> (-10.65%)` | :arrow_down: |
| [pkg/osvscanner/osvscanner.go](https://app.codecov.io/gh/google/osv-scanner/pull/627?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-cGtnL29zdnNjYW5uZXIvb3N2c2Nhbm5lci5nbw==) | `53.12% <4.00%> (-7.52%)` | :arrow_down: |


another-rex: Probably need to update the branch to show correct coverage change.
G-Rath: Na it's been a bit weird in general - no matter what I do it seems want to go down a fair bit, and it was like that on e.g. #628 too

I suspect it might be we have to land this on `main` before the % will be properly accurate; alternatively I'm thinking it might actually just be completely tossing out the coverage while still including these in the line count which would always result in that worse outcome...

Patch:
diff --git a/cmd/osv-scanner/fixtures/locks-many/replace-local.mod b/cmd/osv-scanner/fixtures/locks-many/replace-local.mod
new file mode 100644
index 0000000..b8a1163
--- /dev/null
+++ b/cmd/osv-scanner/fixtures/locks-many/replace-local.mod
@@ -0,0 +1,7 @@
+require (
+    golang.org/x/net v1.2.3
+)
+
+replace (
+    golang.org/x/net v1.2.3 => ./fork/net
+)
diff --git a/codecov.yml b/codecov.yml
deleted file mode 100644
index 63ee507..0000000
--- a/codecov.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-ignore:
-  - internal/testutility
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 7afacee..a4b435d 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/google/osv-scanner
 go 1.20
 
 require (
-	deps.dev/api/v3alpha v0.0.0-20230809051853-667b62c44a10
+	deps.dev/api/v3alpha v0.0.0-20231029115524-a2ccd033c6d4
 	github.com/BurntSushi/toml v1.3.2
 	github.com/CycloneDX/cyclonedx-go v0.7.2
 	github.com/go-git/go-billy/v5 v5.5.0
@@ -18,11 +18,11 @@ require (
 	github.com/spdx/tools-golang v0.5.3
 	github.com/urfave/cli/v2 v2.25.7
 	golang.org/x/exp v0.0.0-20231006140011-7918f672742d
-	golang.org/x/mod v0.13.0
-	golang.org/x/sync v0.4.0
+	golang.org/x/mod v0.14.0
+	golang.org/x/sync v0.5.0
 	golang.org/x/term v0.13.0
 	golang.org/x/vuln v1.0.1
-	google.golang.org/grpc v1.58.3
+	google.golang.org/grpc v1.59.0
 	gopkg.in/yaml.v3 v3.0.1
 )
 
@@ -57,7 +57,7 @@ require (
 	golang.org/x/sys v0.13.0 // indirect
 	golang.org/x/text v0.13.0 // indirect
 	golang.org/x/tools v0.14.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
 )
diff --git a/go.sum b/go.sum
index 54cd133..d8c764e 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,7 @@
 dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
 dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
-deps.dev/api/v3alpha v0.0.0-20230809051853-667b62c44a10 h1:qarCOf30WxJl59R04MCCq6IuL1pzE3Z1M4YeFJ8hEOk=
-deps.dev/api/v3alpha v0.0.0-20230809051853-667b62c44a10/go.mod h1:69Mvmw3jh/42Ci9wYemDIid4hXXAEJGHI6oUAWaZnqA=
+deps.dev/api/v3alpha v0.0.0-20231029115524-a2ccd033c6d4 h1:y/JsYdh5JCgcI1WtxfTYrhj48YK8DsZUHFVVtZT4Qwc=
+deps.dev/api/v3alpha v0.0.0-20231029115524-a2ccd033c6d4/go.mod h1:uRN72FJn1F0FD/2ZYUOqdyFMu8VUsyHxvmZAMW30/DA=
 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 github.com/CycloneDX/cyclonedx-go v0.7.2 h1:kKQ0t1dPOlugSIYVOMiMtFqeXI2wp/f5DBIdfux8gnQ=
@@ -142,8 +142,8 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM
 golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
-golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
+golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -158,8 +158,8 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
-golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
+golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -205,10 +205,10 @@ golang.org/x/vuln v1.0.1/go.mod h1:bb2hMwln/tqxg32BNY4CcxHWtHXuYa3SbIBmtsyjxtM=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
-google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
-google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
+google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
+google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
diff --git a/pkg/lockfile/fixtures/cargo/two-packages-with-local.lock b/pkg/lockfile/fixtures/cargo/two-packages-with-local.lock
new file mode 100644
index 0000000..0e45b75
--- /dev/null
+++ b/pkg/lockfile/fixtures/cargo/two-packages-with-local.lock
@@ -0,0 +1,16 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "local-rust-pkg"
+version = "0.1.0"
diff --git a/pkg/osvscanner/osvscanner.go b/pkg/osvscanner/osvscanner.go
index 230fdf0..bc334e7 100644
--- a/pkg/osvscanner/osvscanner.go
+++ b/pkg/osvscanner/osvscanner.go
@@ -774,19 +774,25 @@ func DoScan(actions ScannerActions, r reporter.Reporter) (models.VulnerabilityRe
 		return models.VulnerabilityResults{}, NoPackagesFoundErr
 	}
 
-	vulnsResp, err := makeRequest(r, scannedPackages, actions.CompareLocally, actions.CompareOffline, actions.LocalDBPath)
+	filteredScannedPackages := filterUnscannablePackages(scannedPackages)
+
+	if len(filteredScannedPackages) != len(scannedPackages) {
+		r.PrintText(fmt.Sprintf("Filtered %d local package/s from the scan.\n", len(scannedPackages)-len(filteredScannedPackages)))
+	}
+
+	vulnsResp, err := makeRequest(r, filteredScannedPackages, actions.CompareLocally, actions.CompareOffline, actions.LocalDBPath)
 	if err != nil {
 		return models.VulnerabilityResults{}, err
 	}
 
 	var licensesResp [][]models.License
 	if actions.ScanLicenses {
-		licensesResp, err = makeLicensesRequests(scannedPackages)
+		licensesResp, err = makeLicensesRequests(filteredScannedPackages)
 		if err != nil {
 			return models.VulnerabilityResults{}, err
 		}
 	}
-	results := buildVulnerabilityResults(r, scannedPackages, vulnsResp, licensesResp, actions.CallAnalysis, actions.ShowAllPackages, actions.ScanLicenses, actions.ScanLicensesAllowlist)
+	results := buildVulnerabilityResults(r, filteredScannedPackages, vulnsResp, licensesResp, actions.CallAnalysis, actions.ShowAllPackages, actions.ScanLicenses, actions.ScanLicensesAllowlist)
 
 	filtered := filterResults(r, &results, &configManager, actions.ShowAllPackages)
 	if filtered > 0 {
@@ -842,6 +848,25 @@ func DoScan(actions ScannerActions, r reporter.Reporter) (models.VulnerabilityRe
 	return results, nil
 }
 
+// filterUnscannablePackages removes packages that don't have enough information to be scanned
+// e,g, local packages that specified by path
+func filterUnscannablePackages(packages []scannedPackage) []scannedPackage {
+	out := make([]scannedPackage, 0, len(packages))
+	for _, p := range packages {
+		switch {
+		// If none of the cases match, skip this package since it's not scannable
+		case p.Ecosystem != "" && p.Name != "" && p.Version != "":
+		case p.Commit != "":
+		case p.PURL != "":
+		default:
+			continue
+		}
+		out = append(out, p)
+	}
+
+	return out
+}
+
 func makeRequest(
 	r reporter.Reporter,
 	packages []scannedPackage,


Test patch:
diff --git a/cmd/osv-scanner/main_test.go b/cmd/osv-scanner/main_test.go
index cca785d..ff124d8 100644
--- a/cmd/osv-scanner/main_test.go
+++ b/cmd/osv-scanner/main_test.go
@@ -167,7 +167,7 @@ func TestRun(t *testing.T) {
 		},
 		// one specific supported lockfile
 		{
-			name:         "",
+			name:         "one specific supported lockfile",
 			args:         []string{"", "./fixtures/locks-many/composer.lock"},
 			wantExitCode: 0,
 			wantStdout: `
@@ -589,6 +589,18 @@ func TestRun_LockfileWithExplicitParseAs(t *testing.T) {
 				open <rootdir>/path/to/my:project/package-lock.json: no such file or directory
 			`,
 		},
+		// one lockfile with local path
+		{
+			name:         "one lockfile with local path",
+			args:         []string{"", "--lockfile=go.mod:./fixtures/locks-many/replace-local.mod"},
+			wantExitCode: 0,
+			wantStdout: `
+				Scanned <rootdir>/fixtures/locks-many/replace-local.mod file as a go.mod and found 2 packages
+				Filtered 1 local package/s from the scan.
+				No issues found
+			`,
+			wantStderr: "",
+		},
 		// when an explicit parse-as is given, it's applied to that file
 		{
 			name: "",
diff --git a/pkg/lockfile/parse-cargo-lock_test.go b/pkg/lockfile/parse-cargo-lock_test.go
index 61baa06..d1d80b8 100644
--- a/pkg/lockfile/parse-cargo-lock_test.go
+++ b/pkg/lockfile/parse-cargo-lock_test.go
@@ -133,6 +133,31 @@ func TestParseCargoLock_TwoPackages(t *testing.T) {
 	})
 }
 
+func TestParseCargoLock_TwoPackagesWithLocal(t *testing.T) {
+	t.Parallel()
+
+	packages, err := lockfile.ParseCargoLock("fixtures/cargo/two-packages-with-local.lock")
+
+	if err != nil {
+		t.Errorf("Got unexpected error: %v", err)
+	}
+
+	expectPackages(t, packages, []lockfile.PackageDetails{
+		{
+			Name:      "addr2line",
+			Version:   "0.15.2",
+			Ecosystem: lockfile.CargoEcosystem,
+			CompareAs: lockfile.CargoEcosystem,
+		},
+		{
+			Name:      "local-rust-pkg",
+			Version:   "0.1.0",
+			Ecosystem: lockfile.CargoEcosystem,
+			CompareAs: lockfile.CargoEcosystem,
+		},
+	})
+}
+
 func TestParseCargoLock_PackageWithBuildString(t *testing.T) {
 	t.Parallel()