Skip to content

Commit 1bdac6c

Browse files
committed
Increase mapping recursion depth of platform.txt tools.* properties
The Arduino project configuration files make an unusual usage of the "properties" data format in that sometimes a `.` in a key name indicates a nested data level, while other times it is only a character. There are cases where a completely programmatic recursion of the properties into a fully nested structure would result in the impossibility of some keys having both a string and a map type, which is not supported by the Go map type that holds the recursed data, nor the JSON data format it is validated against. For this reason, it's necessary to manually configure the recursion of key levels on a case-by-case basis and the approach is taken of recursing only when necessary. Previously, it was possible to treat the params.verbose/quiet component of the `tools.TOOL_NAME.ACTION_NAME.params.verbose/quiet` properties as being just key names. However, the addition of the `tools.TOOL_NAME.upload.field.FIELD_NAME` and `tools.TOOL_NAME.upload.field.FIELD_NAME.secret` properties requires one more level of recursion in order to deal with the fact that the FIELD_NAME component is arbitrary. This resulted in splitting the params.verbose/quiet property, which required adjustments to their schema and rules.
1 parent 7c18e57 commit 1bdac6c

File tree

5 files changed

+313
-17
lines changed

5 files changed

+313
-17
lines changed

Diff for: etc/schemas/arduino-platform-txt-definitions-schema.json

+149-1
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,13 @@
11201120
{
11211121
"$ref": "#/definitions/propertiesObjects/toolsToolNameProgram/base/object"
11221122
},
1123+
{
1124+
"properties": {
1125+
"params": {
1126+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/permissive/object"
1127+
}
1128+
}
1129+
},
11231130
{
11241131
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/permissive/object"
11251132
}
@@ -1132,6 +1139,13 @@
11321139
{
11331140
"$ref": "#/definitions/propertiesObjects/toolsToolNameProgram/base/object"
11341141
},
1142+
{
1143+
"properties": {
1144+
"params": {
1145+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/specification/object"
1146+
}
1147+
}
1148+
},
11351149
{
11361150
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/specification/object"
11371151
}
@@ -1144,6 +1158,13 @@
11441158
{
11451159
"$ref": "#/definitions/propertiesObjects/toolsToolNameProgram/base/object"
11461160
},
1161+
{
1162+
"properties": {
1163+
"params": {
1164+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/strict/object"
1165+
}
1166+
}
1167+
},
11471168
{
11481169
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/strict/object"
11491170
}
@@ -1167,6 +1188,13 @@
11671188
{
11681189
"$ref": "#/definitions/propertiesObjects/toolsToolNameErase/base/object"
11691190
},
1191+
{
1192+
"properties": {
1193+
"params": {
1194+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/permissive/object"
1195+
}
1196+
}
1197+
},
11701198
{
11711199
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/permissive/object"
11721200
}
@@ -1179,6 +1207,13 @@
11791207
{
11801208
"$ref": "#/definitions/propertiesObjects/toolsToolNameErase/base/object"
11811209
},
1210+
{
1211+
"properties": {
1212+
"params": {
1213+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/specification/object"
1214+
}
1215+
}
1216+
},
11821217
{
11831218
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/specification/object"
11841219
}
@@ -1191,6 +1226,13 @@
11911226
{
11921227
"$ref": "#/definitions/propertiesObjects/toolsToolNameErase/base/object"
11931228
},
1229+
{
1230+
"properties": {
1231+
"params": {
1232+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/strict/object"
1233+
}
1234+
}
1235+
},
11941236
{
11951237
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/strict/object"
11961238
}
@@ -1214,6 +1256,13 @@
12141256
{
12151257
"$ref": "#/definitions/propertiesObjects/toolsToolNameBootloader/base/object"
12161258
},
1259+
{
1260+
"properties": {
1261+
"params": {
1262+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/permissive/object"
1263+
}
1264+
}
1265+
},
12171266
{
12181267
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/permissive/object"
12191268
}
@@ -1226,6 +1275,13 @@
12261275
{
12271276
"$ref": "#/definitions/propertiesObjects/toolsToolNameBootloader/base/object"
12281277
},
1278+
{
1279+
"properties": {
1280+
"params": {
1281+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/specification/object"
1282+
}
1283+
}
1284+
},
12291285
{
12301286
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/specification/object"
12311287
}
@@ -1238,12 +1294,66 @@
12381294
{
12391295
"$ref": "#/definitions/propertiesObjects/toolsToolNameBootloader/base/object"
12401296
},
1297+
{
1298+
"properties": {
1299+
"params": {
1300+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/strict/object"
1301+
}
1302+
}
1303+
},
12411304
{
12421305
"$ref": "#/definitions/requiredObjects/toolsToolNameActionName/strict/object"
12431306
}
12441307
]
12451308
}
12461309
}
1310+
},
1311+
"toolsToolNameActionNameParams": {
1312+
"base": {
1313+
"object": {
1314+
"allOf": [
1315+
{
1316+
"type": "object"
1317+
}
1318+
]
1319+
}
1320+
},
1321+
"permissive": {
1322+
"object": {
1323+
"allOf": [
1324+
{
1325+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/base/object"
1326+
},
1327+
{
1328+
"$ref": "#/definitions/requiredObjects/toolsToolNameActionNameParams/permissive/object"
1329+
}
1330+
]
1331+
}
1332+
},
1333+
"specification": {
1334+
"object": {
1335+
"allOf": [
1336+
{
1337+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/base/object"
1338+
},
1339+
{
1340+
"$ref": "#/definitions/requiredObjects/toolsToolNameActionNameParams/specification/object"
1341+
}
1342+
]
1343+
}
1344+
},
1345+
"strict": {
1346+
"object": {
1347+
"allOf": [
1348+
{
1349+
"$ref": "#/definitions/propertiesObjects/toolsToolNameActionNameParams/base/object"
1350+
},
1351+
{
1352+
"$ref": "#/definitions/requiredObjects/toolsToolNameActionNameParams/strict/object"
1353+
}
1354+
]
1355+
}
1356+
}
12471357
}
12481358
},
12491359
"dependenciesObjects": {
@@ -1397,7 +1507,7 @@
13971507
"object": {
13981508
"allOf": [
13991509
{
1400-
"required": ["params.verbose", "params.quiet", "pattern"]
1510+
"required": ["params", "pattern"]
14011511
}
14021512
]
14031513
}
@@ -1430,6 +1540,44 @@
14301540
}
14311541
}
14321542
},
1543+
"toolsToolNameActionNameParams": {
1544+
"base": {
1545+
"object": {
1546+
"allOf": [
1547+
{
1548+
"required": ["verbose", "quiet"]
1549+
}
1550+
]
1551+
}
1552+
},
1553+
"permissive": {
1554+
"object": {
1555+
"allOf": [
1556+
{
1557+
"$ref": "#/definitions/requiredObjects/toolsToolNameActionNameParams/base/object"
1558+
}
1559+
]
1560+
}
1561+
},
1562+
"specification": {
1563+
"object": {
1564+
"allOf": [
1565+
{
1566+
"$ref": "#/definitions/requiredObjects/toolsToolNameActionNameParams/base/object"
1567+
}
1568+
]
1569+
}
1570+
},
1571+
"strict": {
1572+
"object": {
1573+
"allOf": [
1574+
{
1575+
"$ref": "#/definitions/requiredObjects/toolsToolNameActionNameParams/base/object"
1576+
}
1577+
]
1578+
}
1579+
}
1580+
},
14331581
"toolsToolNameUpload": {
14341582
"base": {
14351583
"object": {

Diff for: internal/project/platform/platformtxt/platformtxt.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func Validate(platformTxt *properties.Map) map[compliancelevel.Type]schema.Valid
7171
platformTxtInterface["pluggable_discovery"] = general.PropertiesToMap(platformTxt.SubTree("pluggable_discovery"), 2)
7272
}
7373
} else if strings.HasPrefix(key, "tools.") {
74-
platformTxtInterface["tools"] = general.PropertiesToMap(platformTxt.SubTree("tools"), 3)
74+
platformTxtInterface["tools"] = general.PropertiesToMap(platformTxt.SubTree("tools"), 4)
7575
} else {
7676
platformTxtInterface[key] = platformTxt.Get(key)
7777
}

Diff for: internal/project/platform/platformtxt/platformtxtschema_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ func TestRequired(t *testing.T) {
204204
{"tools.avrdude.upload.pattern", "", "tools/avrdude/upload/pattern", compliancelevel.Specification, assert.True},
205205
{"tools.avrdude.upload.pattern", "", "tools/avrdude/upload/pattern", compliancelevel.Strict, assert.True},
206206

207-
{"tools.avrdude.program.params.verbose", "", "tools/avrdude/program/params\\.verbose", compliancelevel.Permissive, assert.True},
208-
{"tools.avrdude.program.params.verbose", "", "tools/avrdude/program/params\\.verbose", compliancelevel.Specification, assert.True},
209-
{"tools.avrdude.program.params.verbose", "", "tools/avrdude/program/params\\.verbose", compliancelevel.Strict, assert.True},
207+
{"tools.avrdude.program.params.verbose", "", "tools/avrdude/program/params/verbose", compliancelevel.Permissive, assert.True},
208+
{"tools.avrdude.program.params.verbose", "", "tools/avrdude/program/params/verbose", compliancelevel.Specification, assert.True},
209+
{"tools.avrdude.program.params.verbose", "", "tools/avrdude/program/params/verbose", compliancelevel.Strict, assert.True},
210210

211-
{"tools.avrdude.program.params.quiet", "", "tools/avrdude/program/params\\.quiet", compliancelevel.Permissive, assert.True},
212-
{"tools.avrdude.program.params.quiet", "", "tools/avrdude/program/params\\.quiet", compliancelevel.Specification, assert.True},
213-
{"tools.avrdude.program.params.quiet", "", "tools/avrdude/program/params\\.quiet", compliancelevel.Strict, assert.True},
211+
{"tools.avrdude.program.params.quiet", "", "tools/avrdude/program/params/quiet", compliancelevel.Permissive, assert.True},
212+
{"tools.avrdude.program.params.quiet", "", "tools/avrdude/program/params/quiet", compliancelevel.Specification, assert.True},
213+
{"tools.avrdude.program.params.quiet", "", "tools/avrdude/program/params/quiet", compliancelevel.Strict, assert.True},
214214

215215
{"tools.avrdude.program.pattern", "", "tools/avrdude/program/pattern", compliancelevel.Permissive, assert.True},
216216
{"tools.avrdude.program.pattern", "", "tools/avrdude/program/pattern", compliancelevel.Specification, assert.True},

Diff for: internal/rule/rulefunction/platform.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,7 @@ func PlatformTxtUploadParamsVerboseMissing() (result ruleresult.Type, output str
16501650
return ruleresult.Skip, "platform.txt has no tools"
16511651
}
16521652

1653-
nonCompliantTools := toolNameMissingRequiredProperty("upload/params\\.verbose", compliancelevel.Specification)
1653+
nonCompliantTools := toolNameMissingRequiredProperty("upload/params/verbose", compliancelevel.Specification)
16541654

16551655
if len(nonCompliantTools) > 0 {
16561656
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")
@@ -1673,7 +1673,7 @@ func PlatformTxtUploadParamsQuietMissing() (result ruleresult.Type, output strin
16731673
return ruleresult.Skip, "platform.txt has no tools"
16741674
}
16751675

1676-
nonCompliantTools := toolNameMissingRequiredProperty("upload/params\\.quiet", compliancelevel.Specification)
1676+
nonCompliantTools := toolNameMissingRequiredProperty("upload/params/quiet", compliancelevel.Specification)
16771677

16781678
if len(nonCompliantTools) > 0 {
16791679
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")
@@ -1772,7 +1772,7 @@ func PlatformTxtProgramParamsVerboseMissing() (result ruleresult.Type, output st
17721772
return ruleresult.Skip, "platform.txt has no tools"
17731773
}
17741774

1775-
nonCompliantTools := toolNameMissingRequiredProperty("program/params\\.verbose", compliancelevel.Specification)
1775+
nonCompliantTools := toolNameMissingRequiredProperty("program/params/verbose", compliancelevel.Specification)
17761776

17771777
if len(nonCompliantTools) > 0 {
17781778
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")
@@ -1795,7 +1795,7 @@ func PlatformTxtProgramParamsQuietMissing() (result ruleresult.Type, output stri
17951795
return ruleresult.Skip, "platform.txt has no tools"
17961796
}
17971797

1798-
nonCompliantTools := toolNameMissingRequiredProperty("program/params\\.quiet", compliancelevel.Specification)
1798+
nonCompliantTools := toolNameMissingRequiredProperty("program/params/quiet", compliancelevel.Specification)
17991799

18001800
if len(nonCompliantTools) > 0 {
18011801
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")
@@ -1841,7 +1841,7 @@ func PlatformTxtEraseParamsVerboseMissing() (result ruleresult.Type, output stri
18411841
return ruleresult.Skip, "platform.txt has no tools"
18421842
}
18431843

1844-
nonCompliantTools := toolNameMissingRequiredProperty("erase/params\\.verbose", compliancelevel.Specification)
1844+
nonCompliantTools := toolNameMissingRequiredProperty("erase/params/verbose", compliancelevel.Specification)
18451845

18461846
if len(nonCompliantTools) > 0 {
18471847
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")
@@ -1864,7 +1864,7 @@ func PlatformTxtEraseParamsQuietMissing() (result ruleresult.Type, output string
18641864
return ruleresult.Skip, "platform.txt has no tools"
18651865
}
18661866

1867-
nonCompliantTools := toolNameMissingRequiredProperty("erase/params\\.quiet", compliancelevel.Specification)
1867+
nonCompliantTools := toolNameMissingRequiredProperty("erase/params/quiet", compliancelevel.Specification)
18681868

18691869
if len(nonCompliantTools) > 0 {
18701870
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")
@@ -1910,7 +1910,7 @@ func PlatformTxtBootloaderParamsVerboseMissing() (result ruleresult.Type, output
19101910
return ruleresult.Skip, "platform.txt has no tools"
19111911
}
19121912

1913-
nonCompliantTools := toolNameMissingRequiredProperty("bootloader/params\\.verbose", compliancelevel.Specification)
1913+
nonCompliantTools := toolNameMissingRequiredProperty("bootloader/params/verbose", compliancelevel.Specification)
19141914

19151915
if len(nonCompliantTools) > 0 {
19161916
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")
@@ -1933,7 +1933,7 @@ func PlatformTxtBootloaderParamsQuietMissing() (result ruleresult.Type, output s
19331933
return ruleresult.Skip, "platform.txt has no tools"
19341934
}
19351935

1936-
nonCompliantTools := toolNameMissingRequiredProperty("bootloader/params\\.quiet", compliancelevel.Specification)
1936+
nonCompliantTools := toolNameMissingRequiredProperty("bootloader/params/quiet", compliancelevel.Specification)
19371937

19381938
if len(nonCompliantTools) > 0 {
19391939
return ruleresult.Fail, strings.Join(nonCompliantTools, ", ")

0 commit comments

Comments
 (0)