Skip to content

Commit 2d263ad

Browse files
committed
Add rules for the platform.txt pluggable_monitor.* properties
The new pluggable monitor system for Arduino boards platforms introduces a set of `pluggable_monitor.*` properties to the platform.txt configuration file. These properties have requirements that are enforced by the rules added here.
1 parent 5bc680a commit 2d263ad

File tree

12 files changed

+433
-0
lines changed

12 files changed

+433
-0
lines changed

Diff for: internal/rule/ruleconfiguration/ruleconfiguration.go

+34
Original file line numberDiff line numberDiff line change
@@ -2864,6 +2864,40 @@ var configurations = []Type{
28642864
ErrorModes: []rulemode.Type{rulemode.Default},
28652865
RuleFunction: rulefunction.PlatformTxtPluggableDiscoveryDiscoveryIDPatternMissing,
28662866
},
2867+
{
2868+
ProjectType: projecttype.Platform,
2869+
SuperprojectType: projecttype.All,
2870+
Category: "configuration files",
2871+
Subcategory: "platform.txt",
2872+
ID: "PF094",
2873+
Brief: "pluggable_monitor.pattern.PROTOCOL_ID < min length",
2874+
Description: "The `pluggable_monitor.pattern.PROTOCOL_ID` property in the platform's `platform.txt` configuration file is shorter than the minimum length.",
2875+
MessageTemplate: "pluggable_monitor.pattern.PROTOCOL_ID value for protocol(s) {{.}} is less than the minimum length.",
2876+
Reference: "https://arduino.github.io/arduino-cli/latest/platform-specification/#pluggable-monitor",
2877+
DisableModes: nil,
2878+
EnableModes: []rulemode.Type{rulemode.Default},
2879+
InfoModes: nil,
2880+
WarningModes: nil,
2881+
ErrorModes: []rulemode.Type{rulemode.Default},
2882+
RuleFunction: rulefunction.PlatformTxtPluggableMonitorPatternProtocolIDLTMinLength,
2883+
},
2884+
{
2885+
ProjectType: projecttype.Platform,
2886+
SuperprojectType: projecttype.All,
2887+
Category: "configuration files",
2888+
Subcategory: "platform.txt",
2889+
ID: "PF095",
2890+
Brief: "invalid pluggable_monitor.required.PROTOCOL_ID format",
2891+
Description: "The tool dependency reference for a pluggable monitor in the platform's `platform.txt` configuration file has an invalid format.",
2892+
MessageTemplate: "Value for tool dependency reference of pluggable monitor protocol(s) {{.}} is invalid.",
2893+
Reference: "https://arduino.github.io/arduino-cli/latest/platform-specification/#pluggable-monitor",
2894+
DisableModes: nil,
2895+
EnableModes: []rulemode.Type{rulemode.Default},
2896+
InfoModes: nil,
2897+
WarningModes: nil,
2898+
ErrorModes: []rulemode.Type{rulemode.Default},
2899+
RuleFunction: rulefunction.PlatformTxtPluggableMonitorRequiredProtocolIDInvalid,
2900+
},
28672901
{
28682902
ProjectType: projecttype.Platform,
28692903
SuperprojectType: projecttype.All,

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

+56
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,62 @@ func PlatformTxtPluggableDiscoveryDiscoveryIDPatternMissing() (result ruleresult
17361736
return ruleresult.Pass, ""
17371737
}
17381738

1739+
// PlatformTxtPluggableMonitorPatternProtocolIDLTMinLength checks if the platform.txt pluggable_monitor.pattern.PROTOCOL_ID property value is less than the minimum length.
1740+
func PlatformTxtPluggableMonitorPatternProtocolIDLTMinLength() (result ruleresult.Type, output string) {
1741+
if !projectdata.PlatformTxtExists() {
1742+
return ruleresult.Skip, "Platform has no platform.txt"
1743+
}
1744+
1745+
if projectdata.PlatformTxtLoadError() != nil {
1746+
return ruleresult.NotRun, "Couldn't load platform.txt"
1747+
}
1748+
1749+
if projectdata.PlatformTxt().SubTree("pluggable_monitor.pattern").Size() == 0 {
1750+
return ruleresult.Skip, "Property not present"
1751+
}
1752+
1753+
nonCompliant := []string{}
1754+
for _, protocol := range projectdata.PlatformTxt().SubTree("pluggable_monitor.pattern").Keys() {
1755+
if schema.PropertyLessThanMinLength("pluggable_monitor\\.pattern/"+protocol, projectdata.PlatformTxtSchemaValidationResult()[compliancelevel.Specification]) {
1756+
nonCompliant = append(nonCompliant, protocol)
1757+
}
1758+
}
1759+
1760+
if len(nonCompliant) > 0 {
1761+
return ruleresult.Fail, strings.Join(nonCompliant, ", ")
1762+
}
1763+
1764+
return ruleresult.Pass, ""
1765+
}
1766+
1767+
// PlatformTxtPluggableMonitorRequiredProtocolIDInvalid checks if any of the pluggable monitor tool references have invalid format.
1768+
func PlatformTxtPluggableMonitorRequiredProtocolIDInvalid() (result ruleresult.Type, output string) {
1769+
if !projectdata.PlatformTxtExists() {
1770+
return ruleresult.Skip, "Platform has no platform.txt"
1771+
}
1772+
1773+
if projectdata.PlatformTxtLoadError() != nil {
1774+
return ruleresult.NotRun, "Couldn't load platform.txt"
1775+
}
1776+
1777+
if projectdata.PlatformTxt().SubTree("pluggable_monitor.required").Size() == 0 {
1778+
return ruleresult.Skip, "Property not present"
1779+
}
1780+
1781+
nonCompliant := []string{}
1782+
for _, protocol := range projectdata.PlatformTxt().SubTree("pluggable_monitor.required").Keys() {
1783+
if schema.PropertyPatternMismatch("pluggable_monitor\\.required/"+protocol, projectdata.PlatformTxtSchemaValidationResult()[compliancelevel.Specification]) {
1784+
nonCompliant = append(nonCompliant, protocol)
1785+
}
1786+
}
1787+
1788+
if len(nonCompliant) > 0 {
1789+
return ruleresult.Fail, strings.Join(nonCompliant, ", ")
1790+
}
1791+
1792+
return ruleresult.Pass, ""
1793+
}
1794+
17391795
// PlatformTxtUploadFieldFieldNameGTMaxLength checks if any platform.txt tools.UPLOAD_RECIPE_ID.upload.field.FIELD_NAME property value is greater than the maximum length.
17401796
func PlatformTxtUploadFieldFieldNameGTMaxLength() (result ruleresult.Type, output string) {
17411797
if !projectdata.PlatformTxtExists() {

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

+24
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,30 @@ func TestPlatformTxtPluggableDiscoveryDiscoveryIDPatternMissing(t *testing.T) {
993993
checkPlatformRuleFunction(PlatformTxtPluggableDiscoveryDiscoveryIDPatternMissing, testTables, t)
994994
}
995995

996+
func TestPlatformTxtPluggableMonitorPatternProtocolIDLTMinLength(t *testing.T) {
997+
testTables := []platformRuleFunctionTestTable{
998+
{"Missing", "missing-platform.txt", ruleresult.Skip, ""},
999+
{"Invalid", "invalid-platform.txt", ruleresult.NotRun, ""},
1000+
{"Property absent", "no-pluggable-monitors-platform.txt", ruleresult.Skip, ""},
1001+
{"Property LT min", "pluggable-monitor-pattern-protocol-id-LT-platform.txt", ruleresult.Fail, "^network, ble$"},
1002+
{"Valid", "valid-with-manual-installation-pluggable-monitors-platform.txt", ruleresult.Pass, ""},
1003+
}
1004+
1005+
checkPlatformRuleFunction(PlatformTxtPluggableMonitorPatternProtocolIDLTMinLength, testTables, t)
1006+
}
1007+
1008+
func TestPlatformTxtPluggableMonitorRequiredProtocolIDInvalid(t *testing.T) {
1009+
testTables := []platformRuleFunctionTestTable{
1010+
{"Missing", "missing-platform.txt", ruleresult.Skip, ""},
1011+
{"Invalid", "invalid-platform.txt", ruleresult.NotRun, ""},
1012+
{"Property absent", "no-pluggable-monitors-platform.txt", ruleresult.Skip, ""},
1013+
{"Property invalid", "invalid-pluggable-monitor-required-platform.txt", ruleresult.Fail, "^network, ble$"},
1014+
{"Valid", "valid-platform.txt", ruleresult.Pass, ""},
1015+
}
1016+
1017+
checkPlatformRuleFunction(PlatformTxtPluggableMonitorRequiredProtocolIDInvalid, testTables, t)
1018+
}
1019+
9961020
func TestPlatformTxtUploadFieldFieldNameGTMaxLength(t *testing.T) {
9971021
testTables := []platformRuleFunctionTestTable{
9981022
{"Missing", "missing-platform.txt", ruleresult.Skip, ""},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
buno.name=Buno
2+
buno.build.board=BUNO
3+
buno.build.core=arduino
4+
buno.build.variant=standard
5+
buno.upload.tool=avrdude
6+
buno.upload.maximum_size=32256
7+
buno.upload.maximum_data_size=2048
8+
9+
uno.name=Arduino Uno
10+
uno.build.board=UNO
11+
uno.build.core=arduino
12+
uno.build.variant=standard
13+
uno.upload.tool=avrdude
14+
uno.upload.maximum_size=32256
15+
uno.upload.maximum_data_size=2048
16+
17+
funo.name=Funo
18+
funo.build.board=FUNO
19+
funo.build.core=arduino
20+
funo.build.variant=standard
21+
funo.upload.tool=avrdude
22+
funo.upload.maximum_size=32256
23+
funo.upload.maximum_data_size=2048
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name=Arduino AVR Boards
2+
version=1.8.3
3+
compiler.warning_flags.none=asdf
4+
compiler.warning_flags.default=asdf
5+
compiler.warning_flags.more=asdf
6+
compiler.warning_flags.all=asdf
7+
compiler.optimization_flags.debug=
8+
compiler.optimization_flags.release=
9+
compiler.c.extra_flags=
10+
compiler.c.elf.extra_flags=
11+
compiler.S.extra_flags=
12+
compiler.cpp.extra_flags=
13+
compiler.ar.extra_flags=
14+
compiler.objcopy.eep.extra_flags=
15+
compiler.elf2hex.extra_flags=
16+
recipe.c.o.pattern=asdf {compiler.c.extra_flags}
17+
recipe.cpp.o.pattern=asdf {compiler.cpp.extra_flags}
18+
recipe.S.o.pattern=asdf {compiler.S.extra_flags}
19+
recipe.ar.pattern=asdf {compiler.ar.extra_flags}
20+
recipe.c.combine.pattern=asdf {compiler.c.elf.extra_flags}
21+
recipe.preproc.macros=asdf {compiler.cpp.extra_flags}
22+
recipe.objcopy.eep.pattern=asdf
23+
recipe.objcopy.hex.pattern=asdf
24+
recipe.output.tmp_file=asdf
25+
recipe.output.save_file=asdf
26+
recipe.size.pattern=asdf
27+
recipe.size.regex=asdf
28+
recipe.size.regex.data=asdf
29+
pluggable_discovery.required.0=builtin:serial-discovery
30+
pluggable_discovery.required.1=builtin:mdns-discovery
31+
pluggable_monitor.required.carrier-pigeon=coop:coo
32+
pluggable_monitor.required.network=bar
33+
pluggable_monitor.required.ble=
34+
tools.avrdude.upload.field.foo_field_name=Some field label
35+
tools.avrdude.upload.field.foo_field_name.secret=true
36+
tools.avrdude.upload.params.verbose=-v
37+
tools.avrdude.upload.params.quiet=-q -q
38+
tools.avrdude.upload.pattern=asdf
39+
tools.bossac.upload.field.bar_field_name=Some other field label
40+
tools.bossac.upload.params.verbose=-v
41+
tools.bossac.upload.params.quiet=-q -q
42+
tools.bossac.upload.pattern=asdf
43+
tools.avrdude.program.params.verbose=-v
44+
tools.avrdude.program.params.quiet=-q -q
45+
tools.avrdude.program.pattern=asdf
46+
tools.bossac.program.params.verbose=-v
47+
tools.bossac.program.params.quiet=-q -q
48+
tools.bossac.program.pattern=asdf
49+
tools.avrdude.erase.params.verbose=-v
50+
tools.avrdude.erase.params.quiet=-q -q
51+
tools.avrdude.erase.pattern=asdf
52+
tools.bossac.erase.params.verbose=-v
53+
tools.bossac.erase.params.quiet=-q -q
54+
tools.bossac.erase.pattern=asdf
55+
tools.avrdude.bootloader.params.verbose=-v
56+
tools.avrdude.bootloader.params.quiet=-q -q
57+
tools.avrdude.bootloader.pattern=asdf
58+
tools.bossac.bootloader.params.verbose=-v
59+
tools.bossac.bootloader.params.quiet=-q -q
60+
tools.bossac.bootloader.pattern=asdf
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
buno.name=Buno
2+
buno.build.board=BUNO
3+
buno.build.core=arduino
4+
buno.build.variant=standard
5+
buno.upload.tool=avrdude
6+
buno.upload.maximum_size=32256
7+
buno.upload.maximum_data_size=2048
8+
9+
uno.name=Arduino Uno
10+
uno.build.board=UNO
11+
uno.build.core=arduino
12+
uno.build.variant=standard
13+
uno.upload.tool=avrdude
14+
uno.upload.maximum_size=32256
15+
uno.upload.maximum_data_size=2048
16+
17+
funo.name=Funo
18+
funo.build.board=FUNO
19+
funo.build.core=arduino
20+
funo.build.variant=standard
21+
funo.upload.tool=avrdude
22+
funo.upload.maximum_size=32256
23+
funo.upload.maximum_data_size=2048
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name=Arduino AVR Boards
2+
version=1.8.3
3+
compiler.warning_flags.none=asdf
4+
compiler.warning_flags.default=asdf
5+
compiler.warning_flags.more=asdf
6+
compiler.warning_flags.all=asdf
7+
compiler.optimization_flags.debug=
8+
compiler.optimization_flags.release=
9+
compiler.c.extra_flags=
10+
compiler.c.elf.extra_flags=
11+
compiler.S.extra_flags=
12+
compiler.cpp.extra_flags=
13+
compiler.ar.extra_flags=
14+
compiler.objcopy.eep.extra_flags=
15+
compiler.elf2hex.extra_flags=
16+
recipe.c.o.pattern=asdf {compiler.c.extra_flags}
17+
recipe.cpp.o.pattern=asdf {compiler.cpp.extra_flags}
18+
recipe.S.o.pattern=asdf {compiler.S.extra_flags}
19+
recipe.ar.pattern=asdf {compiler.ar.extra_flags}
20+
recipe.c.combine.pattern=asdf {compiler.c.elf.extra_flags}
21+
recipe.preproc.macros=asdf {compiler.cpp.extra_flags}
22+
recipe.objcopy.eep.pattern=asdf
23+
recipe.objcopy.hex.pattern=asdf
24+
recipe.output.tmp_file=asdf
25+
recipe.output.save_file=asdf
26+
recipe.size.pattern=asdf
27+
recipe.size.regex=asdf
28+
recipe.size.regex.data=asdf
29+
tools.avrdude.upload.params.verbose=-v
30+
tools.avrdude.upload.params.quiet=-q -q
31+
tools.avrdude.upload.pattern=asdf
32+
tools.bossac.upload.params.verbose=-v
33+
tools.bossac.upload.params.quiet=-q -q
34+
tools.bossac.upload.pattern=asdf
35+
tools.avrdude.program.params.verbose=-v
36+
tools.avrdude.program.params.quiet=-q -q
37+
tools.avrdude.program.pattern=asdf
38+
tools.bossac.program.params.verbose=-v
39+
tools.bossac.program.params.quiet=-q -q
40+
tools.bossac.program.pattern=asdf
41+
tools.avrdude.erase.params.verbose=-v
42+
tools.avrdude.erase.params.quiet=-q -q
43+
tools.avrdude.erase.pattern=asdf
44+
tools.bossac.erase.params.verbose=-v
45+
tools.bossac.erase.params.quiet=-q -q
46+
tools.bossac.erase.pattern=asdf
47+
tools.avrdude.bootloader.params.verbose=-v
48+
tools.avrdude.bootloader.params.quiet=-q -q
49+
tools.avrdude.bootloader.pattern=asdf
50+
tools.bossac.bootloader.params.verbose=-v
51+
tools.bossac.bootloader.params.quiet=-q -q
52+
tools.bossac.bootloader.pattern=asdf
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
buno.name=Buno
2+
buno.build.board=BUNO
3+
buno.build.core=arduino
4+
buno.build.variant=standard
5+
buno.upload.tool=avrdude
6+
buno.upload.maximum_size=32256
7+
buno.upload.maximum_data_size=2048
8+
9+
uno.name=Arduino Uno
10+
uno.build.board=UNO
11+
uno.build.core=arduino
12+
uno.build.variant=standard
13+
uno.upload.tool=avrdude
14+
uno.upload.maximum_size=32256
15+
uno.upload.maximum_data_size=2048
16+
17+
funo.name=Funo
18+
funo.build.board=FUNO
19+
funo.build.core=arduino
20+
funo.build.variant=standard
21+
funo.upload.tool=avrdude
22+
funo.upload.maximum_size=32256
23+
funo.upload.maximum_data_size=2048
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name=Arduino AVR Boards
2+
version=1.8.3
3+
compiler.warning_flags.none=asdf
4+
compiler.warning_flags.default=asdf
5+
compiler.warning_flags.more=asdf
6+
compiler.warning_flags.all=asdf
7+
compiler.optimization_flags.debug=
8+
compiler.optimization_flags.release=
9+
compiler.c.extra_flags=
10+
compiler.c.elf.extra_flags=
11+
compiler.S.extra_flags=
12+
compiler.cpp.extra_flags=
13+
compiler.ar.extra_flags=
14+
compiler.objcopy.eep.extra_flags=
15+
compiler.elf2hex.extra_flags=
16+
recipe.c.o.pattern=asdf {compiler.c.extra_flags}
17+
recipe.cpp.o.pattern=asdf {compiler.cpp.extra_flags}
18+
recipe.S.o.pattern=asdf {compiler.S.extra_flags}
19+
recipe.ar.pattern=asdf {compiler.ar.extra_flags}
20+
recipe.c.combine.pattern=asdf {compiler.c.elf.extra_flags}
21+
recipe.preproc.macros=asdf {compiler.cpp.extra_flags}
22+
recipe.objcopy.eep.pattern=asdf
23+
recipe.objcopy.hex.pattern=asdf
24+
recipe.output.tmp_file=asdf
25+
recipe.output.save_file=asdf
26+
recipe.size.pattern=asdf
27+
recipe.size.regex=asdf
28+
recipe.size.regex.data=asdf
29+
pluggable_discovery.foo_discovery.pattern=asdf
30+
pluggable_monitor.pattern.carrier-pigeon=coo
31+
pluggable_monitor.pattern.network=
32+
pluggable_monitor.pattern.ble=
33+
tools.avrdude.upload.params.verbose=-v
34+
tools.avrdude.upload.params.quiet=-q -q
35+
tools.avrdude.upload.pattern=asdf
36+
tools.bossac.upload.params.verbose=-v
37+
tools.bossac.upload.params.quiet=-q -q
38+
tools.bossac.upload.pattern=asdf
39+
tools.avrdude.program.params.verbose=-v
40+
tools.avrdude.program.params.quiet=-q -q
41+
tools.avrdude.program.pattern=asdf
42+
tools.bossac.program.params.verbose=-v
43+
tools.bossac.program.params.quiet=-q -q
44+
tools.bossac.program.pattern=asdf
45+
tools.avrdude.erase.params.verbose=-v
46+
tools.avrdude.erase.params.quiet=-q -q
47+
tools.avrdude.erase.pattern=asdf
48+
tools.bossac.erase.params.verbose=-v
49+
tools.bossac.erase.params.quiet=-q -q
50+
tools.bossac.erase.pattern=asdf
51+
tools.avrdude.bootloader.params.verbose=-v
52+
tools.avrdude.bootloader.params.quiet=-q -q
53+
tools.avrdude.bootloader.pattern=asdf
54+
tools.bossac.bootloader.params.verbose=-v
55+
tools.bossac.bootloader.params.quiet=-q -q
56+
tools.bossac.bootloader.pattern=asdf

Diff for: internal/rule/rulefunction/testdata/platforms/valid-platform.txt/platform.txt

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ recipe.size.regex=asdf
2828
recipe.size.regex.data=asdf
2929
pluggable_discovery.required.0=builtin:serial-discovery
3030
pluggable_discovery.required.1=builtin:mdns-discovery
31+
pluggable_monitor.pattern.carrier-pigeon=coop:coo
32+
pluggable_monitor.required.network=foo:bar
33+
pluggable_monitor.required.ble=baz:qux
3134
tools.avrdude.upload.field.foo_field_name=Some field label
3235
tools.avrdude.upload.field.foo_field_name.secret=true
3336
tools.avrdude.upload.params.verbose=-v

0 commit comments

Comments
 (0)