Skip to content

Commit 4599421

Browse files
authored
feat: support checking if packages exist for CRAN (#399)
Signed-off-by: Gareth Jones <3151613+G-Rath@users.noreply.github.com>
1 parent d392694 commit 4599421

File tree

5 files changed

+113
-2
lines changed

5 files changed

+113
-2
lines changed

tools/osv-linter/internal/pkgchecker/ecosystems.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var SupportedEcosystems = []string{
2121

2222
// EcosystemBaseURLs maps ecosystems to their base API URLs.
2323
var EcosystemBaseURLs = map[string]string{
24+
"CRAN": "https://crandb.r-pkg.org/",
2425
"crates.io": "https://crates.io/api/v1/crates",
2526
"Go": "https://proxy.golang.org",
2627
"Hackage": "https://hackage.haskell.org/package",
@@ -48,7 +49,7 @@ func ExistsInEcosystem(pkg string, ecosystem string) bool {
4849
case "Chainguard":
4950
return true
5051
case "CRAN":
51-
return true
52+
return existsInCran(pkg)
5253
case "crates.io":
5354
return existsInCrates(pkg)
5455
case "Debian":
@@ -142,7 +143,7 @@ func VersionsExistInEcosystem(pkg string, versions []string, ecosystem string) e
142143
case "Chainguard":
143144
return nil
144145
case "CRAN":
145-
return nil
146+
return versionsExistInCran(pkg, versions)
146147
case "crates.io":
147148
return versionsExistInCrates(pkg, versions)
148149
case "Debian":

tools/osv-linter/internal/pkgchecker/ecosystems_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,70 @@ package pkgchecker
22

33
import "testing"
44

5+
func Test_versionsExistInCran(t *testing.T) {
6+
t.Parallel()
7+
8+
type args struct {
9+
pkg string
10+
versions []string
11+
}
12+
tests := []struct {
13+
name string
14+
args args
15+
wantErr bool
16+
}{
17+
{
18+
name: "multiple_versions_which_all_exist",
19+
args: args{
20+
pkg: "gdata",
21+
versions: []string{"2.7.1", "2.12.0.2", "2.18.0.1", "2.19.0"},
22+
},
23+
wantErr: false,
24+
},
25+
{
26+
name: "multiple_versions_with_one_that_does_not_exist",
27+
args: args{
28+
pkg: "gdata",
29+
versions: []string{"2.4.1", "2.9.1", "2.12.0"},
30+
},
31+
wantErr: true,
32+
},
33+
{
34+
name: "an_invalid_version",
35+
args: args{
36+
pkg: "gdata",
37+
versions: []string{"!"},
38+
},
39+
wantErr: true,
40+
},
41+
{
42+
name: "an_invalid_package",
43+
args: args{
44+
pkg: "!",
45+
versions: []string{"1.0.0"},
46+
},
47+
wantErr: true,
48+
},
49+
{
50+
name: "a_package_that_does_not_exit",
51+
args: args{
52+
pkg: "not-a-real-package-hopefully",
53+
versions: []string{"1.0.0"},
54+
},
55+
wantErr: true,
56+
},
57+
}
58+
for _, tt := range tests {
59+
t.Run(tt.name, func(t *testing.T) {
60+
t.Parallel()
61+
62+
if err := versionsExistInCran(tt.args.pkg, tt.args.versions); (err != nil) != tt.wantErr {
63+
t.Errorf("versionsExistInCran() error = %v, wantErr %v", err, tt.wantErr)
64+
}
65+
})
66+
}
67+
}
68+
569
func Test_versionsExistInCrates(t *testing.T) {
670
t.Parallel()
771

tools/osv-linter/internal/pkgchecker/package_check.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ import (
88
"github.com/ossf/osv-schema/linter/internal/faulttolerant"
99
)
1010

11+
// Validate the existence of a package in CRAN.
12+
func existsInCran(pkg string) bool {
13+
ecosystem := "CRAN"
14+
packageInstanceURL := fmt.Sprintf("%s/%s", EcosystemBaseURLs[ecosystem], pkg)
15+
16+
return checkPackageExists(packageInstanceURL)
17+
}
18+
1119
// Validate the existence of a package in crates.io.
1220
func existsInCrates(pkg string) bool {
1321
// Handle special case for rust standard library

tools/osv-linter/internal/pkgchecker/package_check_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@ import (
44
"testing"
55
)
66

7+
func Test_existsInCran(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
pkg string
11+
want bool
12+
}{
13+
{
14+
name: "existing package",
15+
pkg: "igraph",
16+
want: true,
17+
},
18+
{
19+
name: "non-existing package",
20+
pkg: "non-existing-package",
21+
want: false,
22+
},
23+
}
24+
for _, tt := range tests {
25+
t.Run(tt.name, func(t *testing.T) {
26+
if got := existsInCran(tt.pkg); got != tt.want {
27+
t.Errorf("existsInCran() = %v, want %v", got, tt.want)
28+
}
29+
})
30+
}
31+
}
32+
733
func Test_existsInCrates(t *testing.T) {
834
tests := []struct {
935
name string

tools/osv-linter/internal/pkgchecker/version_check.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ func versionsExistInGeneric(
8989
return nil
9090
}
9191

92+
// Confirm that all specified versions of a package exist in CRAN.
93+
func versionsExistInCran(pkg string, versions []string) error {
94+
packageInstanceURL := fmt.Sprintf("%s/%s/all", EcosystemBaseURLs["CRAN"], pkg)
95+
96+
return versionsExistInGeneric(
97+
pkg, versions,
98+
"CRAN",
99+
packageInstanceURL,
100+
"versions.@keys",
101+
)
102+
}
103+
92104
// Confirm that all specified versions of a package exist in crates.io.
93105
func versionsExistInCrates(pkg string, versions []string) error {
94106
packageInstanceURL := fmt.Sprintf("%s/%s", EcosystemBaseURLs["crates.io"], pkg)

0 commit comments

Comments
 (0)