@@ -23,6 +23,7 @@ import (
2323 "github.com/arduino/arduino-lint/internal/rule/ruleresult"
2424 "github.com/arduino/arduino-lint/internal/rule/schema"
2525 "github.com/arduino/arduino-lint/internal/rule/schema/compliancelevel"
26+ "github.com/arduino/go-properties-orderedmap"
2627 "github.com/sirupsen/logrus"
2728)
2829
@@ -104,7 +105,7 @@ func BoardsTxtBoardIDBuildBoardMissing() (result ruleresult.Type, output string)
104105 return ruleresult .Skip , "boards.txt has no boards"
105106 }
106107
107- nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtBoardIds (), "build.board" )
108+ nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtBoardIds (), "build.board" , false )
108109
109110 if len (nonCompliantBoardIDs ) > 0 {
110111 return ruleresult .Fail , strings .Join (nonCompliantBoardIDs , ", " )
@@ -142,7 +143,7 @@ func BoardsTxtBoardIDBuildCoreMissing() (result ruleresult.Type, output string)
142143 return ruleresult .Skip , "boards.txt has no visible boards"
143144 }
144145
145- nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "build.core" )
146+ nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "build.core" , false )
146147
147148 if len (nonCompliantBoardIDs ) > 0 {
148149 return ruleresult .Fail , strings .Join (nonCompliantBoardIDs , ", " )
@@ -285,7 +286,7 @@ func BoardsTxtBoardIDUploadToolMissing() (result ruleresult.Type, output string)
285286 return ruleresult .Skip , "boards.txt has no visible boards"
286287 }
287288
288- nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "upload.tool" )
289+ nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "upload.tool" , false )
289290
290291 if len (nonCompliantBoardIDs ) > 0 {
291292 return ruleresult .Fail , strings .Join (nonCompliantBoardIDs , ", " )
@@ -323,7 +324,7 @@ func BoardsTxtBoardIDUploadMaximumSizeMissing() (result ruleresult.Type, output
323324 return ruleresult .Skip , "boards.txt has no visible boards"
324325 }
325326
326- nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "upload.maximum_size" )
327+ nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "upload.maximum_size" , false )
327328
328329 if len (nonCompliantBoardIDs ) > 0 {
329330 return ruleresult .Fail , strings .Join (nonCompliantBoardIDs , ", " )
@@ -361,7 +362,7 @@ func BoardsTxtBoardIDUploadMaximumDataSizeMissing() (result ruleresult.Type, out
361362 return ruleresult .Skip , "boards.txt has no visible boards"
362363 }
363364
364- nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "upload.maximum_data_size" )
365+ nonCompliantBoardIDs := boardIDMissingRequiredProperty (projectdata .BoardsTxtVisibleBoardIds (), "upload.maximum_data_size" , false )
365366
366367 if len (nonCompliantBoardIDs ) > 0 {
367368 return ruleresult .Fail , strings .Join (nonCompliantBoardIDs , ", " )
@@ -1691,7 +1692,7 @@ func PlatformTxtPluggableDiscoveryRequiredInvalid() (result ruleresult.Type, out
16911692 return ruleresult .NotRun , "Couldn't load platform.txt"
16921693 }
16931694
1694- if ! projectdata . PlatformTxt (). ContainsKey ( "pluggable_discovery.required" ) && projectdata .PlatformTxt (). SubTree ( "pluggable_discovery.required" ). Size () == 0 {
1695+ if ! containsKeyOrParent ( projectdata .PlatformTxt (), "pluggable_discovery.required" ) {
16951696 return ruleresult .Skip , "Property not present"
16961697 }
16971698
@@ -1970,12 +1971,20 @@ Unlike iDMissingRequiredProperty(), this function does a direct check on the pro
19701971This is necessary because JSON schema does not have the capability to account for the custom board options system.
19711972This function should not be used in cases where the JSON schema does cover a required property.
19721973*/
1973- func boardIDMissingRequiredProperty (boardIDs []string , propertyName string ) []string {
1974+ func boardIDMissingRequiredProperty (boardIDs []string , propertyName string , parentOK bool ) []string {
1975+ containsKey := func (key string ) bool {
1976+ if parentOK {
1977+ return containsKeyOrParent (projectdata .BoardsTxt (), key )
1978+ }
1979+
1980+ return projectdata .BoardsTxt ().ContainsKey (key )
1981+ }
1982+
19741983 nonCompliantBoardIDs := []string {}
19751984 for _ , boardID := range boardIDs {
19761985 logrus .Tracef ("Board ID: %s" , boardID )
19771986 boardIDHasProperty := func (boardID string , propertyName string ) bool {
1978- if projectdata . BoardsTxt (). ContainsKey (boardID + "." + propertyName ) {
1987+ if containsKey (boardID + "." + propertyName ) {
19791988 logrus .Trace ("Property defined at top level\n " )
19801989 return true // The board has a first level definition of the property. No need to check custom board options.
19811990
@@ -1992,7 +2001,7 @@ func boardIDMissingRequiredProperty(boardIDs []string, propertyName string) []st
19922001 boardOptionProperties := boardMenuProperties .SubTree (boardMenuID )
19932002 boardOptionIDs := boardOptionProperties .FirstLevelKeys ()
19942003 for _ , boardOptionID := range boardOptionIDs {
1995- if ! boardOptionProperties . ContainsKey (boardOptionID + "." + propertyName ) {
2004+ if ! containsKey (boardOptionID + "." + propertyName ) {
19962005 logrus .Tracef ("Option ID %s doesn't provide property\n " , boardOptionID )
19972006 menuProvidesProperty = false // Every option associated with the menuID must define the property.
19982007 break
@@ -2067,6 +2076,12 @@ func toolNameMissingRequiredProperty(propertyNameQuery string, complianceLevel c
20672076 return nonCompliantTools
20682077}
20692078
2079+ // containsKeyOrParent returns whether the given properties contain a key of the given name, or whether the given key is
2080+ // a first level of a key in the properties.
2081+ func containsKeyOrParent (propertiesMap * properties.Map , key string ) bool {
2082+ return propertiesMap .ContainsKey (key ) || propertiesMap .SubTree (key ).Size () > 0
2083+ }
2084+
20702085// iDMissingRequiredProperty returns the list of first level keys missing the given required property.
20712086func iDMissingRequiredProperty (iDs []string , propertyNameQuery string , validationResult schema.ValidationResult ) []string {
20722087 nonCompliantIDs := []string {}
0 commit comments