From a60ecef26b58a1f32403ec57f1d3db302464e426 Mon Sep 17 00:00:00 2001 From: per1234 Date: Sat, 12 Jun 2021 18:57:24 -0700 Subject: [PATCH] Add schema-based rules for package data of package index These are the JSON schema-based rules to check the root and package level data of package indexes. --- .../ruleconfiguration/ruleconfiguration.go | 356 +++++++++++++- internal/rule/rulefunction/packageindex.go | 435 ++++++++++++++++++ .../rule/rulefunction/packageindex_test.go | 220 +++++++++ .../incorrect-type/package_foo_index.json | 1 + .../package_foo_index.json | 16 + .../package_foo_index.json | 15 + .../package_foo_index.json | 14 + .../package_foo_index.json | 16 + .../package_foo_index.json | 13 + .../package_foo_index.json | 15 + .../package_foo_index.json | 15 + .../package_foo_index.json | 13 + .../package_foo_index.json | 3 + .../package_foo_index.json | 15 + .../package_foo_index.json | 15 + .../package_foo_index.json | 14 + .../package_foo_index.json | 15 + .../packages-missing/package_foo_index.json | 1 + .../package_foo_index.json | 15 + .../package_foo_index.json | 15 + .../package_foo_index.json | 15 + .../package_foo_index.json | 108 +++++ .../package_foo_index.json | 15 + .../package_foo_index.json | 15 + .../package_foo_index.json | 14 + .../package_foo_index.json | 110 +++++ 26 files changed, 1497 insertions(+), 2 deletions(-) create mode 100644 internal/rule/rulefunction/testdata/packageindexes/incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-additional-properties/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-email-incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-email-missing/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-help-additional-properties/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-help-incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-help-online-incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-help-online-invalid-format/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-help-online-missing/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-length-lt/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-missing/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-starts-with-arduino/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-missing/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-name-incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-name-is-arduino/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-name-length-lt/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-name-missing/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-incorrect-type/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-invalid-format/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-missing/package_foo_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/root-additional-properties/package_foo_index.json diff --git a/internal/rule/ruleconfiguration/ruleconfiguration.go b/internal/rule/ruleconfiguration/ruleconfiguration.go index d453d004..3d34f74d 100644 --- a/internal/rule/ruleconfiguration/ruleconfiguration.go +++ b/internal/rule/ruleconfiguration/ruleconfiguration.go @@ -2925,8 +2925,248 @@ var configurations = []Type{ ProjectType: projecttype.PackageIndex, SuperprojectType: projecttype.All, Category: "data", - Subcategory: "package", + Subcategory: "root", ID: "ID003", + Brief: "Additional properties in root", + Description: "", + MessageTemplate: "Unknown properties found in package index root.", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexAdditionalProperties, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA001", + Brief: "packages[] missing", + Description: "", + MessageTemplate: "Missing packages property.", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesMissing, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA002", + Brief: "Incorrect packages type", + Description: "", + MessageTemplate: "packages property has incorrect type.", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesIncorrectType, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "root", + ID: "IA003", + Brief: "Additional properties in packages", + Description: "", + MessageTemplate: "Unknown properties found in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesAdditionalProperties, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA004", + Brief: "packages[].name missing", + Description: "", + MessageTemplate: "Missing packages[].name property in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesNameMissing, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA005", + Brief: "Incorrect packages[].name type", + Description: "The name value must be a string.", + MessageTemplate: "packages[].name property has incorrect type in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesNameIncorrectType, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA006", + Brief: "packages[].name < min length", + Description: "", + MessageTemplate: "packages[].name value less than the minimum length in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesNameLTMinLength, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA007", + Brief: "packages[].name is arduino", + Description: "Case insensitive.", + MessageTemplate: "packages[].name value is \"arduino\" in package {{.}}. This name is reserved for official packages.", + DisableModes: []rulemode.Type{rulemode.Official}, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: []rulemode.Type{rulemode.Permissive}, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesNameIsArduino, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA008", + Brief: "packages[].maintainer missing", + Description: "", + MessageTemplate: "Missing packages[].maintainer property in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesMaintainerMissing, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA009", + Brief: "Incorrect packages[].maintainer type", + Description: "The maintainer value must be a string.", + MessageTemplate: "packages[].maintainer property has incorrect type in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesMaintainerIncorrectType, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA010", + Brief: "packages[].maintainer < min length", + Description: "", + MessageTemplate: "packages[].maintainer value less than the minimum length in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesMaintainerLTMinLength, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA011", + Brief: "packages[].maintainer starts with \"arduino\"", + Description: "Case insensitive.", + MessageTemplate: "packages[].maintainer value starts with \"arduino\" in package(s): {{.}}. 3rd party packages are not maintained by Arduino.", + DisableModes: []rulemode.Type{rulemode.Official}, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: []rulemode.Type{rulemode.Default}, + ErrorModes: []rulemode.Type{rulemode.Strict}, + RuleFunction: rulefunction.PackageIndexPackagesMaintainerStartsWithArduino, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA012", + Brief: "packages[].websiteURL missing", + Description: "", + MessageTemplate: "Missing packages[].websiteURL property in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesWebsiteURLMissing, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA013", + Brief: "Incorrect packages[].websiteURL type", + Description: "Must be a string.", + MessageTemplate: "packages[].websiteURL property has incorrect type in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesWebsiteURLIncorrectType, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA014", + Brief: "Invalid packages[].websiteURL format", + Description: "", + MessageTemplate: "packages[].websiteURL property does not have a valid URL format in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesWebsiteURLInvalidFormat, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA015", Brief: "dead packages[].websiteURL", Description: "", MessageTemplate: "Unable to load the packages[].websiteURL URL for package(s): {{.}}", @@ -2942,7 +3182,119 @@ var configurations = []Type{ SuperprojectType: projecttype.All, Category: "data", Subcategory: "package", - ID: "ID004", + ID: "IA016", + Brief: "packages[].email missing", + Description: "", + MessageTemplate: "Missing packages[].email property in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesEmailMissing, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA017", + Brief: "Incorrect packages[].email type", + Description: "Must be a string.", + MessageTemplate: "packages[].email property has incorrect type in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesEmailIncorrectType, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA018", + Brief: "Incorrect packages[].help type", + Description: "Must be a string.", + MessageTemplate: "packages[].help property has incorrect type in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesHelpIncorrectType, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "root", + ID: "IA019", + Brief: "Additional properties in packages[].help", + Description: "", + MessageTemplate: "Unknown properties under packages[].help found in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesHelpAdditionalProperties, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA020", + Brief: "packages[].help.online missing", + Description: "", + MessageTemplate: "Missing packages[].help.online property in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesHelpOnlineMissing, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA021", + Brief: "Incorrect packages[].help.online type", + Description: "Must be a string.", + MessageTemplate: "packages[].help.online property has incorrect type in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesHelpOnlineIncorrectType, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA022", + Brief: "Invalid packages[].help.online format", + Description: "", + MessageTemplate: "packages[].help.online property does not have a valid URL format in package(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesHelpOnlineInvalidFormat, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "package", + ID: "IA023", Brief: "dead packages[].help.online", Description: "", MessageTemplate: "Unable to load the packages[].help.online URL for package(s): {{.}}", diff --git a/internal/rule/rulefunction/packageindex.go b/internal/rule/rulefunction/packageindex.go index 00b2ac21..f5d30d05 100644 --- a/internal/rule/rulefunction/packageindex.go +++ b/internal/rule/rulefunction/packageindex.go @@ -21,6 +21,8 @@ import ( "github.com/arduino/arduino-lint/internal/project/packageindex" "github.com/arduino/arduino-lint/internal/project/projectdata" "github.com/arduino/arduino-lint/internal/rule/ruleresult" + "github.com/arduino/arduino-lint/internal/rule/schema" + "github.com/arduino/arduino-lint/internal/rule/schema/compliancelevel" ) // The rule functions for package indexes. @@ -86,6 +88,299 @@ func PackageIndexFormat() (result ruleresult.Type, output string) { return ruleresult.Pass, "" } +// PackageIndexAdditionalProperties checks for additional properties in the package index root. +func PackageIndexAdditionalProperties() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + if schema.ProhibitedAdditionalProperties("", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + return ruleresult.Fail, "" + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesMissing checks for missing packages property. +func PackageIndexPackagesMissing() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + if schema.RequiredPropertyMissing("/packages", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + return ruleresult.Fail, "" + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesIncorrectType checks for incorrect type of packages[]. +func PackageIndexPackagesIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + if schema.PropertyTypeMismatch("/packages", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + return ruleresult.Fail, "" + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesAdditionalProperties checks for additional properties in packages[]. +func PackageIndexPackagesAdditionalProperties() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.ProhibitedAdditionalProperties(packageData.JSONPointer, projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesNameMissing checks for missing packages[].name property. +func PackageIndexPackagesNameMissing() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.RequiredPropertyMissing(packageData.JSONPointer+"/name", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesNameIncorrectType checks for incorrect type of the packages[].name property. +func PackageIndexPackagesNameIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyTypeMismatch(packageData.JSONPointer+"/name", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesNameLTMinLength checks for incorrect type of the packages[].name property. +func PackageIndexPackagesNameLTMinLength() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyLessThanMinLength(packageData.JSONPointer+"/name", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesNameIsArduino checks for packages[].name being "arduino". +func PackageIndexPackagesNameIsArduino() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.ValidationErrorMatch( + "^#"+packageData.JSONPointer+"/name$", + "/patternObjects/notArduino", + "", + "", + projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification], + ) { + // Since the package name is implicit in the rule itself, it makes most sense to use the JSON pointer to identify. + nonCompliantIDs = append(nonCompliantIDs, packageData.JSONPointer) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesMaintainerMissing checks for missing packages[].maintainer property. +func PackageIndexPackagesMaintainerMissing() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.RequiredPropertyMissing(packageData.JSONPointer+"/maintainer", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesMaintainerIncorrectType checks for incorrect type of the packages[].maintainer property. +func PackageIndexPackagesMaintainerIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyTypeMismatch(packageData.JSONPointer+"/maintainer", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesMaintainerLTMinLength checks for incorrect type of the packages[].maintainer property. +func PackageIndexPackagesMaintainerLTMinLength() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyLessThanMinLength(packageData.JSONPointer+"/maintainer", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesMaintainerStartsWithArduino checks for packages[].maintainer starting with "arduino". +func PackageIndexPackagesMaintainerStartsWithArduino() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.ValidationErrorMatch( + "^#"+packageData.JSONPointer+"/maintainer$", + "/patternObjects/notStartsWithArduino", + "", + "", + projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Strict], + ) { + // Since the package name is implicit in the rule itself, it makes most sense to use the JSON pointer to identify. + nonCompliantIDs = append(nonCompliantIDs, packageData.JSONPointer) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesWebsiteURLMissing checks for missing packages[].websiteURL property. +func PackageIndexPackagesWebsiteURLMissing() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.RequiredPropertyMissing(packageData.JSONPointer+"/websiteURL", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesWebsiteURLIncorrectType checks for incorrect type of the packages[].websiteURL property. +func PackageIndexPackagesWebsiteURLIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyTypeMismatch(packageData.JSONPointer+"/websiteURL", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesWebsiteURLInvalidFormat checks for incorrect format of the packages[].websiteURL property. +func PackageIndexPackagesWebsiteURLInvalidFormat() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyFormatMismatch(packageData.JSONPointer+"/websiteURL", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + // PackageIndexPackagesWebsiteURLDeadLink checks for dead links in packages[].websiteURL. func PackageIndexPackagesWebsiteURLDeadLink() (result ruleresult.Type, output string) { if projectdata.PackageIndexLoadError() != nil { @@ -117,6 +412,146 @@ func PackageIndexPackagesWebsiteURLDeadLink() (result ruleresult.Type, output st return ruleresult.Pass, "" } +// PackageIndexPackagesEmailMissing checks for missing packages[].email property. +func PackageIndexPackagesEmailMissing() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.RequiredPropertyMissing(packageData.JSONPointer+"/email", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesEmailIncorrectType checks for incorrect type of the packages[].email property. +func PackageIndexPackagesEmailIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyTypeMismatch(packageData.JSONPointer+"/email", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesHelpIncorrectType checks for incorrect type of the packages[].help property. +func PackageIndexPackagesHelpIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyTypeMismatch(packageData.JSONPointer+"/help", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesHelpAdditionalProperties checks for additional properties in packages[].help. +func PackageIndexPackagesHelpAdditionalProperties() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.ProhibitedAdditionalProperties(packageData.JSONPointer+"/help", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesHelpOnlineMissing checks for missing packages[].help.online property. +func PackageIndexPackagesHelpOnlineMissing() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.RequiredPropertyMissing(packageData.JSONPointer+"/help/online", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesHelpOnlineIncorrectType checks for incorrect type of the packages[].help.online property. +func PackageIndexPackagesHelpOnlineIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyTypeMismatch(packageData.JSONPointer+"/help/online", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + +// PackageIndexPackagesHelpOnlineInvalidFormat checks for incorrect format of the packages[].help.online property. +func PackageIndexPackagesHelpOnlineInvalidFormat() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, packageData := range projectdata.PackageIndexPackages() { + if schema.PropertyFormatMismatch(packageData.JSONPointer+"/help/online", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, packageData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + // PackageIndexPackagesHelpOnlineDeadLink checks for dead links in packages[].help.online. func PackageIndexPackagesHelpOnlineDeadLink() (result ruleresult.Type, output string) { if projectdata.PackageIndexLoadError() != nil { diff --git a/internal/rule/rulefunction/packageindex_test.go b/internal/rule/rulefunction/packageindex_test.go index 36508c5b..e0980bc8 100644 --- a/internal/rule/rulefunction/packageindex_test.go +++ b/internal/rule/rulefunction/packageindex_test.go @@ -111,6 +111,156 @@ func TestPackageIndexFormat(t *testing.T) { checkPackageIndexRuleFunction(PackageIndexFormat, testTables, t) } +func TestPackageIndexAdditionalProperties(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Additional root properties", "root-additional-properties", ruleresult.Fail, ""}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexAdditionalProperties, testTables, t) +} + +func TestPackageIndexPackagesMissing(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Packages key missing", "packages-missing", ruleresult.Fail, ""}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesMissing, testTables, t) +} + +func TestPackageIndexPackagesIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages type", "packages-incorrect-type", ruleresult.Fail, ""}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesIncorrectType, testTables, t) +} + +func TestPackageIndexPackagesAdditionalProperties(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Additional packages properties", "packages-additional-properties", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesAdditionalProperties, testTables, t) +} + +func TestPackageIndexPackagesNameMissing(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].name missing", "packages-name-missing", ruleresult.Fail, "^/packages/0$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesNameMissing, testTables, t) +} + +func TestPackageIndexPackagesNameIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].name type", "packages-name-incorrect-type", ruleresult.Fail, "^/packages/0$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesNameIncorrectType, testTables, t) +} + +func TestPackageIndexPackagesNameLTMinLength(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].name < min length", "packages-name-length-lt", ruleresult.Fail, "^/packages/0$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesNameLTMinLength, testTables, t) +} + +func TestPackageIndexPackagesNameIsArduino(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].name is arduino", "packages-name-is-arduino", ruleresult.Fail, "^/packages/0$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesNameIsArduino, testTables, t) +} + +func TestPackageIndexPackagesMaintainerMissing(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].maintainer missing", "packages-maintainer-missing", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesMaintainerMissing, testTables, t) +} + +func TestPackageIndexPackagesMaintainerIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].maintainer type", "packages-maintainer-incorrect-type", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesMaintainerIncorrectType, testTables, t) +} + +func TestPackageIndexPackagesMaintainerLTMinLength(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].maintainer < min length", "packages-maintainer-length-lt", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesMaintainerLTMinLength, testTables, t) +} + +func TestPackageIndexPackagesMaintainerStartsWithArduino(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].maintainer starts with arduino", "packages-maintainer-starts-with-arduino", ruleresult.Fail, "^/packages/0$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesMaintainerStartsWithArduino, testTables, t) +} + +func TestPackageIndexPackagesWebsiteURLMissing(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].websiteURL missing", "packages-websiteurl-missing", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesWebsiteURLMissing, testTables, t) +} + +func TestPackageIndexPackagesWebsiteURLIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].websiteURL type", "packages-websiteurl-incorrect-type", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesWebsiteURLIncorrectType, testTables, t) +} + +func TestPackageIndexPackagesWebsiteURLInvalidFormat(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].websiteURL format", "packages-websiteurl-invalid-format", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesWebsiteURLInvalidFormat, testTables, t) +} + func TestPackageIndexPackagesWebsiteURLDeadLink(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, @@ -122,6 +272,76 @@ func TestPackageIndexPackagesWebsiteURLDeadLink(t *testing.T) { checkPackageIndexRuleFunction(PackageIndexPackagesWebsiteURLDeadLink, testTables, t) } +func TestPackageIndexPackagesEmailMissing(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].email missing", "packages-email-missing", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesEmailMissing, testTables, t) +} + +func TestPackageIndexPackagesEmailIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].email type", "packages-email-incorrect-type", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesEmailIncorrectType, testTables, t) +} + +func TestPackageIndexPackagesHelpIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].help type", "packages-help-incorrect-type", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesHelpIncorrectType, testTables, t) +} + +func TestPackageIndexPackagesHelpAdditionalProperties(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Additional packages[].help properties", "packages-help-additional-properties", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesHelpAdditionalProperties, testTables, t) +} + +func TestPackageIndexPackagesHelpOnlineMissing(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"packages[].help.online missing", "packages-help-online-missing", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesHelpOnlineMissing, testTables, t) +} + +func TestPackageIndexPackagesHelpOnlineIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].help.online type", "packages-help-online-incorrect-type", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesHelpOnlineIncorrectType, testTables, t) +} + +func TestPackageIndexPackagesHelpOnlineInvalidFormat(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].help.online format", "packages-help-online-invalid-format", ruleresult.Fail, "^foopackager$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesHelpOnlineInvalidFormat, testTables, t) +} + func TestPackageIndexPackagesHelpOnlineDeadLink(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, diff --git a/internal/rule/rulefunction/testdata/packageindexes/incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/incorrect-type/package_foo_index.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/incorrect-type/package_foo_index.json @@ -0,0 +1 @@ +[] diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-additional-properties/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-additional-properties/package_foo_index.json new file mode 100644 index 00000000..1c8cd981 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-additional-properties/package_foo_index.json @@ -0,0 +1,16 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [], + "foo": "bar" + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-email-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-email-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..8fd318b1 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-email-incorrect-type/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": 42, + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-email-missing/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-email-missing/package_foo_index.json new file mode 100644 index 00000000..7cb67365 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-email-missing/package_foo_index.json @@ -0,0 +1,14 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-help-additional-properties/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-help-additional-properties/package_foo_index.json new file mode 100644 index 00000000..8769b30d --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-help-additional-properties/package_foo_index.json @@ -0,0 +1,16 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com", + "foo": "bar" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-help-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-help-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..9bea2ace --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-help-incorrect-type/package_foo_index.json @@ -0,0 +1,13 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": "foo", + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..dc41f16d --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-incorrect-type/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": 42 + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-invalid-format/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-invalid-format/package_foo_index.json new file mode 100644 index 00000000..0897c2bf --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-invalid-format/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "foo" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-missing/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-missing/package_foo_index.json new file mode 100644 index 00000000..5b590b7b --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-missing/package_foo_index.json @@ -0,0 +1,13 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": {}, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..465542a7 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-incorrect-type/package_foo_index.json @@ -0,0 +1,3 @@ +{ + "packages": "foo" +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..9730158b --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-incorrect-type/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": 42, + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-length-lt/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-length-lt/package_foo_index.json new file mode 100644 index 00000000..ddcc4643 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-length-lt/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-missing/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-missing/package_foo_index.json new file mode 100644 index 00000000..ee35914f --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-missing/package_foo_index.json @@ -0,0 +1,14 @@ +{ + "packages": [ + { + "name": "foopackager", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-starts-with-arduino/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-starts-with-arduino/package_foo_index.json new file mode 100644 index 00000000..eca3d1e4 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-maintainer-starts-with-arduino/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Arduino Fan", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-missing/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-missing/package_foo_index.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-missing/package_foo_index.json @@ -0,0 +1 @@ +{} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-name-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-name-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..d560677c --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-name-incorrect-type/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": 42, + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-name-is-arduino/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-name-is-arduino/package_foo_index.json new file mode 100644 index 00000000..2a316688 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-name-is-arduino/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "arduino", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-name-length-lt/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-name-length-lt/package_foo_index.json new file mode 100644 index 00000000..7df28073 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-name-length-lt/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-name-missing/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-name-missing/package_foo_index.json new file mode 100644 index 00000000..e5710ae2 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-name-missing/package_foo_index.json @@ -0,0 +1,108 @@ +{ + "packages": [ + { + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [ + { + "name": "My Board", + "architecture": "avr", + "version": "1.0.0", + "category": "Contributed", + "help": { + "online": "http://example.com" + }, + "url": "http://example.com", + "archiveFileName": "myboard-1.0.0.zip", + "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + "size": "15005", + "boards": [{ "name": "My Board" }, { "name": "My Board Pro" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "4.8.1-arduino5" + }, + { + "packager": "arduino", + "name": "avrdude", + "version": "6.0.1-arduino5" + } + ] + }, + { + "name": "My Board", + "architecture": "avr", + "version": "1.0.1", + "category": "Contributed", + "help": { + "online": "http://example.com" + }, + "url": "http://example.com", + "archiveFileName": "myboard-1.0.1.zip", + "checksum": "SHA-256:9c86ee28a7ce9fe33e8b07ec643316131e0031b0d22e63bb398902a5fdadbca9", + "size": "15125", + "boards": [{ "name": "My Board" }, { "name": "My Board Pro" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "4.8.1-arduino5" + }, + { + "packager": "arduino", + "name": "avrdude", + "version": "6.0.1-arduino5" + } + ] + } + ], + "tools": [ + { + "name": "openocd", + "version": "0.11.0-arduino2", + "systems": [ + { + "size": "1902818", + "checksum": "SHA-256:a1aa7f1435a61eafb72ee90722f2496d6a34a7a0f085d0315c2613e4a548b824", + "host": "aarch64-linux-gnu", + "archiveFileName": "openocd-0.11.0-arduino2-static-aarch64-linux-gnu.tar.bz2", + "url": "http://example.com" + }, + { + "size": "1986716", + "checksum": "SHA-256:57041130160be086e69387cceb4616eefc9819a0ef75de1f7c11aea57fb92699", + "host": "arm-linux-gnueabihf", + "archiveFileName": "openocd-0.11.0-arduino2-static-arm-linux-gnueabihf.tar.bz2", + "url": "http://example.com" + } + ] + }, + { + "name": "CMSIS", + "version": "4.0.0-atmel", + "systems": [ + { + "host": "arm-linux-gnueabihf", + "url": "http://example.com", + "archiveFileName": "CMSIS-4.0.0.tar.bz2", + "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", + "size": "17642623" + }, + { + "host": "i686-mingw32", + "url": "http://example.com", + "archiveFileName": "CMSIS-4.0.0.tar.bz2", + "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", + "size": "17642623" + } + ] + } + ] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..d85a33cc --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-incorrect-type/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": 42, + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-invalid-format/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-invalid-format/package_foo_index.json new file mode 100644 index 00000000..ea0a6753 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-invalid-format/package_foo_index.json @@ -0,0 +1,15 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "foo", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-missing/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-missing/package_foo_index.json new file mode 100644 index 00000000..3d705253 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-missing/package_foo_index.json @@ -0,0 +1,14 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [], + "tools": [] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/root-additional-properties/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/root-additional-properties/package_foo_index.json new file mode 100644 index 00000000..84df15df --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/root-additional-properties/package_foo_index.json @@ -0,0 +1,110 @@ +{ + "packages": [ + { + "name": "foopackager", + "maintainer": "Jane Developer", + "websiteURL": "http://example.com", + "email": "jane@example.com", + "help": { + "online": "http://example.com" + }, + "platforms": [ + { + "name": "My Board", + "architecture": "avr", + "version": "1.0.0", + "category": "Contributed", + "help": { + "online": "http://example.com" + }, + "url": "http://example.com", + "archiveFileName": "myboard-1.0.0.zip", + "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + "size": "15005", + "boards": [{ "name": "My Board" }, { "name": "My Board Pro" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "4.8.1-arduino5" + }, + { + "packager": "arduino", + "name": "avrdude", + "version": "6.0.1-arduino5" + } + ] + }, + { + "name": "My Board", + "architecture": "avr", + "version": "1.0.1", + "category": "Contributed", + "help": { + "online": "http://example.com" + }, + "url": "http://example.com", + "archiveFileName": "myboard-1.0.1.zip", + "checksum": "SHA-256:9c86ee28a7ce9fe33e8b07ec643316131e0031b0d22e63bb398902a5fdadbca9", + "size": "15125", + "boards": [{ "name": "My Board" }, { "name": "My Board Pro" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "4.8.1-arduino5" + }, + { + "packager": "arduino", + "name": "avrdude", + "version": "6.0.1-arduino5" + } + ] + } + ], + "tools": [ + { + "name": "openocd", + "version": "0.11.0-arduino2", + "systems": [ + { + "size": "1902818", + "checksum": "SHA-256:a1aa7f1435a61eafb72ee90722f2496d6a34a7a0f085d0315c2613e4a548b824", + "host": "aarch64-linux-gnu", + "archiveFileName": "openocd-0.11.0-arduino2-static-aarch64-linux-gnu.tar.bz2", + "url": "http://example.com" + }, + { + "size": "1986716", + "checksum": "SHA-256:57041130160be086e69387cceb4616eefc9819a0ef75de1f7c11aea57fb92699", + "host": "arm-linux-gnueabihf", + "archiveFileName": "openocd-0.11.0-arduino2-static-arm-linux-gnueabihf.tar.bz2", + "url": "http://example.com" + } + ] + }, + { + "name": "CMSIS", + "version": "4.0.0-atmel", + "systems": [ + { + "host": "arm-linux-gnueabihf", + "url": "http://example.com", + "archiveFileName": "CMSIS-4.0.0.tar.bz2", + "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", + "size": "17642623" + }, + { + "host": "i686-mingw32", + "url": "http://example.com", + "archiveFileName": "CMSIS-4.0.0.tar.bz2", + "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", + "size": "17642623" + } + ] + } + ] + } + ], + "foo": "bar" +}