diff --git a/etc/schemas/arduino-library-properties-definitions-schema.json b/etc/schemas/arduino-library-properties-definitions-schema.json index 5a38ff6b..a8630aa1 100644 --- a/etc/schemas/arduino-library-properties-definitions-schema.json +++ b/etc/schemas/arduino-library-properties-definitions-schema.json @@ -6,11 +6,6 @@ "definitions": { "general": { "patternObjects": { - "notStartsWithArduino": { - "not": { - "pattern": "^[aA][rR][dD][uU][iI][nN][oO].*$" - } - }, "notContainsArduino": { "not": { "pattern": "^.+[aA][rR][dD][uU][iI][nN][oO].*$" @@ -69,7 +64,7 @@ }, { "$comment": "Only official Arduino libraries are allowed to have names starting with \"Arduino\"", - "$ref": "#/definitions/general/patternObjects/notStartsWithArduino" + "$ref": "general-definitions-schema.json#/definitions/patternObjects/notStartsWithArduino" } ] } @@ -228,7 +223,7 @@ }, { "$comment": "Only official Arduino libraries are allowed to have maintainer field starting with \"Arduino\"", - "$ref": "#/definitions/general/patternObjects/notStartsWithArduino" + "$ref": "general-definitions-schema.json#/definitions/patternObjects/notStartsWithArduino" } ] } diff --git a/etc/schemas/arduino-package-index-definitions-schema.json b/etc/schemas/arduino-package-index-definitions-schema.json new file mode 100644 index 00000000..bbdf1c54 --- /dev/null +++ b/etc/schemas/arduino-package-index-definitions-schema.json @@ -0,0 +1,1324 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-definitions-schema.json", + "title": "Shared definitions for the Arduino Package Index schemas", + "definitions": { + "root": { + "base": { + "object": { + "type": "object", + "required": ["packages"] + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/root/base/object" + }, + { + "properties": { + "packages": { + "$ref": "#/definitions/propertiesObjects/packages/permissive/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/root/base/object" + }, + { + "properties": { + "packages": { + "$ref": "#/definitions/propertiesObjects/packages/specification/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/root/base/object" + }, + { + "properties": { + "packages": { + "$ref": "#/definitions/propertiesObjects/packages/strict/object" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "propertiesObjects": { + "packages": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "$comment": "help property is currently undocumented, so considered optional.", + "required": ["name", "maintainer", "websiteURL", "email", "platforms", "tools"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packages/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/packageName/permissive/object" + }, + "maintainer": { + "$ref": "#/definitions/propertiesObjects/maintainer/permissive/object" + }, + "websiteURL": { + "$ref": "#/definitions/propertiesObjects/websiteURL/permissive/object" + }, + "email": { + "$ref": "#/definitions/propertiesObjects/email/permissive/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/permissive/object" + }, + "platforms": { + "$ref": "#/definitions/propertiesObjects/platforms/permissive/object" + }, + "tools": { + "$ref": "#/definitions/propertiesObjects/tools/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packages/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/packageName/specification/object" + }, + "maintainer": { + "$ref": "#/definitions/propertiesObjects/maintainer/specification/object" + }, + "websiteURL": { + "$ref": "#/definitions/propertiesObjects/websiteURL/specification/object" + }, + "email": { + "$ref": "#/definitions/propertiesObjects/email/specification/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/specification/object" + }, + "platforms": { + "$ref": "#/definitions/propertiesObjects/platforms/specification/object" + }, + "tools": { + "$ref": "#/definitions/propertiesObjects/tools/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packages/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/packageName/strict/object" + }, + "maintainer": { + "$ref": "#/definitions/propertiesObjects/maintainer/strict/object" + }, + "websiteURL": { + "$ref": "#/definitions/propertiesObjects/websiteURL/strict/object" + }, + "email": { + "$ref": "#/definitions/propertiesObjects/email/strict/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/strict/object" + }, + "platforms": { + "$ref": "#/definitions/propertiesObjects/platforms/strict/object" + }, + "tools": { + "$ref": "#/definitions/propertiesObjects/tools/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "packageName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/packageName/base/object" + } + }, + "specification": { + "definitions": { + "patternObjects": { + "notArduino": { + "not": { + "pattern": "^[aA][rR][dD][uU][iI][nN][oO]$" + } + } + } + }, + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packageName/base/object" + }, + { + "$comment": "Only official Arduino packages are allowed to use the \"arduino\" vendor name", + "$ref": "#/definitions/propertiesObjects/packageName/specification/definitions/patternObjects/notArduino" + } + ] + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/packageName/specification/object" + } + } + }, + "maintainer": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/maintainer/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/maintainer/base/object" + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/maintainer/specification/object" + }, + { + "$comment": "Only official Arduino packages are allowed to have maintainer field starting with \"Arduino\"", + "$ref": "general-definitions-schema.json#/definitions/patternObjects/notStartsWithArduino" + } + ] + } + } + }, + "websiteURL": { + "base": { + "object": { + "type": "string", + "format": "uri" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/websiteURL/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/websiteURL/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/websiteURL/specification/object" + } + } + }, + "email": { + "base": { + "object": { + "type": "string" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/email/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/email/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/email/specification/object" + } + } + }, + "help": { + "$comment": "Schema for package and platform help objects.", + "base": { + "object": { + "type": "object", + "required": ["online"] + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/help/base/object" + }, + { + "properties": { + "online": { + "$ref": "#/definitions/propertiesObjects/online/permissive/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/help/base/object" + }, + { + "properties": { + "online": { + "$ref": "#/definitions/propertiesObjects/online/specification/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/help/base/object" + }, + { + "properties": { + "online": { + "$ref": "#/definitions/propertiesObjects/online/strict/object" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "online": { + "base": { + "object": { + "type": "string", + "format": "uri" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/online/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/online/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/online/specification/object" + } + } + }, + "platforms": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "architecture", + "version", + "category", + "help", + "url", + "archiveFileName", + "checksum", + "size", + "boards", + "toolsDependencies" + ] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platforms/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/platformName/permissive/object" + }, + "architecture": { + "$ref": "#/definitions/propertiesObjects/architecture/permissive/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/platformVersion/permissive/object" + }, + "category": { + "$ref": "#/definitions/propertiesObjects/category/permissive/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/permissive/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/permissive/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/permissive/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/permissive/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/permissive/object" + }, + "boards": { + "$ref": "#/definitions/propertiesObjects/boards/permissive/object" + }, + "toolsDependencies": { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platforms/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/platformName/specification/object" + }, + "architecture": { + "$ref": "#/definitions/propertiesObjects/architecture/specification/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/platformVersion/specification/object" + }, + "category": { + "$ref": "#/definitions/propertiesObjects/category/specification/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/specification/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/specification/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/specification/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/specification/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/specification/object" + }, + "boards": { + "$ref": "#/definitions/propertiesObjects/boards/specification/object" + }, + "toolsDependencies": { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platforms/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/platformName/strict/object" + }, + "architecture": { + "$ref": "#/definitions/propertiesObjects/architecture/strict/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/platformVersion/strict/object" + }, + "category": { + "$ref": "#/definitions/propertiesObjects/category/strict/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/strict/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/strict/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/strict/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/strict/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/strict/object" + }, + "boards": { + "$ref": "#/definitions/propertiesObjects/boards/strict/object" + }, + "toolsDependencies": { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "platformName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/platformName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/platformName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/platformName/specification/object" + } + } + }, + "architecture": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/architecture/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/architecture/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/architecture/specification/object" + } + } + }, + "platformVersion": { + "base": { + "object": { + "type": "string" + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platformVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platformVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platformVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/semver" + } + ] + } + } + }, + "category": { + "base": { + "object": { + "type": "string", + "enum": ["Contributed"] + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/category/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/category/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/category/specification/object" + } + } + }, + "archiveUrl": { + "$comment": "Schema for platform and tool archive URLs", + "base": { + "object": { + "type": "string", + "format": "uri" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/specification/object" + } + } + }, + "archiveFileName": { + "$comment": "Schema for platform and tool archive filenames.", + "base": { + "definitions": { + "validExtensionPattern": { + "pattern": "^.+\\.(tar\\.bz2|tar\\.gz|zip)$" + } + }, + "object": { + "allOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/definitions/propertiesObjects/archiveFileName/base/definitions/validExtensionPattern" + } + ] + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/specification/object" + } + } + }, + "checksum": { + "$comment": "Schema for platform and tool archive checksums.", + "base": { + "object": { + "type": "string", + "pattern": "^(MD5|SHA-1|SHA-256):[0-9a-fA-F]+$" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/checksum/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/checksum/base/object" + } + }, + "strict": { + "definitions": { + "patternObjects": { + "usesSHA256": { + "pattern": "^SHA-256:" + } + } + }, + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/checksum/specification/object" + }, + { + "$ref": "#/definitions/propertiesObjects/checksum/strict/definitions/patternObjects/usesSHA256" + } + ] + } + } + }, + "size": { + "$comment": "Schema for platform and tool archive file sizes.", + "base": { + "object": { + "type": "string", + "pattern": "[0-9]+" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/size/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/size/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/size/specification/object" + } + } + }, + "boards": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["name"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/boards/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/boardName/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/boards/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/boardName/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/boards/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/boardName/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "boardName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/boardName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/boardName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/boardName/specification/object" + } + } + }, + "toolsDependencies": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["packager", "name", "version"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/base/object" + }, + { + "items": { + "properties": { + "packager": { + "$ref": "#/definitions/propertiesObjects/packager/permissive/object" + }, + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/permissive/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/base/object" + }, + { + "items": { + "properties": { + "packager": { + "$ref": "#/definitions/propertiesObjects/packager/specification/object" + }, + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/specification/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/base/object" + }, + { + "items": { + "properties": { + "packager": { + "$ref": "#/definitions/propertiesObjects/packager/strict/object" + }, + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/strict/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "packager": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/packager/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/packager/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/packager/specification/object" + } + } + }, + "tools": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "version", "systems"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/tools/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/permissive/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/permissive/object" + }, + "systems": { + "$ref": "#/definitions/propertiesObjects/systems/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/tools/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/specification/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/specification/object" + }, + "systems": { + "$ref": "#/definitions/propertiesObjects/systems/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/tools/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/strict/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/strict/object" + }, + "systems": { + "$ref": "#/definitions/propertiesObjects/systems/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "toolName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/toolName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/toolName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/toolName/specification/object" + } + } + }, + "toolVersion": { + "base": { + "object": { + "type": "string" + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/semver" + } + ] + } + } + }, + "systems": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["host", "url", "archiveFileName", "size", "checksum"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/systems/base/object" + }, + { + "items": { + "properties": { + "host": { + "$ref": "#/definitions/propertiesObjects/host/permissive/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/permissive/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/permissive/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/permissive/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/systems/base/object" + }, + { + "items": { + "properties": { + "host": { + "$ref": "#/definitions/propertiesObjects/host/specification/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/specification/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/specification/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/specification/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/systems/base/object" + }, + { + "items": { + "properties": { + "host": { + "$ref": "#/definitions/propertiesObjects/host/strict/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/strict/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/strict/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/strict/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "host": { + "base": { + "definitions": { + "patternObjects": { + "validHost": { + "$comment": "https://github.com/arduino/arduino-cli/blob/cdbebe98f895c18146ea2607cfb706d002b01191/arduino/cores/tools.go#L144-L155", + "anyOf": [ + { + "pattern": "^arm.*-linux-gnueabihf$" + }, + { + "pattern": "^(aarch64|arm64)-linux-gnu$" + }, + { + "pattern": "^x86_64-.*linux-gnu$" + }, + { + "pattern": "^i[3456]86-.*linux-gnu$" + }, + { + "pattern": "^i[3456]86-.*(mingw32|cygwin)$" + }, + { + "pattern": "^(amd64|x86_64)-.*(mingw32|cygwin)$" + }, + { + "pattern": "^x86_64-apple-darwin.*$" + }, + { + "pattern": "^i[3456]86-apple-darwin.*$" + }, + { + "pattern": "^arm64-apple-darwin.*$" + }, + { + "pattern": "^arm.*-freebsd[0-9]*$" + }, + { + "pattern": "^i?[3456]86-freebsd[0-9]*$" + }, + { + "pattern": "^amd64-freebsd[0-9]*$" + } + ] + } + } + }, + "object": { + "allOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/propertiesObjects/host/base/definitions/patternObjects/validHost" + } + ] + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/host/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/host/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/host/specification/object" + } + } + } + } + } +} diff --git a/etc/schemas/arduino-package-index-permissive-schema.json b/etc/schemas/arduino-package-index-permissive-schema.json new file mode 100644 index 00000000..97ddfa0b --- /dev/null +++ b/etc/schemas/arduino-package-index-permissive-schema.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-permissive-schema.json", + "title": "Arduino Package Index JSON permissive schema", + "description": "Package indexes define Arduino hardware packages. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/. This schema defines the minimum accepted data format.", + "allOf": [ + { + "$ref": "arduino-package-index-definitions-schema.json#/definitions/root/permissive/object" + } + ] +} diff --git a/etc/schemas/arduino-package-index-schema.json b/etc/schemas/arduino-package-index-schema.json new file mode 100644 index 00000000..e5a948ef --- /dev/null +++ b/etc/schemas/arduino-package-index-schema.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-schema.json", + "title": "Arduino Package Index JSON schema", + "description": "Package indexes define Arduino hardware packages. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/. This schema defines the data format per the specification.", + "allOf": [ + { + "$ref": "arduino-package-index-definitions-schema.json#/definitions/root/specification/object" + } + ] +} diff --git a/etc/schemas/arduino-package-index-strict-schema.json b/etc/schemas/arduino-package-index-strict-schema.json new file mode 100644 index 00000000..3008876b --- /dev/null +++ b/etc/schemas/arduino-package-index-strict-schema.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-strict-schema.json", + "title": "Arduino Package Index JSON strict schema", + "description": "Package indexes define Arduino hardware packages. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/. This schema defines the best practices for the data format, above and beyond the specification.", + "allOf": [ + { + "$ref": "arduino-package-index-definitions-schema.json#/definitions/root/strict/object" + } + ] +} diff --git a/etc/schemas/general-definitions-schema.json b/etc/schemas/general-definitions-schema.json index 983972ab..5ecff6d9 100644 --- a/etc/schemas/general-definitions-schema.json +++ b/etc/schemas/general-definitions-schema.json @@ -17,6 +17,11 @@ "containsPropertyReference": { "$comment": "https://arduino.github.io/arduino-cli/dev/platform-specification/#configuration-files-format", "pattern": "{.+}" + }, + "notStartsWithArduino": { + "not": { + "pattern": "^[aA][rR][dD][uU][iI][nN][oO].*$" + } } } } diff --git a/go.mod b/go.mod index d53228e5..9cc0afd9 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/spf13/viper v1.7.1 // indirect github.com/stretchr/testify v1.6.1 github.com/xanzy/ssh-agent v0.3.0 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 go.bug.st/relaxed-semver v0.0.0-20190922224835-391e10178d18 go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.14.0 // indirect diff --git a/internal/project/library/libraryproperties/librarypropertiesschemas_test.go b/internal/project/library/libraryproperties/librarypropertiesschemas_test.go index 4fde2c83..01634f25 100644 --- a/internal/project/library/libraryproperties/librarypropertiesschemas_test.go +++ b/internal/project/library/libraryproperties/librarypropertiesschemas_test.go @@ -79,6 +79,19 @@ func checkPropertyEnumMismatch(propertyName string, testTables []propertyValueTe } } +func checkPropertyFormatMismatch(propertyName string, testTables []propertyValueTestTable, t *testing.T) { + libraryProperties := properties.NewFromHashmap(validLibraryPropertiesMap) + var validationResult map[compliancelevel.Type]schema.ValidationResult + + for _, testTable := range testTables { + validationResult = changeValueUpdateValidationResult(propertyName, testTable.propertyValue, libraryProperties, validationResult) + + t.Run(fmt.Sprintf("%s (%s)", testTable.testName, testTable.complianceLevel), func(t *testing.T) { + testTable.assertion(t, schema.PropertyFormatMismatch(propertyName, validationResult[testTable.complianceLevel])) + }) + } +} + type validationErrorTestTable struct { testName string propertyValue string @@ -322,13 +335,13 @@ func TestPropertiesCategoryEnum(t *testing.T) { } func TestPropertiesUrlFormat(t *testing.T) { - testTables := []validationErrorTestTable{ - {"Invalid URL format", "foo", "/format$", compliancelevel.Permissive, assert.False}, - {"Invalid URL format", "foo", "/format$", compliancelevel.Specification, assert.True}, - {"Invalid URL format", "foo", "/format$", compliancelevel.Strict, assert.True}, + testTables := []propertyValueTestTable{ + {"Invalid URL format", "foo", compliancelevel.Permissive, assert.False}, + {"Invalid URL format", "foo", compliancelevel.Specification, assert.True}, + {"Invalid URL format", "foo", compliancelevel.Strict, assert.True}, } - checkValidationErrorMatch("url", testTables, t) + checkPropertyFormatMismatch("url", testTables, t) } func TestPropertiesDependsPattern(t *testing.T) { diff --git a/internal/project/packageindex/packageindex.go b/internal/project/packageindex/packageindex.go index febba77a..1d0560df 100644 --- a/internal/project/packageindex/packageindex.go +++ b/internal/project/packageindex/packageindex.go @@ -20,12 +20,55 @@ See: https://arduino.github.io/arduino-cli/latest/package_index_json-specificati package packageindex import ( + "encoding/json" "fmt" "regexp" + "github.com/arduino/arduino-lint/internal/rule/schema" + "github.com/arduino/arduino-lint/internal/rule/schema/compliancelevel" + "github.com/arduino/arduino-lint/internal/rule/schema/schemadata" "github.com/arduino/go-paths-helper" ) +// Properties parses the package index from the given path and returns the data. +func Properties(packageIndexPath *paths.Path) (map[string]interface{}, error) { + rawIndex, err := packageIndexPath.ReadFile() + if err != nil { + panic(err) + } + var indexData map[string]interface{} + err = json.Unmarshal(rawIndex, &indexData) + if err != nil { + return nil, err + } + + return indexData, nil +} + +var schemaObject = make(map[compliancelevel.Type]schema.Schema) + +// Validate validates boards.txt data against the JSON schema and returns a map of the result for each compliance level. +func Validate(packageIndex map[string]interface{}) map[compliancelevel.Type]schema.ValidationResult { + referencedSchemaFilenames := []string{ + "general-definitions-schema.json", + "arduino-package-index-definitions-schema.json", + } + + var validationResults = make(map[compliancelevel.Type]schema.ValidationResult) + + if schemaObject[compliancelevel.Permissive].Compiled == nil { // Only compile the schemas once. + schemaObject[compliancelevel.Permissive] = schema.Compile("arduino-package-index-permissive-schema.json", referencedSchemaFilenames, schemadata.Asset) + schemaObject[compliancelevel.Specification] = schema.Compile("arduino-package-index-schema.json", referencedSchemaFilenames, schemadata.Asset) + schemaObject[compliancelevel.Strict] = schema.Compile("arduino-package-index-strict-schema.json", referencedSchemaFilenames, schemadata.Asset) + } + + validationResults[compliancelevel.Permissive] = schema.Validate(packageIndex, schemaObject[compliancelevel.Permissive]) + validationResults[compliancelevel.Specification] = schema.Validate(packageIndex, schemaObject[compliancelevel.Specification]) + validationResults[compliancelevel.Strict] = schema.Validate(packageIndex, schemaObject[compliancelevel.Strict]) + + return validationResults +} + var empty struct{} // Reference: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/#naming-of-the-json-index-file diff --git a/internal/project/packageindex/packageindex_test.go b/internal/project/packageindex/packageindex_test.go index 5db7e6be..8d8375e1 100644 --- a/internal/project/packageindex/packageindex_test.go +++ b/internal/project/packageindex/packageindex_test.go @@ -21,6 +21,7 @@ import ( "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var testDataPath *paths.Path @@ -33,6 +34,13 @@ func init() { testDataPath = paths.New(workingDirectory, "testdata") } +func TestProperties(t *testing.T) { + packageIndex, err := Properties(testDataPath.Join("package_valid_index.json")) + require.Nil(t, err) + + assert.NotNil(t, packageIndex) +} + func TestHasValidExtension(t *testing.T) { assert.True(t, HasValidExtension(paths.New("/foo", "bar.json"))) assert.False(t, HasValidExtension(paths.New("/foo", "bar.baz"))) diff --git a/internal/project/packageindex/packageindexschemas_test.go b/internal/project/packageindex/packageindexschemas_test.go new file mode 100644 index 00000000..436a6adb --- /dev/null +++ b/internal/project/packageindex/packageindexschemas_test.go @@ -0,0 +1,699 @@ +// This file is part of Arduino Lint. +// +// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of Arduino Lint. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +// This file contains tests for the package index JSON schemas. +package packageindex_test + +import ( + "encoding/json" + "fmt" + "strings" + "testing" + + "github.com/arduino/arduino-lint/internal/project/packageindex" + "github.com/arduino/arduino-lint/internal/rule/schema" + "github.com/arduino/arduino-lint/internal/rule/schema/compliancelevel" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/xeipuuv/gojsonpointer" +) + +var validIndexRaw = []byte(` +{ + "packages": [ + { + "name": "notarduino", + "maintainer": "NotArduino", + "websiteURL": "http://www.arduino.cc/", + "email": "packages@arduino.cc", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "platforms": [ + { + "name": "Arduino AVR Boards", + "architecture": "avr", + "version": "1.8.3", + "category": "Contributed", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "url": "http://downloads.arduino.cc/cores/avr-1.8.3.tar.bz2", + "archiveFileName": "avr-1.8.3.tar.bz2", + "checksum": "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", + "size": "4941548", + "boards": [ + {"name": "Arduino Uno"} + ], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7" + } + ] + } + ], + "tools": [ + { + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7", + "systems": [ + { + "size": "34683056", + "checksum": "SHA-256:3903553d035da59e33cff9941b857c3cb379cb0638105dfdf69c97f0acc8e7b5", + "host": "arm-linux-gnueabihf", + "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2", + "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2" + } + ] + } + ] + } + ] +} +`) + +func TestSchemaValid(t *testing.T) { + var validIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &validIndex) + require.NoError(t, err) + + validationResult := packageindex.Validate(validIndex) + + assert.Nil(t, validationResult[compliancelevel.Permissive].Result) + assert.Nil(t, validationResult[compliancelevel.Specification].Result) + assert.Nil(t, validationResult[compliancelevel.Strict].Result) +} + +func TestMinLength(t *testing.T) { + testTables := []struct { + propertyPointerString string + minLength int + complianceLevel compliancelevel.Type + }{ + {"/packages/0/name", 1, compliancelevel.Permissive}, + {"/packages/0/name", 1, compliancelevel.Specification}, + {"/packages/0/name", 1, compliancelevel.Strict}, + + {"/packages/0/maintainer", 1, compliancelevel.Permissive}, + {"/packages/0/maintainer", 1, compliancelevel.Specification}, + {"/packages/0/maintainer", 1, compliancelevel.Strict}, + + {"/packages/0/platforms/0/name", 1, compliancelevel.Permissive}, + {"/packages/0/platforms/0/name", 1, compliancelevel.Specification}, + {"/packages/0/platforms/0/name", 1, compliancelevel.Strict}, + + {"/packages/0/platforms/0/architecture", 1, compliancelevel.Permissive}, + {"/packages/0/platforms/0/architecture", 1, compliancelevel.Specification}, + {"/packages/0/platforms/0/architecture", 1, compliancelevel.Strict}, + + {"/packages/0/platforms/0/archiveFileName", 1, compliancelevel.Permissive}, + {"/packages/0/platforms/0/archiveFileName", 1, compliancelevel.Specification}, + {"/packages/0/platforms/0/archiveFileName", 1, compliancelevel.Strict}, + + {"/packages/0/platforms/0/boards/0/name", 1, compliancelevel.Permissive}, + {"/packages/0/platforms/0/boards/0/name", 1, compliancelevel.Specification}, + {"/packages/0/platforms/0/boards/0/name", 1, compliancelevel.Strict}, + + {"/packages/0/platforms/0/toolsDependencies/0/packager", 1, compliancelevel.Permissive}, + {"/packages/0/platforms/0/toolsDependencies/0/packager", 1, compliancelevel.Specification}, + {"/packages/0/platforms/0/toolsDependencies/0/packager", 1, compliancelevel.Strict}, + + {"/packages/0/platforms/0/toolsDependencies/0/name", 1, compliancelevel.Permissive}, + {"/packages/0/platforms/0/toolsDependencies/0/name", 1, compliancelevel.Specification}, + {"/packages/0/platforms/0/toolsDependencies/0/name", 1, compliancelevel.Strict}, + + {"/packages/0/tools/0/systems/0/archiveFileName", 1, compliancelevel.Permissive}, + {"/packages/0/tools/0/systems/0/archiveFileName", 1, compliancelevel.Specification}, + {"/packages/0/tools/0/systems/0/archiveFileName", 1, compliancelevel.Strict}, + + {"/packages/0/tools/0/name", 1, compliancelevel.Permissive}, + {"/packages/0/tools/0/name", 1, compliancelevel.Specification}, + {"/packages/0/tools/0/name", 1, compliancelevel.Strict}, + } + + // Test schema validation results with value length < minimum. + for _, testTable := range testTables { + var packageIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &packageIndex) + require.NoError(t, err) + + propertyPointer, err := gojsonpointer.NewJsonPointer(testTable.propertyPointerString) + require.NoError(t, err) + _, err = propertyPointer.Set(packageIndex, strings.Repeat("a", testTable.minLength-1)) + require.NoError(t, err) + + t.Run(fmt.Sprintf("%s less than minimum length of %d (%s)", testTable.propertyPointerString, testTable.minLength, testTable.complianceLevel), func(t *testing.T) { + assert.True(t, schema.PropertyLessThanMinLength(strings.TrimPrefix(testTable.propertyPointerString, "/"), packageindex.Validate(packageIndex)[testTable.complianceLevel])) + }) + + // Test schema validation results with minimum value length. + propertyPointer.Set(packageIndex, strings.Repeat("a", testTable.minLength)) + + t.Run(fmt.Sprintf("%s at minimum length of %d (%s)", testTable.propertyPointerString, testTable.minLength, testTable.complianceLevel), func(t *testing.T) { + assert.False(t, schema.PropertyLessThanMinLength(strings.TrimPrefix(testTable.propertyPointerString, "/"), packageindex.Validate(packageIndex)[testTable.complianceLevel])) + }) + } +} + +func TestRequired(t *testing.T) { + testTables := []struct { + propertyPointerString string + complianceLevel compliancelevel.Type + assertion assert.BoolAssertionFunc + }{ + {"/packages", compliancelevel.Permissive, assert.True}, + {"/packages", compliancelevel.Specification, assert.True}, + {"/packages", compliancelevel.Strict, assert.True}, + + {"/packages/0/name", compliancelevel.Permissive, assert.True}, + {"/packages/0/name", compliancelevel.Specification, assert.True}, + {"/packages/0/name", compliancelevel.Strict, assert.True}, + + {"/packages/0/maintainer", compliancelevel.Permissive, assert.True}, + {"/packages/0/maintainer", compliancelevel.Specification, assert.True}, + {"/packages/0/maintainer", compliancelevel.Strict, assert.True}, + + {"/packages/0/websiteURL", compliancelevel.Permissive, assert.True}, + {"/packages/0/websiteURL", compliancelevel.Specification, assert.True}, + {"/packages/0/websiteURL", compliancelevel.Strict, assert.True}, + + {"/packages/0/email", compliancelevel.Permissive, assert.True}, + {"/packages/0/email", compliancelevel.Specification, assert.True}, + {"/packages/0/email", compliancelevel.Strict, assert.True}, + + {"/packages/0/help", compliancelevel.Permissive, assert.False}, + {"/packages/0/help", compliancelevel.Specification, assert.False}, + {"/packages/0/help", compliancelevel.Strict, assert.False}, + + {"/packages/0/help/online", compliancelevel.Permissive, assert.True}, + {"/packages/0/help/online", compliancelevel.Specification, assert.True}, + {"/packages/0/help/online", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools", compliancelevel.Specification, assert.True}, + {"/packages/0/tools", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/name", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/name", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/name", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/architecture", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/architecture", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/architecture", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/version", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/version", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/version", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/category", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/category", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/category", compliancelevel.Strict, assert.True}, + + {"/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}, + + {"/packages/0/platforms/0/help/online", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/help/online", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/help/online", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/url", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/url", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/url", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/archiveFileName", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/archiveFileName", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/archiveFileName", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/checksum", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/checksum", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/checksum", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/size", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/size", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/size", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/boards", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/boards", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/boards", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/toolsDependencies", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/toolsDependencies", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/toolsDependencies", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/toolsDependencies/0/packager", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0/packager", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0/packager", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/toolsDependencies/0/name", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0/name", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0/name", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/toolsDependencies/0/version", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0/version", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0/version", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/name", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/name", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/name", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/version", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/version", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/version", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/host", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/host", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/host", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/url", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/url", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/url", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/archiveFileName", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/archiveFileName", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/archiveFileName", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/size", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/size", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/size", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/checksum", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/checksum", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/checksum", compliancelevel.Strict, assert.True}, + } + + for _, testTable := range testTables { + var packageIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &packageIndex) + require.NoError(t, err) + + propertyPointer, err := gojsonpointer.NewJsonPointer(testTable.propertyPointerString) + require.NoError(t, err) + _, err = propertyPointer.Delete(packageIndex) + require.NoError(t, err) + + validationResult := packageindex.Validate(packageIndex) + t.Run(fmt.Sprintf("%s (%s)", testTable.propertyPointerString, testTable.complianceLevel), func(t *testing.T) { + testTable.assertion(t, schema.RequiredPropertyMissing(strings.TrimPrefix(testTable.propertyPointerString, "/"), validationResult[testTable.complianceLevel])) + }) + } +} + +func TestEnum(t *testing.T) { + testTables := []struct { + propertyPointerString string + propertyValue string + complianceLevel compliancelevel.Type + assertion assert.BoolAssertionFunc + }{ + {"/packages/0/platforms/0/category", "Contributed", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/category", "Contributed", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/category", "Contributed", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/category", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/category", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/category", "foo", compliancelevel.Strict, assert.True}, + } + + for _, testTable := range testTables { + var packageIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &packageIndex) + require.NoError(t, err) + + propertyPointer, err := gojsonpointer.NewJsonPointer(testTable.propertyPointerString) + require.NoError(t, err) + _, err = propertyPointer.Set(packageIndex, testTable.propertyValue) + require.NoError(t, err) + + t.Run(fmt.Sprintf("%s: %s (%s)", testTable.propertyPointerString, testTable.propertyValue, testTable.complianceLevel), func(t *testing.T) { + testTable.assertion(t, schema.PropertyEnumMismatch(strings.TrimPrefix(testTable.propertyPointerString, "/"), packageindex.Validate(packageIndex)[testTable.complianceLevel])) + }) + } +} + +func TestPattern(t *testing.T) { + testTables := []struct { + propertyPointerString string + propertyValue string + complianceLevel compliancelevel.Type + assertion assert.BoolAssertionFunc + }{ + {"/packages/0/name", "foo", compliancelevel.Permissive, assert.False}, + {"/packages/0/name", "foo", compliancelevel.Specification, assert.False}, + {"/packages/0/name", "foo", compliancelevel.Strict, assert.False}, + + {"/packages/0/name", "arduino", compliancelevel.Permissive, assert.False}, + {"/packages/0/name", "arduino", compliancelevel.Specification, assert.True}, + {"/packages/0/name", "arduino", compliancelevel.Strict, assert.True}, + + {"/packages/0/name", "Arduino", compliancelevel.Permissive, assert.False}, + {"/packages/0/name", "Arduino", compliancelevel.Specification, assert.True}, + {"/packages/0/name", "Arduino", compliancelevel.Strict, assert.True}, + + {"/packages/0/name", "ARDUINO", compliancelevel.Permissive, assert.False}, + {"/packages/0/name", "ARDUINO", compliancelevel.Specification, assert.True}, + {"/packages/0/name", "ARDUINO", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/archiveFileName", "foo.tar.bz2", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/archiveFileName", "foo.tar.bz2", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/archiveFileName", "foo.tar.bz2", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/archiveFileName", "foo.tar.gz", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/archiveFileName", "foo.tar.gz", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/archiveFileName", "foo.tar.gz", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/archiveFileName", "foo.zip", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/archiveFileName", "foo.zip", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/archiveFileName", "foo.zip", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/archiveFileName", "foo.bar", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/archiveFileName", "foo.bar", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/archiveFileName", "foo.bar", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/checksum", "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/checksum", "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/checksum", "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/checksum", "SHA-1:f89bb8563bf86eb097679dce9d2b29b86d06bf66", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/checksum", "SHA-1:f89bb8563bf86eb097679dce9d2b29b86d06bf66", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/checksum", "SHA-1:f89bb8563bf86eb097679dce9d2b29b86d06bf66", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/checksum", "MD5:6c0f556759894aa1a45e8af423a08ce8", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/checksum", "MD5:6c0f556759894aa1a45e8af423a08ce8", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/checksum", "MD5:6c0f556759894aa1a45e8af423a08ce8", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/checksum", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/checksum", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/checksum", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/size", "42", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/size", "42", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/size", "42", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/size", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/size", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/size", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.tar.bz2", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.tar.bz2", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.tar.bz2", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.tar.gz", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.tar.gz", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.tar.gz", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.zip", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.zip", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.zip", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.bar", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.bar", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/archiveFileName", "foo.bar", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/checksum", "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/checksum", "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/checksum", "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/checksum", "SHA-1:f89bb8563bf86eb097679dce9d2b29b86d06bf66", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/checksum", "SHA-1:f89bb8563bf86eb097679dce9d2b29b86d06bf66", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/checksum", "SHA-1:f89bb8563bf86eb097679dce9d2b29b86d06bf66", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/checksum", "MD5:6c0f556759894aa1a45e8af423a08ce8", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/checksum", "MD5:6c0f556759894aa1a45e8af423a08ce8", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/checksum", "MD5:6c0f556759894aa1a45e8af423a08ce8", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/checksum", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/checksum", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/checksum", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/size", "42", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/size", "42", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/size", "42", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/size", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/size", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/size", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/host", "arm-linux-gnueabihf", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "arm-linux-gnueabihf", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "arm-linux-gnueabihf", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "aarch64-linux-gnu", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "aarch64-linux-gnu", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "aarch64-linux-gnu", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "arm64-linux-gnu", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "arm64-linux-gnu", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "arm64-linux-gnu", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "x86_64-linux-gnu", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "x86_64-linux-gnu", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "x86_64-linux-gnu", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "i686-mingw32", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i686-mingw32", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i686-mingw32", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "i686-cygwin", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i686-cygwin", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i686-cygwin", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "x86_64-apple-darwin", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "x86_64-apple-darwin", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "x86_64-apple-darwin", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "i386-apple-darwin11", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i386-apple-darwin11", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i386-apple-darwin11", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "i386-freebsd11", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i386-freebsd11", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "i386-freebsd11", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "amd64-freebsd11", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/host", "amd64-freebsd11", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/host", "amd64-freebsd11", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/host", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/host", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/host", "foo", compliancelevel.Strict, assert.True}, + } + + for _, testTable := range testTables { + var packageIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &packageIndex) + require.NoError(t, err) + + propertyPointer, err := gojsonpointer.NewJsonPointer(testTable.propertyPointerString) + require.NoError(t, err) + _, err = propertyPointer.Set(packageIndex, testTable.propertyValue) + require.NoError(t, err) + + t.Run(fmt.Sprintf("%s: %s (%s)", testTable.propertyPointerString, testTable.propertyValue, testTable.complianceLevel), func(t *testing.T) { + testTable.assertion(t, schema.PropertyPatternMismatch(strings.TrimPrefix(testTable.propertyPointerString, "/"), packageindex.Validate(packageIndex)[testTable.complianceLevel])) + }) + } +} + +func TestType(t *testing.T) { + testTables := []struct { + propertyPointerString string + propertyValue interface{} + assertion assert.BoolAssertionFunc + }{ + {"/packages", 42, assert.True}, + {"/packages/0/name", 42, assert.True}, + {"/packages/0/maintainer", 42, assert.True}, + {"/packages/0/websiteURL", 42, assert.True}, + {"/packages/0/email", 42, assert.True}, + {"/packages/0/help", 42, assert.True}, + {"/packages/0/help/online", 42, assert.True}, + {"/packages/0/platforms", 42, assert.True}, + {"/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/help", 42, assert.True}, + {"/packages/0/platforms/0/help/online", 42, assert.True}, + {"/packages/0/platforms/0/category", 42, assert.True}, + {"/packages/0/platforms/0/url", 42, assert.True}, + {"/packages/0/platforms/0/archiveFileName", 42, assert.True}, + {"/packages/0/platforms/0/checksum", 42, assert.True}, + {"/packages/0/platforms/0/size", 42, assert.True}, + {"/packages/0/platforms/0/boards", 42, assert.True}, + {"/packages/0/platforms/0/boards/0/name", 42, assert.True}, + {"/packages/0/platforms/0/toolsDependencies", 42, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0/packager", 42, assert.True}, + {"/packages/0/tools", 42, assert.True}, + {"/packages/0/tools/0/name", 42, assert.True}, + {"/packages/0/tools/0/version", 42, assert.True}, + {"/packages/0/tools/0/systems", 42, assert.True}, + {"/packages/0/tools/0/systems/0/host", 42, assert.True}, + {"/packages/0/tools/0/systems/0/url", 42, assert.True}, + {"/packages/0/tools/0/systems/0/archiveFileName", 42, assert.True}, + {"/packages/0/tools/0/systems/0/checksum", 42, assert.True}, + {"/packages/0/tools/0/systems/0/size", 42, assert.True}, + } + + for _, testTable := range testTables { + for _, complianceLevel := range []compliancelevel.Type{compliancelevel.Permissive, compliancelevel.Specification, compliancelevel.Strict} { + var packageIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &packageIndex) + require.NoError(t, err) + + propertyPointer, err := gojsonpointer.NewJsonPointer(testTable.propertyPointerString) + require.NoError(t, err) + _, err = propertyPointer.Set(packageIndex, testTable.propertyValue) + + t.Run(fmt.Sprintf("%s: %v (%s)", testTable.propertyPointerString, testTable.propertyValue, complianceLevel), func(t *testing.T) { + testTable.assertion(t, schema.PropertyTypeMismatch(strings.TrimPrefix(testTable.propertyPointerString, "/"), packageindex.Validate(packageIndex)[complianceLevel])) + }) + } + } +} + +func TestFormat(t *testing.T) { + testTables := []struct { + propertyPointerString string + propertyValue string + complianceLevel compliancelevel.Type + assertion assert.BoolAssertionFunc + }{ + {"/packages/0/websiteURL", "http://example.com", compliancelevel.Permissive, assert.False}, + {"/packages/0/websiteURL", "http://example.com", compliancelevel.Specification, assert.False}, + {"/packages/0/websiteURL", "http://example.com", compliancelevel.Strict, assert.False}, + + {"/packages/0/websiteURL", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/websiteURL", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/websiteURL", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/help/online", "http://example.com", compliancelevel.Permissive, assert.False}, + {"/packages/0/help/online", "http://example.com", compliancelevel.Specification, assert.False}, + {"/packages/0/help/online", "http://example.com", compliancelevel.Strict, assert.False}, + + {"/packages/0/help/online", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/help/online", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/help/online", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/help/online", "http://example.com", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/help/online", "http://example.com", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/help/online", "http://example.com", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/help/online", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/help/online", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/help/online", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/url", "http://example.com/foo.tar.bz2", compliancelevel.Permissive, assert.False}, + {"/packages/0/platforms/0/url", "http://example.com/foo.tar.bz2", compliancelevel.Specification, assert.False}, + {"/packages/0/platforms/0/url", "http://example.com/foo.tar.bz2", compliancelevel.Strict, assert.False}, + + {"/packages/0/platforms/0/url", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/url", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/url", "foo", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0/url", "http://example.com/foo.tar.bz2", compliancelevel.Permissive, assert.False}, + {"/packages/0/tools/0/systems/0/url", "http://example.com/foo.tar.bz2", compliancelevel.Specification, assert.False}, + {"/packages/0/tools/0/systems/0/url", "http://example.com/foo.tar.bz2", compliancelevel.Strict, assert.False}, + + {"/packages/0/tools/0/systems/0/url", "foo", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0/url", "foo", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0/url", "foo", compliancelevel.Strict, assert.True}, + } + + for _, testTable := range testTables { + var packageIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &packageIndex) + require.NoError(t, err) + + propertyPointer, err := gojsonpointer.NewJsonPointer(testTable.propertyPointerString) + require.NoError(t, err) + _, err = propertyPointer.Set(packageIndex, testTable.propertyValue) + require.NoError(t, err) + + t.Run(fmt.Sprintf("%s: %s (%s)", testTable.propertyPointerString, testTable.propertyValue, testTable.complianceLevel), func(t *testing.T) { + testTable.assertion(t, schema.PropertyFormatMismatch(strings.TrimPrefix(testTable.propertyPointerString, "/"), packageindex.Validate(packageIndex)[testTable.complianceLevel])) + }) + } +} + +func TestAdditionalProperties(t *testing.T) { + testTables := []struct { + propertyPointerString string + complianceLevel compliancelevel.Type + assertion assert.BoolAssertionFunc + }{ + // Root + {"", compliancelevel.Permissive, assert.True}, + {"", compliancelevel.Specification, assert.True}, + {"", compliancelevel.Strict, assert.True}, + + {"/packages/0", compliancelevel.Permissive, assert.True}, + {"/packages/0", compliancelevel.Specification, assert.True}, + {"/packages/0", compliancelevel.Strict, assert.True}, + + {"/packages/0/help", compliancelevel.Permissive, assert.True}, + {"/packages/0/help", compliancelevel.Specification, assert.True}, + {"/packages/0/help", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0", compliancelevel.Strict, assert.True}, + + {"/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}, + + {"/packages/0/platforms/0/boards/0", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/boards/0", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/boards/0", compliancelevel.Strict, assert.True}, + + {"/packages/0/platforms/0/toolsDependencies/0", compliancelevel.Permissive, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0", compliancelevel.Specification, assert.True}, + {"/packages/0/platforms/0/toolsDependencies/0", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0", compliancelevel.Strict, assert.True}, + + {"/packages/0/tools/0/systems/0", compliancelevel.Permissive, assert.True}, + {"/packages/0/tools/0/systems/0", compliancelevel.Specification, assert.True}, + {"/packages/0/tools/0/systems/0", compliancelevel.Strict, assert.True}, + } + + for _, testTable := range testTables { + var packageIndex map[string]interface{} + err := json.Unmarshal(validIndexRaw, &packageIndex) + require.NoError(t, err) + + // Add an additional property to the object. + propertyPointer, err := gojsonpointer.NewJsonPointer(testTable.propertyPointerString + "/fooAdditionalProperty") + require.NoError(t, err) + _, err = propertyPointer.Set(packageIndex, "bar") + require.NoError(t, err) + + t.Run(fmt.Sprintf("Additional property in the %s object (%s)", testTable.propertyPointerString, testTable.complianceLevel), func(t *testing.T) { + testTable.assertion(t, schema.ProhibitedAdditionalProperties(strings.TrimPrefix(testTable.propertyPointerString, "/"), packageindex.Validate(packageIndex)[testTable.complianceLevel])) + }) + } +} diff --git a/internal/project/packageindex/testdata/package_valid_index.json b/internal/project/packageindex/testdata/package_valid_index.json new file mode 100644 index 00000000..7938a2aa --- /dev/null +++ b/internal/project/packageindex/testdata/package_valid_index.json @@ -0,0 +1,51 @@ +{ + "packages": [ + { + "name": "notarduino", + "maintainer": "NotArduino", + "websiteURL": "http://www.arduino.cc/", + "email": "packages@arduino.cc", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "platforms": [ + { + "name": "Arduino AVR Boards", + "architecture": "avr", + "version": "1.8.3", + "category": "Contributed", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "url": "http://downloads.arduino.cc/cores/avr-1.8.3.tar.bz2", + "archiveFileName": "avr-1.8.3.tar.bz2", + "checksum": "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", + "size": "4941548", + "boards": [{ "name": "Arduino Uno" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7" + } + ] + } + ], + "tools": [ + { + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7", + "systems": [ + { + "size": "34683056", + "checksum": "SHA-256:3903553d035da59e33cff9941b857c3cb379cb0638105dfdf69c97f0acc8e7b5", + "host": "arm-linux-gnueabihf", + "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2", + "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2" + } + ] + } + ] + } + ] +} diff --git a/internal/rule/schema/parsevalidationresult.go b/internal/rule/schema/parsevalidationresult.go index 4595aeab..7d122de5 100644 --- a/internal/rule/schema/parsevalidationresult.go +++ b/internal/rule/schema/parsevalidationresult.go @@ -54,6 +54,21 @@ func PropertyDependenciesMissing(propertyName string, validationResult Validatio return ValidationErrorMatch("", "/dependencies/"+propertyName+"/[0-9]+$", "", "", validationResult) } +// PropertyTypeMismatch returns whether the given property has incorrect type. +func PropertyTypeMismatch(propertyName string, validationResult ValidationResult) bool { + return ValidationErrorMatch("^#/"+propertyName+"$", "/type$", "", "", validationResult) +} + +// PropertyFormatMismatch returns whether the given property has incorrect format. +func PropertyFormatMismatch(propertyName string, validationResult ValidationResult) bool { + return ValidationErrorMatch("^#/"+propertyName+"$", "/format$", "", "", validationResult) +} + +// ProhibitedAdditionalProperty returns whether the given property has prohibited additional subproperty(s). +func ProhibitedAdditionalProperties(propertyName string, validationResult ValidationResult) bool { + return ValidationErrorMatch("^#/?"+propertyName+"$", "/additionalProperties$", "", "", validationResult) +} + // MisspelledOptionalPropertyFound returns whether a misspelled optional property was found. func MisspelledOptionalPropertyFound(validationResult ValidationResult) bool { return ValidationErrorMatch("#/", "/misspelledOptionalProperties/", "", "", validationResult) diff --git a/internal/rule/schema/schema_test.go b/internal/rule/schema/schema_test.go index 100ba76d..86fd78f1 100644 --- a/internal/rule/schema/schema_test.go +++ b/internal/rule/schema/schema_test.go @@ -16,7 +16,10 @@ package schema import ( + "encoding/json" + "fmt" "regexp" + "strings" "testing" "github.com/arduino/arduino-lint/internal/project/general" @@ -25,6 +28,7 @@ import ( "github.com/ory/jsonschema/v3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/xeipuuv/gojsonpointer" ) var validMap = map[string]string{ @@ -150,6 +154,94 @@ func TestPropertyEnumMismatch(t *testing.T) { assert.True(t, PropertyEnumMismatch("property3", validationResult)) } +func TestPropertyTypeMismatch(t *testing.T) { + propertyName := "TestPropertyTypeMismatch" + instanceTemplate := ` +{ + "%s": "foo" +} +` + rawInstance := fmt.Sprintf(instanceTemplate, propertyName) + var instance map[string]interface{} + json.Unmarshal([]byte(rawInstance), &instance) + + assert.False(t, PropertyTypeMismatch(propertyName, Validate(instance, validSchemaWithReferences)), "Property type is correct") + + // Change property to incorrect type. + pointerString := "/" + propertyName + pointer, err := gojsonpointer.NewJsonPointer(pointerString) + require.NoError(t, err) + _, err = pointer.Set(instance, 1) + require.NoError(t, err) + + assert.True(t, PropertyTypeMismatch(propertyName, Validate(instance, validSchemaWithReferences)), "Property type is incorrect") +} + +func TestPropertyFormatMismatch(t *testing.T) { + propertyName := "TestPropertyFormatMismatch" + instanceTemplate := ` +{ + "%s": "http://example.com" +} +` + rawInstance := fmt.Sprintf(instanceTemplate, propertyName) + var instance map[string]interface{} + json.Unmarshal([]byte(rawInstance), &instance) + + assert.False(t, PropertyFormatMismatch(propertyName, Validate(instance, validSchemaWithReferences)), "Property format is correct") + + // Change property to incorrect type. + pointerString := "/" + propertyName + pointer, err := gojsonpointer.NewJsonPointer(pointerString) + require.NoError(t, err) + _, err = pointer.Set(instance, "foo") + require.NoError(t, err) + + assert.True(t, PropertyFormatMismatch(propertyName, Validate(instance, validSchemaWithReferences)), "Property format is incorrect") +} + +func TestProhibitedAdditionalProperties(t *testing.T) { + propertyName := "TestProhibitedAdditionalProperties" + instanceTemplate := ` +{ + "%s": { + "additionalPropertiesTrue": { + "fooProperty": "bar" + }, + "additionalPropertiesFalse": { + "fooProperty": "bar" + } + } +} +` + + testTables := []struct { + objectPointerString string + assertion assert.BoolAssertionFunc + }{ + {"/TestProhibitedAdditionalProperties/additionalPropertiesTrue", assert.False}, + {"/TestProhibitedAdditionalProperties/additionalPropertiesFalse", assert.True}, + } + + for _, testTable := range testTables { + rawInstance := fmt.Sprintf(instanceTemplate, propertyName) + var instance map[string]interface{} + json.Unmarshal([]byte(rawInstance), &instance) + + assert.False(t, ProhibitedAdditionalProperties(strings.TrimPrefix(testTable.objectPointerString, "/"), Validate(instance, validSchemaWithReferences)), fmt.Sprintf("No additional properties in %s", testTable.objectPointerString)) + + // Add additional property to object. + pointer, err := gojsonpointer.NewJsonPointer(testTable.objectPointerString + "/fooAdditionalProperty") + require.NoError(t, err) + _, err = pointer.Set(instance, "bar") + require.NoError(t, err) + + t.Run(fmt.Sprintf("Additional property in the %s object", testTable.objectPointerString), func(t *testing.T) { + testTable.assertion(t, ProhibitedAdditionalProperties(strings.TrimPrefix(testTable.objectPointerString, "/"), Validate(instance, validSchemaWithReferences))) + }) + } +} + func TestPropertyDependenciesMissing(t *testing.T) { propertiesMap := properties.NewFromHashmap(validMap) validationResult := Validate(general.PropertiesToMap(propertiesMap, 0), validSchemaWithReferences) diff --git a/internal/rule/schema/schemadata/bindata.go b/internal/rule/schema/schemadata/bindata.go index fae8d4cd..ec16d1cb 100644 --- a/internal/rule/schema/schemadata/bindata.go +++ b/internal/rule/schema/schemadata/bindata.go @@ -8,6 +8,10 @@ // etc/schemas/arduino-library-properties-permissive-schema.json // etc/schemas/arduino-library-properties-schema.json // etc/schemas/arduino-library-properties-strict-schema.json +// etc/schemas/arduino-package-index-definitions-schema.json +// etc/schemas/arduino-package-index-permissive-schema.json +// etc/schemas/arduino-package-index-schema.json +// etc/schemas/arduino-package-index-strict-schema.json // etc/schemas/arduino-platform-txt-definitions-schema.json // etc/schemas/arduino-platform-txt-permissive-schema.json // etc/schemas/arduino-platform-txt-schema.json @@ -1425,11 +1429,6 @@ var _arduinoLibraryPropertiesDefinitionsSchemaJson = []byte(`{ "definitions": { "general": { "patternObjects": { - "notStartsWithArduino": { - "not": { - "pattern": "^[aA][rR][dD][uU][iI][nN][oO].*$" - } - }, "notContainsArduino": { "not": { "pattern": "^.+[aA][rR][dD][uU][iI][nN][oO].*$" @@ -1488,7 +1487,7 @@ var _arduinoLibraryPropertiesDefinitionsSchemaJson = []byte(`{ }, { "$comment": "Only official Arduino libraries are allowed to have names starting with \"Arduino\"", - "$ref": "#/definitions/general/patternObjects/notStartsWithArduino" + "$ref": "general-definitions-schema.json#/definitions/patternObjects/notStartsWithArduino" } ] } @@ -1647,7 +1646,7 @@ var _arduinoLibraryPropertiesDefinitionsSchemaJson = []byte(`{ }, { "$comment": "Only official Arduino libraries are allowed to have maintainer field starting with \"Arduino\"", - "$ref": "#/definitions/general/patternObjects/notStartsWithArduino" + "$ref": "general-definitions-schema.json#/definitions/patternObjects/notStartsWithArduino" } ] } @@ -2263,16 +2262,1597 @@ var _arduinoLibraryPropertiesDefinitionsSchemaJson = []byte(`{ ] } }, - "strict": { - "object": { - "allOf": [ - { - "$ref": "#/definitions/requiredObjects/specification/object" - }, - { - "required": ["category", "architectures"] + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/requiredObjects/specification/object" + }, + { + "required": ["category", "architectures"] + } + ] + } + } + } + } +} +`) + +func arduinoLibraryPropertiesDefinitionsSchemaJsonBytes() ([]byte, error) { + return _arduinoLibraryPropertiesDefinitionsSchemaJson, nil +} + +func arduinoLibraryPropertiesDefinitionsSchemaJson() (*asset, error) { + bytes, err := arduinoLibraryPropertiesDefinitionsSchemaJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "arduino-library-properties-definitions-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _arduinoLibraryPropertiesPermissiveSchemaJson = []byte(`{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-library-properties-permissive-schema.json", + "title": "Arduino library.properties JSON permissive schema", + "description": "library.properties is the metadata file for Arduino libraries. This schema defines the minimum requirements for this file. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata", + "$comment": "For information on the Arduino library.properties format, see https://godoc.org/github.com/arduino/go-properties-orderedmap", + "type": "object", + "properties": { + "name": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/name/permissive/object" + }, + "version": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/version/permissive/object" + }, + "author": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/author/permissive/object" + }, + "maintainer": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/maintainer/permissive/object" + }, + "email": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/email/permissive/object" + }, + "sentence": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/sentence/permissive/object" + }, + "paragraph": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/paragraph/permissive/object" + }, + "category": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/category/permissive/object" + }, + "url": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/url/permissive/object" + }, + "architectures": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/architectures/permissive/object" + }, + "dot_a_linkage": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/dot_a_linkage/permissive/object" + }, + "depends": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/depends/permissive/object" + }, + "includes": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/includes/permissive/object" + }, + "precompiled": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/precompiled/permissive/object" + }, + "ldflags": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/ldflags/permissive/object" + } + }, + "allOf": [ + { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertyNamesObjects/permissive/object" + }, + { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/requiredObjects/permissive/object" + } + ] +} +`) + +func arduinoLibraryPropertiesPermissiveSchemaJsonBytes() ([]byte, error) { + return _arduinoLibraryPropertiesPermissiveSchemaJson, nil +} + +func arduinoLibraryPropertiesPermissiveSchemaJson() (*asset, error) { + bytes, err := arduinoLibraryPropertiesPermissiveSchemaJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "arduino-library-properties-permissive-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _arduinoLibraryPropertiesSchemaJson = []byte(`{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-library-properties-schema.json", + "title": "Arduino library.properties JSON schema", + "description": "library.properties is the metadata file for Arduino libraries. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata", + "$comment": "For information on the Arduino library.properties format, see https://godoc.org/github.com/arduino/go-properties-orderedmap", + "type": "object", + "properties": { + "name": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/name/specification/object" + }, + "version": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/version/specification/object" + }, + "author": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/author/specification/object" + }, + "maintainer": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/maintainer/specification/object" + }, + "email": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/email/specification/object" + }, + "sentence": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/sentence/specification/object" + }, + "paragraph": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/paragraph/specification/object" + }, + "category": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/category/specification/object" + }, + "url": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/url/specification/object" + }, + "architectures": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/architectures/specification/object" + }, + "dot_a_linkage": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/dot_a_linkage/specification/object" + }, + "depends": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/depends/specification/object" + }, + "includes": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/includes/specification/object" + }, + "precompiled": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/precompiled/specification/object" + }, + "ldflags": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/ldflags/specification/object" + } + }, + "allOf": [ + { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertyNamesObjects/specification/object" + }, + { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/requiredObjects/specification/object" + } + ] +} +`) + +func arduinoLibraryPropertiesSchemaJsonBytes() ([]byte, error) { + return _arduinoLibraryPropertiesSchemaJson, nil +} + +func arduinoLibraryPropertiesSchemaJson() (*asset, error) { + bytes, err := arduinoLibraryPropertiesSchemaJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "arduino-library-properties-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _arduinoLibraryPropertiesStrictSchemaJson = []byte(`{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-library-properties-strict-schema.json", + "title": "Arduino library.properties strict JSON schema", + "description": "library.properties is the metadata file for Arduino libraries. This schema defines the recommended format. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata", + "$comment": "For information on the Arduino library.properties format, see https://godoc.org/github.com/arduino/go-properties-orderedmap", + "type": "object", + "properties": { + "name": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/name/strict/object" + }, + "version": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/version/strict/object" + }, + "author": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/author/strict/object" + }, + "maintainer": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/maintainer/strict/object" + }, + "email": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/email/strict/object" + }, + "sentence": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/sentence/strict/object" + }, + "paragraph": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/paragraph/strict/object" + }, + "category": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/category/strict/object" + }, + "url": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/url/strict/object" + }, + "architectures": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/architectures/strict/object" + }, + "dot_a_linkage": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/dot_a_linkage/strict/object" + }, + "depends": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/depends/strict/object" + }, + "includes": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/includes/strict/object" + }, + "precompiled": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/precompiled/strict/object" + }, + "ldflags": { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/ldflags/strict/object" + } + }, + "allOf": [ + { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertyNamesObjects/strict/object" + }, + { + "$ref": "arduino-library-properties-definitions-schema.json#/definitions/requiredObjects/strict/object" + } + ] +} +`) + +func arduinoLibraryPropertiesStrictSchemaJsonBytes() ([]byte, error) { + return _arduinoLibraryPropertiesStrictSchemaJson, nil +} + +func arduinoLibraryPropertiesStrictSchemaJson() (*asset, error) { + bytes, err := arduinoLibraryPropertiesStrictSchemaJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "arduino-library-properties-strict-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _arduinoPackageIndexDefinitionsSchemaJson = []byte(`{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-definitions-schema.json", + "title": "Shared definitions for the Arduino Package Index schemas", + "definitions": { + "root": { + "base": { + "object": { + "type": "object", + "required": ["packages"] + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/root/base/object" + }, + { + "properties": { + "packages": { + "$ref": "#/definitions/propertiesObjects/packages/permissive/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/root/base/object" + }, + { + "properties": { + "packages": { + "$ref": "#/definitions/propertiesObjects/packages/specification/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/root/base/object" + }, + { + "properties": { + "packages": { + "$ref": "#/definitions/propertiesObjects/packages/strict/object" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "propertiesObjects": { + "packages": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "$comment": "help property is currently undocumented, so considered optional.", + "required": ["name", "maintainer", "websiteURL", "email", "platforms", "tools"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packages/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/packageName/permissive/object" + }, + "maintainer": { + "$ref": "#/definitions/propertiesObjects/maintainer/permissive/object" + }, + "websiteURL": { + "$ref": "#/definitions/propertiesObjects/websiteURL/permissive/object" + }, + "email": { + "$ref": "#/definitions/propertiesObjects/email/permissive/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/permissive/object" + }, + "platforms": { + "$ref": "#/definitions/propertiesObjects/platforms/permissive/object" + }, + "tools": { + "$ref": "#/definitions/propertiesObjects/tools/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packages/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/packageName/specification/object" + }, + "maintainer": { + "$ref": "#/definitions/propertiesObjects/maintainer/specification/object" + }, + "websiteURL": { + "$ref": "#/definitions/propertiesObjects/websiteURL/specification/object" + }, + "email": { + "$ref": "#/definitions/propertiesObjects/email/specification/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/specification/object" + }, + "platforms": { + "$ref": "#/definitions/propertiesObjects/platforms/specification/object" + }, + "tools": { + "$ref": "#/definitions/propertiesObjects/tools/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packages/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/packageName/strict/object" + }, + "maintainer": { + "$ref": "#/definitions/propertiesObjects/maintainer/strict/object" + }, + "websiteURL": { + "$ref": "#/definitions/propertiesObjects/websiteURL/strict/object" + }, + "email": { + "$ref": "#/definitions/propertiesObjects/email/strict/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/strict/object" + }, + "platforms": { + "$ref": "#/definitions/propertiesObjects/platforms/strict/object" + }, + "tools": { + "$ref": "#/definitions/propertiesObjects/tools/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "packageName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/packageName/base/object" + } + }, + "specification": { + "definitions": { + "patternObjects": { + "notArduino": { + "not": { + "pattern": "^[aA][rR][dD][uU][iI][nN][oO]$" + } + } + } + }, + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/packageName/base/object" + }, + { + "$comment": "Only official Arduino packages are allowed to use the \"arduino\" vendor name", + "$ref": "#/definitions/propertiesObjects/packageName/specification/definitions/patternObjects/notArduino" + } + ] + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/packageName/specification/object" + } + } + }, + "maintainer": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/maintainer/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/maintainer/base/object" + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/maintainer/specification/object" + }, + { + "$comment": "Only official Arduino packages are allowed to have maintainer field starting with \"Arduino\"", + "$ref": "general-definitions-schema.json#/definitions/patternObjects/notStartsWithArduino" + } + ] + } + } + }, + "websiteURL": { + "base": { + "object": { + "type": "string", + "format": "uri" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/websiteURL/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/websiteURL/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/websiteURL/specification/object" + } + } + }, + "email": { + "base": { + "object": { + "type": "string" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/email/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/email/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/email/specification/object" + } + } + }, + "help": { + "$comment": "Schema for package and platform help objects.", + "base": { + "object": { + "type": "object", + "required": ["online"] + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/help/base/object" + }, + { + "properties": { + "online": { + "$ref": "#/definitions/propertiesObjects/online/permissive/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/help/base/object" + }, + { + "properties": { + "online": { + "$ref": "#/definitions/propertiesObjects/online/specification/object" + } + }, + "additionalProperties": false + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/help/base/object" + }, + { + "properties": { + "online": { + "$ref": "#/definitions/propertiesObjects/online/strict/object" + } + }, + "additionalProperties": false + } + ] + } + } + }, + "online": { + "base": { + "object": { + "type": "string", + "format": "uri" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/online/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/online/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/online/specification/object" + } + } + }, + "platforms": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": [ + "name", + "architecture", + "version", + "category", + "help", + "url", + "archiveFileName", + "checksum", + "size", + "boards", + "toolsDependencies" + ] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platforms/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/platformName/permissive/object" + }, + "architecture": { + "$ref": "#/definitions/propertiesObjects/architecture/permissive/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/platformVersion/permissive/object" + }, + "category": { + "$ref": "#/definitions/propertiesObjects/category/permissive/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/permissive/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/permissive/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/permissive/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/permissive/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/permissive/object" + }, + "boards": { + "$ref": "#/definitions/propertiesObjects/boards/permissive/object" + }, + "toolsDependencies": { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platforms/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/platformName/specification/object" + }, + "architecture": { + "$ref": "#/definitions/propertiesObjects/architecture/specification/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/platformVersion/specification/object" + }, + "category": { + "$ref": "#/definitions/propertiesObjects/category/specification/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/specification/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/specification/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/specification/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/specification/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/specification/object" + }, + "boards": { + "$ref": "#/definitions/propertiesObjects/boards/specification/object" + }, + "toolsDependencies": { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platforms/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/platformName/strict/object" + }, + "architecture": { + "$ref": "#/definitions/propertiesObjects/architecture/strict/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/platformVersion/strict/object" + }, + "category": { + "$ref": "#/definitions/propertiesObjects/category/strict/object" + }, + "help": { + "$ref": "#/definitions/propertiesObjects/help/strict/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/strict/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/strict/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/strict/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/strict/object" + }, + "boards": { + "$ref": "#/definitions/propertiesObjects/boards/strict/object" + }, + "toolsDependencies": { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "platformName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/platformName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/platformName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/platformName/specification/object" + } + } + }, + "architecture": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/architecture/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/architecture/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/architecture/specification/object" + } + } + }, + "platformVersion": { + "base": { + "object": { + "type": "string" + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platformVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platformVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/platformVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/semver" + } + ] + } + } + }, + "category": { + "base": { + "object": { + "type": "string", + "enum": ["Contributed"] + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/category/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/category/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/category/specification/object" + } + } + }, + "archiveUrl": { + "$comment": "Schema for platform and tool archive URLs", + "base": { + "object": { + "type": "string", + "format": "uri" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/specification/object" + } + } + }, + "archiveFileName": { + "$comment": "Schema for platform and tool archive filenames.", + "base": { + "definitions": { + "validExtensionPattern": { + "pattern": "^.+\\.(tar\\.bz2|tar\\.gz|zip)$" + } + }, + "object": { + "allOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/definitions/propertiesObjects/archiveFileName/base/definitions/validExtensionPattern" + } + ] + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/specification/object" + } + } + }, + "checksum": { + "$comment": "Schema for platform and tool archive checksums.", + "base": { + "object": { + "type": "string", + "pattern": "^(MD5|SHA-1|SHA-256):[0-9a-fA-F]+$" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/checksum/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/checksum/base/object" + } + }, + "strict": { + "definitions": { + "patternObjects": { + "usesSHA256": { + "pattern": "^SHA-256:" + } + } + }, + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/checksum/specification/object" + }, + { + "$ref": "#/definitions/propertiesObjects/checksum/strict/definitions/patternObjects/usesSHA256" + } + ] + } + } + }, + "size": { + "$comment": "Schema for platform and tool archive file sizes.", + "base": { + "object": { + "type": "string", + "pattern": "[0-9]+" + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/size/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/size/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/size/specification/object" + } + } + }, + "boards": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["name"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/boards/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/boardName/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/boards/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/boardName/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/boards/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/boardName/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "boardName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/boardName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/boardName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/boardName/specification/object" + } + } + }, + "toolsDependencies": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["packager", "name", "version"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/base/object" + }, + { + "items": { + "properties": { + "packager": { + "$ref": "#/definitions/propertiesObjects/packager/permissive/object" + }, + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/permissive/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/base/object" + }, + { + "items": { + "properties": { + "packager": { + "$ref": "#/definitions/propertiesObjects/packager/specification/object" + }, + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/specification/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolsDependencies/base/object" + }, + { + "items": { + "properties": { + "packager": { + "$ref": "#/definitions/propertiesObjects/packager/strict/object" + }, + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/strict/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "packager": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/packager/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/packager/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/packager/specification/object" + } + } + }, + "tools": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "version", "systems"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/tools/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/permissive/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/permissive/object" + }, + "systems": { + "$ref": "#/definitions/propertiesObjects/systems/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/tools/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/specification/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/specification/object" + }, + "systems": { + "$ref": "#/definitions/propertiesObjects/systems/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/tools/base/object" + }, + { + "items": { + "properties": { + "name": { + "$ref": "#/definitions/propertiesObjects/toolName/strict/object" + }, + "version": { + "$ref": "#/definitions/propertiesObjects/toolVersion/strict/object" + }, + "systems": { + "$ref": "#/definitions/propertiesObjects/systems/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "toolName": { + "base": { + "object": { + "type": "string", + "minLength": 1 + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/toolName/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/toolName/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/toolName/specification/object" + } + } + }, + "toolVersion": { + "base": { + "object": { + "type": "string" + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/relaxedSemver" + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/toolVersion/base/object" + }, + { + "$ref": "general-definitions-schema.json#/definitions/patternObjects/semver" + } + ] + } + } + }, + "systems": { + "base": { + "object": { + "type": "array", + "items": { + "type": "object", + "required": ["host", "url", "archiveFileName", "size", "checksum"] + } + } + }, + "permissive": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/systems/base/object" + }, + { + "items": { + "properties": { + "host": { + "$ref": "#/definitions/propertiesObjects/host/permissive/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/permissive/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/permissive/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/permissive/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/permissive/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "specification": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/systems/base/object" + }, + { + "items": { + "properties": { + "host": { + "$ref": "#/definitions/propertiesObjects/host/specification/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/specification/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/specification/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/specification/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/specification/object" + } + }, + "additionalProperties": false + } + } + ] + } + }, + "strict": { + "object": { + "allOf": [ + { + "$ref": "#/definitions/propertiesObjects/systems/base/object" + }, + { + "items": { + "properties": { + "host": { + "$ref": "#/definitions/propertiesObjects/host/strict/object" + }, + "url": { + "$ref": "#/definitions/propertiesObjects/archiveUrl/strict/object" + }, + "archiveFileName": { + "$ref": "#/definitions/propertiesObjects/archiveFileName/strict/object" + }, + "checksum": { + "$ref": "#/definitions/propertiesObjects/checksum/strict/object" + }, + "size": { + "$ref": "#/definitions/propertiesObjects/size/strict/object" + } + }, + "additionalProperties": false + } + } + ] + } + } + }, + "host": { + "base": { + "definitions": { + "patternObjects": { + "validHost": { + "$comment": "https://github.com/arduino/arduino-cli/blob/cdbebe98f895c18146ea2607cfb706d002b01191/arduino/cores/tools.go#L144-L155", + "anyOf": [ + { + "pattern": "^arm.*-linux-gnueabihf$" + }, + { + "pattern": "^(aarch64|arm64)-linux-gnu$" + }, + { + "pattern": "^x86_64-.*linux-gnu$" + }, + { + "pattern": "^i[3456]86-.*linux-gnu$" + }, + { + "pattern": "^i[3456]86-.*(mingw32|cygwin)$" + }, + { + "pattern": "^(amd64|x86_64)-.*(mingw32|cygwin)$" + }, + { + "pattern": "^x86_64-apple-darwin.*$" + }, + { + "pattern": "^i[3456]86-apple-darwin.*$" + }, + { + "pattern": "^arm64-apple-darwin.*$" + }, + { + "pattern": "^arm.*-freebsd[0-9]*$" + }, + { + "pattern": "^i?[3456]86-freebsd[0-9]*$" + }, + { + "pattern": "^amd64-freebsd[0-9]*$" + } + ] + } } - ] + }, + "object": { + "allOf": [ + { + "type": "string" + }, + { + "$ref": "#/definitions/propertiesObjects/host/base/definitions/patternObjects/validHost" + } + ] + } + }, + "permissive": { + "object": { + "$ref": "#/definitions/propertiesObjects/host/base/object" + } + }, + "specification": { + "object": { + "$ref": "#/definitions/propertiesObjects/host/base/object" + } + }, + "strict": { + "object": { + "$ref": "#/definitions/propertiesObjects/host/specification/object" + } } } } @@ -2280,257 +3860,101 @@ var _arduinoLibraryPropertiesDefinitionsSchemaJson = []byte(`{ } `) -func arduinoLibraryPropertiesDefinitionsSchemaJsonBytes() ([]byte, error) { - return _arduinoLibraryPropertiesDefinitionsSchemaJson, nil +func arduinoPackageIndexDefinitionsSchemaJsonBytes() ([]byte, error) { + return _arduinoPackageIndexDefinitionsSchemaJson, nil } -func arduinoLibraryPropertiesDefinitionsSchemaJson() (*asset, error) { - bytes, err := arduinoLibraryPropertiesDefinitionsSchemaJsonBytes() +func arduinoPackageIndexDefinitionsSchemaJson() (*asset, error) { + bytes, err := arduinoPackageIndexDefinitionsSchemaJsonBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "arduino-library-properties-definitions-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "arduino-package-index-definitions-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _arduinoLibraryPropertiesPermissiveSchemaJson = []byte(`{ +var _arduinoPackageIndexPermissiveSchemaJson = []byte(`{ "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-library-properties-permissive-schema.json", - "title": "Arduino library.properties JSON permissive schema", - "description": "library.properties is the metadata file for Arduino libraries. This schema defines the minimum requirements for this file. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata", - "$comment": "For information on the Arduino library.properties format, see https://godoc.org/github.com/arduino/go-properties-orderedmap", - "type": "object", - "properties": { - "name": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/name/permissive/object" - }, - "version": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/version/permissive/object" - }, - "author": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/author/permissive/object" - }, - "maintainer": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/maintainer/permissive/object" - }, - "email": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/email/permissive/object" - }, - "sentence": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/sentence/permissive/object" - }, - "paragraph": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/paragraph/permissive/object" - }, - "category": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/category/permissive/object" - }, - "url": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/url/permissive/object" - }, - "architectures": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/architectures/permissive/object" - }, - "dot_a_linkage": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/dot_a_linkage/permissive/object" - }, - "depends": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/depends/permissive/object" - }, - "includes": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/includes/permissive/object" - }, - "precompiled": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/precompiled/permissive/object" - }, - "ldflags": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/ldflags/permissive/object" - } - }, + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-permissive-schema.json", + "title": "Arduino Package Index JSON permissive schema", + "description": "Package indexes define Arduino hardware packages. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/. This schema defines the minimum accepted data format.", "allOf": [ { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertyNamesObjects/permissive/object" - }, - { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/requiredObjects/permissive/object" + "$ref": "arduino-package-index-definitions-schema.json#/definitions/root/permissive/object" } ] } `) -func arduinoLibraryPropertiesPermissiveSchemaJsonBytes() ([]byte, error) { - return _arduinoLibraryPropertiesPermissiveSchemaJson, nil +func arduinoPackageIndexPermissiveSchemaJsonBytes() ([]byte, error) { + return _arduinoPackageIndexPermissiveSchemaJson, nil } -func arduinoLibraryPropertiesPermissiveSchemaJson() (*asset, error) { - bytes, err := arduinoLibraryPropertiesPermissiveSchemaJsonBytes() +func arduinoPackageIndexPermissiveSchemaJson() (*asset, error) { + bytes, err := arduinoPackageIndexPermissiveSchemaJsonBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "arduino-library-properties-permissive-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "arduino-package-index-permissive-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _arduinoLibraryPropertiesSchemaJson = []byte(`{ +var _arduinoPackageIndexSchemaJson = []byte(`{ "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-library-properties-schema.json", - "title": "Arduino library.properties JSON schema", - "description": "library.properties is the metadata file for Arduino libraries. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata", - "$comment": "For information on the Arduino library.properties format, see https://godoc.org/github.com/arduino/go-properties-orderedmap", - "type": "object", - "properties": { - "name": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/name/specification/object" - }, - "version": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/version/specification/object" - }, - "author": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/author/specification/object" - }, - "maintainer": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/maintainer/specification/object" - }, - "email": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/email/specification/object" - }, - "sentence": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/sentence/specification/object" - }, - "paragraph": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/paragraph/specification/object" - }, - "category": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/category/specification/object" - }, - "url": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/url/specification/object" - }, - "architectures": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/architectures/specification/object" - }, - "dot_a_linkage": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/dot_a_linkage/specification/object" - }, - "depends": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/depends/specification/object" - }, - "includes": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/includes/specification/object" - }, - "precompiled": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/precompiled/specification/object" - }, - "ldflags": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/ldflags/specification/object" - } - }, + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-schema.json", + "title": "Arduino Package Index JSON schema", + "description": "Package indexes define Arduino hardware packages. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/. This schema defines the data format per the specification.", "allOf": [ { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertyNamesObjects/specification/object" - }, - { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/requiredObjects/specification/object" + "$ref": "arduino-package-index-definitions-schema.json#/definitions/root/specification/object" } ] } `) -func arduinoLibraryPropertiesSchemaJsonBytes() ([]byte, error) { - return _arduinoLibraryPropertiesSchemaJson, nil +func arduinoPackageIndexSchemaJsonBytes() ([]byte, error) { + return _arduinoPackageIndexSchemaJson, nil } -func arduinoLibraryPropertiesSchemaJson() (*asset, error) { - bytes, err := arduinoLibraryPropertiesSchemaJsonBytes() +func arduinoPackageIndexSchemaJson() (*asset, error) { + bytes, err := arduinoPackageIndexSchemaJsonBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "arduino-library-properties-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "arduino-package-index-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _arduinoLibraryPropertiesStrictSchemaJson = []byte(`{ +var _arduinoPackageIndexStrictSchemaJson = []byte(`{ "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-library-properties-strict-schema.json", - "title": "Arduino library.properties strict JSON schema", - "description": "library.properties is the metadata file for Arduino libraries. This schema defines the recommended format. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-metadata", - "$comment": "For information on the Arduino library.properties format, see https://godoc.org/github.com/arduino/go-properties-orderedmap", - "type": "object", - "properties": { - "name": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/name/strict/object" - }, - "version": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/version/strict/object" - }, - "author": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/author/strict/object" - }, - "maintainer": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/maintainer/strict/object" - }, - "email": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/email/strict/object" - }, - "sentence": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/sentence/strict/object" - }, - "paragraph": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/paragraph/strict/object" - }, - "category": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/category/strict/object" - }, - "url": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/url/strict/object" - }, - "architectures": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/architectures/strict/object" - }, - "dot_a_linkage": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/dot_a_linkage/strict/object" - }, - "depends": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/depends/strict/object" - }, - "includes": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/includes/strict/object" - }, - "precompiled": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/precompiled/strict/object" - }, - "ldflags": { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertiesObjects/ldflags/strict/object" - } - }, + "$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-package-index-strict-schema.json", + "title": "Arduino Package Index JSON strict schema", + "description": "Package indexes define Arduino hardware packages. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/. This schema defines the best practices for the data format, above and beyond the specification.", "allOf": [ { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/propertyNamesObjects/strict/object" - }, - { - "$ref": "arduino-library-properties-definitions-schema.json#/definitions/requiredObjects/strict/object" + "$ref": "arduino-package-index-definitions-schema.json#/definitions/root/strict/object" } ] } `) -func arduinoLibraryPropertiesStrictSchemaJsonBytes() ([]byte, error) { - return _arduinoLibraryPropertiesStrictSchemaJson, nil +func arduinoPackageIndexStrictSchemaJsonBytes() ([]byte, error) { + return _arduinoPackageIndexStrictSchemaJson, nil } -func arduinoLibraryPropertiesStrictSchemaJson() (*asset, error) { - bytes, err := arduinoLibraryPropertiesStrictSchemaJsonBytes() +func arduinoPackageIndexStrictSchemaJson() (*asset, error) { + bytes, err := arduinoPackageIndexStrictSchemaJsonBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "arduino-library-properties-strict-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "arduino-package-index-strict-schema.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -4370,6 +5794,11 @@ var _generalDefinitionsSchemaJson = []byte(`{ "containsPropertyReference": { "$comment": "https://arduino.github.io/arduino-cli/dev/platform-specification/#configuration-files-format", "pattern": "{.+}" + }, + "notStartsWithArduino": { + "not": { + "pattern": "^[aA][rR][dD][uU][iI][nN][oO].*$" + } } } } @@ -4451,6 +5880,10 @@ var _bindata = map[string]func() (*asset, error){ "arduino-library-properties-permissive-schema.json": arduinoLibraryPropertiesPermissiveSchemaJson, "arduino-library-properties-schema.json": arduinoLibraryPropertiesSchemaJson, "arduino-library-properties-strict-schema.json": arduinoLibraryPropertiesStrictSchemaJson, + "arduino-package-index-definitions-schema.json": arduinoPackageIndexDefinitionsSchemaJson, + "arduino-package-index-permissive-schema.json": arduinoPackageIndexPermissiveSchemaJson, + "arduino-package-index-schema.json": arduinoPackageIndexSchemaJson, + "arduino-package-index-strict-schema.json": arduinoPackageIndexStrictSchemaJson, "arduino-platform-txt-definitions-schema.json": arduinoPlatformTxtDefinitionsSchemaJson, "arduino-platform-txt-permissive-schema.json": arduinoPlatformTxtPermissiveSchemaJson, "arduino-platform-txt-schema.json": arduinoPlatformTxtSchemaJson, @@ -4511,6 +5944,10 @@ var _bintree = &bintree{nil, map[string]*bintree{ "arduino-library-properties-permissive-schema.json": &bintree{arduinoLibraryPropertiesPermissiveSchemaJson, map[string]*bintree{}}, "arduino-library-properties-schema.json": &bintree{arduinoLibraryPropertiesSchemaJson, map[string]*bintree{}}, "arduino-library-properties-strict-schema.json": &bintree{arduinoLibraryPropertiesStrictSchemaJson, map[string]*bintree{}}, + "arduino-package-index-definitions-schema.json": &bintree{arduinoPackageIndexDefinitionsSchemaJson, map[string]*bintree{}}, + "arduino-package-index-permissive-schema.json": &bintree{arduinoPackageIndexPermissiveSchemaJson, map[string]*bintree{}}, + "arduino-package-index-schema.json": &bintree{arduinoPackageIndexSchemaJson, map[string]*bintree{}}, + "arduino-package-index-strict-schema.json": &bintree{arduinoPackageIndexStrictSchemaJson, map[string]*bintree{}}, "arduino-platform-txt-definitions-schema.json": &bintree{arduinoPlatformTxtDefinitionsSchemaJson, map[string]*bintree{}}, "arduino-platform-txt-permissive-schema.json": &bintree{arduinoPlatformTxtPermissiveSchemaJson, map[string]*bintree{}}, "arduino-platform-txt-schema.json": &bintree{arduinoPlatformTxtSchemaJson, map[string]*bintree{}}, diff --git a/internal/rule/schema/testdata/bindata.go b/internal/rule/schema/testdata/bindata.go index d2aa48c4..4702b6a4 100644 --- a/internal/rule/schema/testdata/bindata.go +++ b/internal/rule/schema/testdata/bindata.go @@ -138,6 +138,16 @@ var _referencedSchema2Json = []byte(`{ ] } }, + "TestPropertyTypeMismatch": { + "object": { + "type": "string" + } + }, + "TestPropertyFormatMismatch": { + "object": { + "format": "uri" + } + }, "misspelledOptionalProperties": { "propertyNames": { "not": { @@ -217,6 +227,36 @@ var _validSchemaWithReferencesJson = []byte(`{ "$ref": "referenced-schema-2.json#/definitions/notPatternObject" } ] + }, + "TestPropertyTypeMismatch": { + "allOf": [ + { + "$ref": "referenced-schema-2.json#/definitions/TestPropertyTypeMismatch/object" + } + ] + }, + "TestPropertyFormatMismatch": { + "allOf": [ + { + "$ref": "referenced-schema-2.json#/definitions/TestPropertyFormatMismatch/object" + } + ] + }, + "TestProhibitedAdditionalProperties": { + "properties": { + "additionalPropertiesTrue": { + "properties": { + "fooProperty": {} + }, + "additionalProperties": true + }, + "additionalPropertiesFalse": { + "properties": { + "fooProperty": {} + }, + "additionalProperties": false + } + } } }, "allOf": [ diff --git a/internal/rule/schema/testdata/input/referenced-schema-2.json b/internal/rule/schema/testdata/input/referenced-schema-2.json index 9b8e2cf2..7572dd6a 100644 --- a/internal/rule/schema/testdata/input/referenced-schema-2.json +++ b/internal/rule/schema/testdata/input/referenced-schema-2.json @@ -26,6 +26,16 @@ ] } }, + "TestPropertyTypeMismatch": { + "object": { + "type": "string" + } + }, + "TestPropertyFormatMismatch": { + "object": { + "format": "uri" + } + }, "misspelledOptionalProperties": { "propertyNames": { "not": { diff --git a/internal/rule/schema/testdata/input/valid-schema-with-references.json b/internal/rule/schema/testdata/input/valid-schema-with-references.json index d07da8e6..1b7408fc 100644 --- a/internal/rule/schema/testdata/input/valid-schema-with-references.json +++ b/internal/rule/schema/testdata/input/valid-schema-with-references.json @@ -30,6 +30,36 @@ "$ref": "referenced-schema-2.json#/definitions/notPatternObject" } ] + }, + "TestPropertyTypeMismatch": { + "allOf": [ + { + "$ref": "referenced-schema-2.json#/definitions/TestPropertyTypeMismatch/object" + } + ] + }, + "TestPropertyFormatMismatch": { + "allOf": [ + { + "$ref": "referenced-schema-2.json#/definitions/TestPropertyFormatMismatch/object" + } + ] + }, + "TestProhibitedAdditionalProperties": { + "properties": { + "additionalPropertiesTrue": { + "properties": { + "fooProperty": {} + }, + "additionalProperties": true + }, + "additionalPropertiesFalse": { + "properties": { + "fooProperty": {} + }, + "additionalProperties": false + } + } } }, "allOf": [