From d642a94af5e69853653e04c18482ab9f1670145b Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 9 Jul 2021 06:40:59 -0700 Subject: [PATCH] Add support for packages[].platforms[].deprecated property of package index This is a recently added package index property that allows platform developers to specify that a release is deprecated in a machine-readable manner. This is used to enhanced the platform listings in Boards Manager. --- ...uino-package-index-definitions-schema.json | 31 ++++++++++++++++++ .../packageindex/packageindexschemas_test.go | 6 ++++ .../ruleconfiguration/ruleconfiguration.go | 16 ++++++++++ internal/rule/rulefunction/packageindex.go | 20 ++++++++++++ .../rule/rulefunction/packageindex_test.go | 10 ++++++ .../package_foo_index.json | 32 +++++++++++++++++++ internal/rule/schema/schemadata/bindata.go | 31 ++++++++++++++++++ 7 files changed, 146 insertions(+) create mode 100644 internal/rule/rulefunction/testdata/packageindexes/packages-platforms-deprecated-incorrect-type/package_foo_index.json diff --git a/etc/schemas/arduino-package-index-definitions-schema.json b/etc/schemas/arduino-package-index-definitions-schema.json index 3d0968e3..9902fdee 100644 --- a/etc/schemas/arduino-package-index-definitions-schema.json +++ b/etc/schemas/arduino-package-index-definitions-schema.json @@ -425,6 +425,9 @@ "version": { "$ref": "#/definitions/propertiesObjects/platformVersion/permissive/object" }, + "deprecated": { + "$ref": "#/definitions/propertiesObjects/deprecated/permissive/object" + }, "category": { "$ref": "#/definitions/propertiesObjects/category/permissive/object" }, @@ -474,6 +477,9 @@ "version": { "$ref": "#/definitions/propertiesObjects/platformVersion/specification/object" }, + "deprecated": { + "$ref": "#/definitions/propertiesObjects/deprecated/specification/object" + }, "category": { "$ref": "#/definitions/propertiesObjects/category/specification/object" }, @@ -523,6 +529,9 @@ "version": { "$ref": "#/definitions/propertiesObjects/platformVersion/strict/object" }, + "deprecated": { + "$ref": "#/definitions/propertiesObjects/deprecated/strict/object" + }, "category": { "$ref": "#/definitions/propertiesObjects/category/strict/object" }, @@ -644,6 +653,28 @@ } } }, + "deprecated": { + "base": { + "object": { + "type": "boolean" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/deprecated/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/deprecated/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/deprecated/specification/object" + } + } + }, "category": { "base": { "object": { diff --git a/internal/project/packageindex/packageindexschemas_test.go b/internal/project/packageindex/packageindexschemas_test.go index 5e57da39..d1184f39 100644 --- a/internal/project/packageindex/packageindexschemas_test.go +++ b/internal/project/packageindex/packageindexschemas_test.go @@ -46,6 +46,7 @@ var validIndexRaw = []byte(` "name": "Arduino AVR Boards", "architecture": "avr", "version": "1.8.3", + "deprecated": false, "category": "Contributed", "help": { "online": "http://www.arduino.cc/en/Reference/HomePage" @@ -227,6 +228,10 @@ func TestRequired(t *testing.T) { {"/packages/0/platforms/0/category", compliancelevel.Specification, assert.True}, {"/packages/0/platforms/0/category", compliancelevel.Strict, assert.True}, + {"/packages/0/platforms/0/deprecated", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/deprecated", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/deprecated", compliancelevel.Strict, assert.False}, + {"/packages/0/platforms/0/help", compliancelevel.Permissive, assert.True}, {"/packages/0/platforms/0/help", compliancelevel.Specification, assert.True}, {"/packages/0/platforms/0/help", compliancelevel.Strict, assert.True}, @@ -534,6 +539,7 @@ func TestType(t *testing.T) { {"/packages/0/platforms/0/name", 42, assert.True}, {"/packages/0/platforms/0/architecture", 42, assert.True}, {"/packages/0/platforms/0/version", 42, assert.True}, + {"/packages/0/platforms/0/deprecated", 42, assert.True}, {"/packages/0/platforms/0/help", 42, assert.True}, {"/packages/0/platforms/0/help/online", 42, assert.True}, {"/packages/0/platforms/0/category", 42, assert.True}, diff --git a/internal/rule/ruleconfiguration/ruleconfiguration.go b/internal/rule/ruleconfiguration/ruleconfiguration.go index 6ac12db3..42f6717e 100644 --- a/internal/rule/ruleconfiguration/ruleconfiguration.go +++ b/internal/rule/ruleconfiguration/ruleconfiguration.go @@ -3513,6 +3513,22 @@ var configurations = []Type{ ErrorModes: []rulemode.Type{rulemode.Strict}, RuleFunction: rulefunction.PackageIndexPackagesPlatformsVersionNonSemver, }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "platform", + ID: "IL058", + Brief: "incorrect packages[].platforms[].deprecated type", + Description: "Must be a boolean.", + MessageTemplate: "packages[].platforms[].deprecated property has incorrect type in platform(s): {{.}}", + DisableModes: nil, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexPackagesPlatformsDeprecatedIncorrectType, + }, { ProjectType: projecttype.PackageIndex, SuperprojectType: projecttype.All, diff --git a/internal/rule/rulefunction/packageindex.go b/internal/rule/rulefunction/packageindex.go index 05557896..cb380056 100644 --- a/internal/rule/rulefunction/packageindex.go +++ b/internal/rule/rulefunction/packageindex.go @@ -848,6 +848,26 @@ func PackageIndexPackagesPlatformsVersionNonSemver() (result ruleresult.Type, ou return ruleresult.Pass, "" } +// PackageIndexPackagesPlatformsDeprecatedIncorrectType checks for incorrect type of the packages[].platforms[].deprecated property. +func PackageIndexPackagesPlatformsDeprecatedIncorrectType() (result ruleresult.Type, output string) { + if projectdata.PackageIndexLoadError() != nil { + return ruleresult.NotRun, "Error loading package index" + } + + nonCompliantIDs := []string{} + for _, platformData := range projectdata.PackageIndexPlatforms() { + if schema.PropertyTypeMismatch(platformData.JSONPointer+"/deprecated", projectdata.PackageIndexSchemaValidationResult()[compliancelevel.Specification]) { + nonCompliantIDs = append(nonCompliantIDs, platformData.ID) + } + } + + if len(nonCompliantIDs) > 0 { + return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ") + } + + return ruleresult.Pass, "" +} + // PackageIndexPackagesPlatformsCategoryMissing checks for missing packages[].platforms[].category property. func PackageIndexPackagesPlatformsCategoryMissing() (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 9af599c4..9bcbfdb3 100644 --- a/internal/rule/rulefunction/packageindex_test.go +++ b/internal/rule/rulefunction/packageindex_test.go @@ -482,6 +482,16 @@ func TestPackageIndexPackagesPlatformsVersionNonSemver(t *testing.T) { checkPackageIndexRuleFunction(PackageIndexPackagesPlatformsVersionNonSemver, testTables, t) } +func TestPackageIndexPackagesPlatformsDeprecatedIncorrectType(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, + {"Incorrect packages[].platforms[].deprecated type", "packages-platforms-deprecated-incorrect-type", ruleresult.Fail, "^foopackager:avr@1\\.0\\.0$"}, + {"Valid", "valid-package-index", ruleresult.Pass, ""}, + } + + checkPackageIndexRuleFunction(PackageIndexPackagesPlatformsDeprecatedIncorrectType, testTables, t) +} + func TestPackageIndexPackagesPlatformsCategoryMissing(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-deprecated-incorrect-type/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-deprecated-incorrect-type/package_foo_index.json new file mode 100644 index 00000000..1fe529b8 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-deprecated-incorrect-type/package_foo_index.json @@ -0,0 +1,32 @@ +{ + "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", + "deprecated": 42, + "category": "Contributed", + "help": { + "online": "http://example.com" + }, + "url": "http://example.com", + "archiveFileName": "myboard-1.0.0.zip", + "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + "size": "15005", + "boards": [], + "toolsDependencies": [] + } + ], + "tools": [] + } + ] +} diff --git a/internal/rule/schema/schemadata/bindata.go b/internal/rule/schema/schemadata/bindata.go index 5cc3418c..805b8872 100644 --- a/internal/rule/schema/schemadata/bindata.go +++ b/internal/rule/schema/schemadata/bindata.go @@ -2961,6 +2961,9 @@ var _arduinoPackageIndexDefinitionsSchemaJson = []byte(`{ "version": { "$ref": "#/definitions/propertiesObjects/platformVersion/permissive/object" }, + "deprecated": { + "$ref": "#/definitions/propertiesObjects/deprecated/permissive/object" + }, "category": { "$ref": "#/definitions/propertiesObjects/category/permissive/object" }, @@ -3010,6 +3013,9 @@ var _arduinoPackageIndexDefinitionsSchemaJson = []byte(`{ "version": { "$ref": "#/definitions/propertiesObjects/platformVersion/specification/object" }, + "deprecated": { + "$ref": "#/definitions/propertiesObjects/deprecated/specification/object" + }, "category": { "$ref": "#/definitions/propertiesObjects/category/specification/object" }, @@ -3059,6 +3065,9 @@ var _arduinoPackageIndexDefinitionsSchemaJson = []byte(`{ "version": { "$ref": "#/definitions/propertiesObjects/platformVersion/strict/object" }, + "deprecated": { + "$ref": "#/definitions/propertiesObjects/deprecated/strict/object" + }, "category": { "$ref": "#/definitions/propertiesObjects/category/strict/object" }, @@ -3180,6 +3189,28 @@ var _arduinoPackageIndexDefinitionsSchemaJson = []byte(`{ } } }, + "deprecated": { + "base": { + "object": { + "type": "boolean" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/deprecated/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/deprecated/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/deprecated/specification/object" + } + } + }, "category": { "base": { "object": {