diff --git a/tools/osv-linter/internal/pkgchecker/ecosystems.go b/tools/osv-linter/internal/pkgchecker/ecosystems.go index 9ad81a8..14a3491 100644 --- a/tools/osv-linter/internal/pkgchecker/ecosystems.go +++ b/tools/osv-linter/internal/pkgchecker/ecosystems.go @@ -145,7 +145,7 @@ func VersionsExistInEcosystem(pkg string, versions []string, ecosystem string) e case "GSD": return nil case "Hackage": - return nil + return versionsExistInHackage(pkg, versions) case "Hex": return nil case "Linux": diff --git a/tools/osv-linter/internal/pkgchecker/ecosystems_test.go b/tools/osv-linter/internal/pkgchecker/ecosystems_test.go index a7abcb1..64b8c97 100644 --- a/tools/osv-linter/internal/pkgchecker/ecosystems_test.go +++ b/tools/osv-linter/internal/pkgchecker/ecosystems_test.go @@ -102,6 +102,70 @@ func Test_versionsExistInGo(t *testing.T) { } } +func Test_versionsExistInHackage(t *testing.T) { + t.Parallel() + + type args struct { + pkg string + versions []string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "multiple_versions_which_all_exist", + args: args{ + pkg: "aeson", + versions: []string{"0.1.0.0", "1.4.7.1", "2.2.2.0"}, + }, + wantErr: false, + }, + { + name: "multiple_versions_with_one_that_does_not_exist", + args: args{ + pkg: "aeson", + versions: []string{"1.1", "2.0.0-beta1", "3.1.5", "2.2.2.2"}, + }, + wantErr: true, + }, + { + name: "an_invalid_version", + args: args{ + pkg: "aeson", + versions: []string{"!"}, + }, + wantErr: true, + }, + { + name: "an_invalid_package", + args: args{ + pkg: "!", + versions: []string{"1.0.0"}, + }, + wantErr: true, + }, + { + name: "a_package_that_does_not_exit", + args: args{ + pkg: "not-a-real-package-hopefully", + versions: []string{"1.0.0"}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + if err := versionsExistInHackage(tt.args.pkg, tt.args.versions); (err != nil) != tt.wantErr { + t.Errorf("versionsExistInHackage() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func Test_versionsExistInNpm(t *testing.T) { t.Parallel() diff --git a/tools/osv-linter/internal/pkgchecker/version_check.go b/tools/osv-linter/internal/pkgchecker/version_check.go index 6852e82..3167847 100644 --- a/tools/osv-linter/internal/pkgchecker/version_check.go +++ b/tools/osv-linter/internal/pkgchecker/version_check.go @@ -188,6 +188,18 @@ func goVersionsExist(versions []string) error { return nil } +// Confirm that all specified versions of a package exist in Hackage. +func versionsExistInHackage(pkg string, versions []string) error { + packageInstanceURL := fmt.Sprintf("%s/%s.json", EcosystemBaseURLs["Hackage"], pkg) + + return versionsExistInGeneric( + pkg, versions, + "Hackage", + packageInstanceURL, + "@keys", + ) +} + // Confirm that all specified versions of a package exist in npm. func versionsExistInNpm(pkg string, versions []string) error { packageInstanceURL := fmt.Sprintf("%s/%s", EcosystemBaseURLs["npm"], pkg)