Skip to content

Commit

Permalink
Add JSON schema for package index
Browse files Browse the repository at this point in the history
This schema defines the data structure of the Arduino package index at three compliance levels:

- permissive: the minimum accepted format. This allows for a gradual deprecation following specification changes.
- specification: the format as defined in the official specification
- strict: best practices

Helper functions for reading package indexes and validating them against the schema are added, at this point for use in
the tests, but also for the schema-based rules to come.
  • Loading branch information
per1234 committed Jun 7, 2021
1 parent a11044a commit 5861954
Show file tree
Hide file tree
Showing 9 changed files with 3,595 additions and 0 deletions.
1,324 changes: 1,324 additions & 0 deletions etc/schemas/arduino-package-index-definitions-schema.json

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions etc/schemas/arduino-package-index-permissive-schema.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
11 changes: 11 additions & 0 deletions etc/schemas/arduino-package-index-schema.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
11 changes: 11 additions & 0 deletions etc/schemas/arduino-package-index-strict-schema.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
43 changes: 43 additions & 0 deletions internal/project/packageindex/packageindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions internal/project/packageindex/packageindex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")))
Expand Down

0 comments on commit 5861954

Please sign in to comment.