Skip to content

Commit 84bb4ea

Browse files
committed
Add JSON schema for platform.txt
This schema defines the required data structure of the platform.txt configuration file of Arduino boards platforms.
1 parent 929a433 commit 84bb4ea

File tree

149 files changed

+9914
-10
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+9914
-10
lines changed

etc/schemas/arduino-platform-txt-definitions-schema.json

+1,174
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-platform-txt-permissive-schema.json",
4+
"title": "Arduino platform.txt JSON permissive schema",
5+
"description": "platform.txt contains the platform definitions of Arduino platforms. See: https://arduino.github.io/arduino-cli/latest/platform-specification/#platformtxt",
6+
"$comment": "For information on the platform.txt format, see https://godoc.org/github.com/arduino/go-properties-orderedmap",
7+
"type": "object",
8+
"properties": {
9+
"name": {
10+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/name/permissive/object"
11+
},
12+
"version": {
13+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/version/permissive/object"
14+
},
15+
"compiler.c.extra_flags": {
16+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCExtraFlags/permissive/object"
17+
},
18+
"compiler.cpp.extra_flags": {
19+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCppExtraFlags/permissive/object"
20+
},
21+
"compiler.S.extra_flags": {
22+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerSExtraFlags/permissive/object"
23+
},
24+
"compiler.ar.extra_flags": {
25+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerArExtraFlags/permissive/object"
26+
},
27+
"compiler.c.elf.extra_flags": {
28+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCElfExtraFlags/permissive/object"
29+
},
30+
"recipe.preproc.macros": {
31+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipePreprocMacros/permissive/object"
32+
},
33+
"recipe.c.o.pattern": {
34+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCOPattern/permissive/object"
35+
},
36+
"recipe.cpp.o.pattern": {
37+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCppOPattern/permissive/object"
38+
},
39+
"recipe.S.o.pattern": {
40+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeSOPattern/permissive/object"
41+
},
42+
"recipe.ar.pattern": {
43+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeArPattern/permissive/object"
44+
},
45+
"recipe.c.combine.pattern": {
46+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCCombinePattern/permissive/object"
47+
},
48+
"recipe.output.tmp_file": {
49+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeOutputTmpFile/permissive/object"
50+
},
51+
"recipe.output.save_file": {
52+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeOutputSaveFile/permissive/object"
53+
},
54+
"recipe.size.pattern": {
55+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeSizePattern/permissive/object"
56+
},
57+
"tools": {
58+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/tools/permissive/object"
59+
}
60+
},
61+
"allOf": [
62+
{
63+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/dependenciesObjects/root/permissive/object"
64+
},
65+
{
66+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/requiredObjects/root/permissive/object"
67+
}
68+
]
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-platform-txt-schema.json",
4+
"title": "Arduino platform.txt JSON schema",
5+
"description": "platform.txt contains the platform definitions of Arduino platforms. See: https://arduino.github.io/arduino-cli/latest/platform-specification/#platformtxt",
6+
"$comment": "For information on the platform.txt format, see https://godoc.org/github.com/arduino/go-properties-orderedmap",
7+
"type": "object",
8+
"properties": {
9+
"name": {
10+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/name/specification/object"
11+
},
12+
"version": {
13+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/version/specification/object"
14+
},
15+
"compiler.c.extra_flags": {
16+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCExtraFlags/specification/object"
17+
},
18+
"compiler.cpp.extra_flags": {
19+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCppExtraFlags/specification/object"
20+
},
21+
"compiler.S.extra_flags": {
22+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerSExtraFlags/specification/object"
23+
},
24+
"compiler.ar.extra_flags": {
25+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerArExtraFlags/specification/object"
26+
},
27+
"compiler.c.elf.extra_flags": {
28+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCElfExtraFlags/specification/object"
29+
},
30+
"recipe.preproc.macros": {
31+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipePreprocMacros/specification/object"
32+
},
33+
"recipe.c.o.pattern": {
34+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCOPattern/specification/object"
35+
},
36+
"recipe.cpp.o.pattern": {
37+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCppOPattern/specification/object"
38+
},
39+
"recipe.S.o.pattern": {
40+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeSOPattern/specification/object"
41+
},
42+
"recipe.ar.pattern": {
43+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeArPattern/specification/object"
44+
},
45+
"recipe.c.combine.pattern": {
46+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCCombinePattern/specification/object"
47+
},
48+
"recipe.output.tmp_file": {
49+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeOutputTmpFile/specification/object"
50+
},
51+
"recipe.output.save_file": {
52+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeOutputSaveFile/specification/object"
53+
},
54+
"recipe.size.pattern": {
55+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeSizePattern/specification/object"
56+
},
57+
"tools": {
58+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/tools/specification/object"
59+
}
60+
},
61+
"allOf": [
62+
{
63+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/dependenciesObjects/root/specification/object"
64+
},
65+
{
66+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/requiredObjects/root/specification/object"
67+
}
68+
]
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/schemas/arduino-platform-txt-strict-schema.json",
4+
"title": "Arduino platform.txt JSON strict schema",
5+
"description": "platform.txt contains the platform definitions of Arduino platforms. See: https://arduino.github.io/arduino-cli/latest/platform-specification/#platformtxt",
6+
"$comment": "For information on the platform.txt format, see https://godoc.org/github.com/arduino/go-properties-orderedmap",
7+
"type": "object",
8+
"properties": {
9+
"name": {
10+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/name/strict/object"
11+
},
12+
"version": {
13+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/version/strict/object"
14+
},
15+
"compiler.c.extra_flags": {
16+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCExtraFlags/strict/object"
17+
},
18+
"compiler.cpp.extra_flags": {
19+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCppExtraFlags/strict/object"
20+
},
21+
"compiler.S.extra_flags": {
22+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerSExtraFlags/strict/object"
23+
},
24+
"compiler.ar.extra_flags": {
25+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerArExtraFlags/strict/object"
26+
},
27+
"compiler.c.elf.extra_flags": {
28+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/compilerCElfExtraFlags/strict/object"
29+
},
30+
"recipe.preproc.macros": {
31+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipePreprocMacros/strict/object"
32+
},
33+
"recipe.c.o.pattern": {
34+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCOPattern/strict/object"
35+
},
36+
"recipe.cpp.o.pattern": {
37+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCppOPattern/strict/object"
38+
},
39+
"recipe.S.o.pattern": {
40+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeSOPattern/strict/object"
41+
},
42+
"recipe.ar.pattern": {
43+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeArPattern/strict/object"
44+
},
45+
"recipe.c.combine.pattern": {
46+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeCCombinePattern/strict/object"
47+
},
48+
"recipe.output.tmp_file": {
49+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeOutputTmpFile/strict/object"
50+
},
51+
"recipe.output.save_file": {
52+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeOutputSaveFile/strict/object"
53+
},
54+
"recipe.size.pattern": {
55+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/recipeSizePattern/strict/object"
56+
},
57+
"tools": {
58+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/propertiesObjects/tools/strict/object"
59+
}
60+
},
61+
"allOf": [
62+
{
63+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/dependenciesObjects/root/strict/object"
64+
},
65+
{
66+
"$ref": "arduino-platform-txt-definitions-schema.json#/definitions/requiredObjects/root/strict/object"
67+
}
68+
]
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// This file is part of arduino-lint.
2+
//
3+
// Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-lint.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to license@arduino.cc.
15+
16+
/*
17+
Package platformtxt provides functions specific to linting the platform.txt configuration files of Arduino platform platforms.
18+
See: https://arduino.github.io/arduino-cli/latest/platform-specification/#platformtxt
19+
*/
20+
package platformtxt
21+
22+
import (
23+
"strings"
24+
25+
"github.com/arduino/arduino-lint/internal/project/general"
26+
"github.com/arduino/arduino-lint/internal/rule/schema"
27+
"github.com/arduino/arduino-lint/internal/rule/schema/compliancelevel"
28+
"github.com/arduino/arduino-lint/internal/rule/schema/schemadata"
29+
"github.com/arduino/go-paths-helper"
30+
"github.com/arduino/go-properties-orderedmap"
31+
)
32+
33+
// Properties parses the platform.txt from the given path and returns the data.
34+
func Properties(platformPath *paths.Path) (*properties.Map, error) {
35+
return properties.LoadFromPath(platformPath.Join("platform.txt"))
36+
}
37+
38+
var schemaObject = make(map[compliancelevel.Type]schema.Schema)
39+
40+
// Validate validates platform.txt data against the JSON schema and returns a map of the result for each compliance level.
41+
func Validate(platformTxt *properties.Map) map[compliancelevel.Type]schema.ValidationResult {
42+
referencedSchemaFilenames := []string{
43+
"general-definitions-schema.json",
44+
"arduino-platform-txt-definitions-schema.json",
45+
}
46+
47+
var validationResults = make(map[compliancelevel.Type]schema.ValidationResult)
48+
49+
if schemaObject[compliancelevel.Permissive].Compiled == nil { // Only compile the schemas once.
50+
schemaObject[compliancelevel.Permissive] = schema.Compile("arduino-platform-txt-permissive-schema.json", referencedSchemaFilenames, schemadata.Asset)
51+
schemaObject[compliancelevel.Specification] = schema.Compile("arduino-platform-txt-schema.json", referencedSchemaFilenames, schemadata.Asset)
52+
schemaObject[compliancelevel.Strict] = schema.Compile("arduino-platform-txt-strict-schema.json", referencedSchemaFilenames, schemadata.Asset)
53+
}
54+
55+
/*
56+
Convert the platform.txt data from the native properties.Map type to the interface type required by the schema
57+
validation package.
58+
Even though platform.txt has a multi-level nested data structure, the format has the odd characteristic of allowing
59+
a key to be both an object and a string simultaneously, which is not compatible with Golang maps or JSON. So the
60+
data structure used is a selective map, using a flat map except for the tools key, which can contain any number of
61+
arbitrary tool name subproperties which must be linted.
62+
*/
63+
platformTxtInterface := make(map[string]interface{})
64+
keys := platformTxt.Keys()
65+
for _, key := range keys {
66+
if strings.HasPrefix(key, "tools.") {
67+
platformTxtInterface["tools"] = general.PropertiesToMap(platformTxt.SubTree("tools"), 3)
68+
} else {
69+
platformTxtInterface[key] = platformTxt.Get(key)
70+
}
71+
}
72+
73+
validationResults[compliancelevel.Permissive] = schema.Validate(platformTxtInterface, schemaObject[compliancelevel.Permissive])
74+
validationResults[compliancelevel.Specification] = schema.Validate(platformTxtInterface, schemaObject[compliancelevel.Specification])
75+
validationResults[compliancelevel.Strict] = schema.Validate(platformTxtInterface, schemaObject[compliancelevel.Strict])
76+
77+
return validationResults
78+
}
79+
80+
// ToolNames returns the list of tool names from the given platform.txt properties.
81+
func ToolNames(platformTxt *properties.Map) []string {
82+
return platformTxt.SubTree("tools").FirstLevelKeys()
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// This file is part of arduino-lint.
2+
//
3+
// Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-lint.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to license@arduino.cc.
15+
16+
package platformtxt
17+
18+
import (
19+
"testing"
20+
21+
"github.com/arduino/arduino-lint/internal/rule/schema/compliancelevel"
22+
"github.com/arduino/go-paths-helper"
23+
"github.com/arduino/go-properties-orderedmap"
24+
"github.com/stretchr/testify/assert"
25+
"github.com/stretchr/testify/require"
26+
)
27+
28+
var testDataPath *paths.Path
29+
30+
var validPlatformTxtMap map[string]string
31+
32+
func init() {
33+
workingDirectory, err := paths.Getwd()
34+
if err != nil {
35+
panic(err)
36+
}
37+
testDataPath = workingDirectory.Join("testdata")
38+
39+
validPlatformTxtMap = map[string]string{
40+
"name": "Arduino AVR Boards",
41+
"version": "1.8.3",
42+
"compiler.warning_flags.none": "asdf",
43+
"compiler.warning_flags.default": "asdf",
44+
"compiler.warning_flags.more": "asdf",
45+
"compiler.warning_flags.all": "asdf",
46+
"compiler.c.extra_flags": "",
47+
"compiler.c.elf.extra_flags": "",
48+
"compiler.S.extra_flags": "",
49+
"compiler.cpp.extra_flags": "",
50+
"compiler.ar.extra_flags": "",
51+
"compiler.objcopy.eep.extra_flags": "",
52+
"compiler.elf2hex.extra_flags": "",
53+
"recipe.c.o.pattern": "asdf {compiler.c.extra_flags}",
54+
"recipe.cpp.o.pattern": "asdf {compiler.cpp.extra_flags}",
55+
"recipe.S.o.pattern": "asdf {compiler.S.extra_flags}",
56+
"recipe.ar.pattern": "asdf {compiler.ar.extra_flags}",
57+
"recipe.c.combine.pattern": "asdf {compiler.c.elf.extra_flags}",
58+
"recipe.objcopy.eep.pattern": "asdf",
59+
"recipe.objcopy.hex.pattern": "asdf",
60+
"recipe.output.tmp_file": "asdf",
61+
"recipe.output.save_file": "asdf",
62+
"recipe.size.pattern": "asdf",
63+
"recipe.size.regex": "asdf",
64+
"recipe.size.regex.data": "asdf",
65+
"tools.avrdude.upload.params.verbose": "-v",
66+
"tools.avrdude.upload.params.quiet": "-q -q",
67+
"tools.avrdude.upload.pattern": "asdf",
68+
}
69+
}
70+
71+
func TestProperties(t *testing.T) {
72+
propertiesOutput, err := Properties(testDataPath.Join("valid"))
73+
require.Nil(t, err)
74+
75+
assert.True(t, properties.NewFromHashmap(validPlatformTxtMap).Equals(propertiesOutput))
76+
}
77+
78+
func TestValidate(t *testing.T) {
79+
platformTxt := properties.NewFromHashmap(validPlatformTxtMap)
80+
validationResult := Validate(platformTxt)
81+
82+
assert.Nil(t, validationResult[compliancelevel.Permissive].Result, "Valid (permissive)")
83+
assert.Nil(t, validationResult[compliancelevel.Specification].Result, "Valid (specification)")
84+
assert.Nil(t, validationResult[compliancelevel.Strict].Result, "Valid (strict)")
85+
86+
platformTxt.Remove("name") // Remove required property.
87+
validationResult = Validate(platformTxt)
88+
assert.NotNil(t, validationResult[compliancelevel.Permissive].Result, "Invalid (permissive)")
89+
assert.NotNil(t, validationResult[compliancelevel.Specification].Result, "Invalid (specification)")
90+
assert.NotNil(t, validationResult[compliancelevel.Strict].Result, "Invalid (strict)")
91+
}
92+
93+
func TestToolNames(t *testing.T) {
94+
platformTxt := properties.NewFromHashmap(validPlatformTxtMap)
95+
96+
assert.ElementsMatch(t, []string{"avrdude"}, ToolNames(platformTxt))
97+
98+
platformTxt.Set("tools.bossac.program.params.verbose", "asdf")
99+
platformTxt.Set("tools.bossac.program.params.quiet", "asdf")
100+
platformTxt.Set("tools.bossac.program.pattern", "asdf")
101+
assert.ElementsMatch(t, []string{"avrdude", "bossac"}, ToolNames(platformTxt))
102+
}

0 commit comments

Comments
 (0)