Skip to content

Commit fe8b66a

Browse files
committed
Add check for architecture alias
Check for the presence of an alias architecture name in the library.properties `architectures` field without also having the true architecture name.
1 parent d6fbfe1 commit fe8b66a

File tree

7 files changed

+107
-4
lines changed

7 files changed

+107
-4
lines changed

check/checkconfigurations/checkconfigurations.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,21 @@ var configurations = []Type{
716716
ErrorModes: []checkmode.Type{checkmode.Default},
717717
CheckFunction: checkfunctions.LibraryPropertiesArchitecturesFieldLTMinLength,
718718
},
719+
{
720+
ProjectType: projecttype.Library,
721+
Category: "library.properties",
722+
Subcategory: "architectures field",
723+
ID: "",
724+
Brief: "architecture alias",
725+
Description: "Alternative development frameworks diverged on architecture naming.",
726+
MessageTemplate: "Architecture alias(es) in library.properties architectures field: {{.}}. Please also specify the true Arduino architectures compatibilities of the library. See https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format",
727+
DisableModes: nil,
728+
EnableModes: []checkmode.Type{checkmode.Default},
729+
InfoModes: nil,
730+
WarningModes: []checkmode.Type{checkmode.Default},
731+
ErrorModes: []checkmode.Type{checkmode.Strict},
732+
CheckFunction: checkfunctions.LibraryPropertiesArchitecturesFieldSoloAlias,
733+
},
719734
{
720735
ProjectType: projecttype.Library,
721736
Category: "library.properties",

check/checkfunctions/library.go

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,57 @@ func LibraryPropertiesArchitecturesFieldLTMinLength() (result checkresult.Type,
820820
return checkresult.Pass, ""
821821
}
822822

823+
// LibraryPropertiesArchitecturesFieldAlias checks whether an alias architecture name is present, but not its true Arduino architecture name.
824+
func LibraryPropertiesArchitecturesFieldSoloAlias() (result checkresult.Type, output string) {
825+
if checkdata.LibraryPropertiesLoadError() != nil {
826+
return checkresult.NotRun, "Couldn't load library.properties"
827+
}
828+
829+
architectures, ok := checkdata.LibraryProperties().GetOk("architectures")
830+
if !ok {
831+
return checkresult.Skip, "Field not present"
832+
}
833+
834+
architecturesList := commaSeparatedToList(strings.ToLower(architectures))
835+
836+
// Must be all lowercase (there is a separate check for incorrect architecture case).
837+
var aliases = map[string][]string{
838+
"atmelavr": {"avr"},
839+
"atmelmegaavr": {"megaavr"},
840+
"atmelsam": {"sam", "samd"},
841+
"espressif32": {"esp32"},
842+
"espressif8266": {"esp8266"},
843+
"intel_arc32": {"arc32"},
844+
"nordicnrf52": {"nRF5", "nrf52", "mbed"},
845+
}
846+
847+
trueArchitecturePresent := func(trueArchitecturesQuery []string) bool {
848+
for _, trueArchitectureQuery := range trueArchitecturesQuery {
849+
for _, architecture := range architecturesList {
850+
if architecture == trueArchitectureQuery {
851+
return true
852+
}
853+
}
854+
}
855+
856+
return false
857+
}
858+
859+
soloAliases := []string{}
860+
for _, architecture := range architecturesList {
861+
trueEquivalents, isAlias := aliases[architecture]
862+
if isAlias && !trueArchitecturePresent(trueEquivalents) {
863+
soloAliases = append(soloAliases, architecture)
864+
}
865+
}
866+
867+
if len(soloAliases) > 0 {
868+
return checkresult.Fail, strings.Join(soloAliases, ", ")
869+
}
870+
871+
return checkresult.Pass, ""
872+
}
873+
823874
// LibraryPropertiesDependsFieldDisallowedCharacters checks for disallowed characters in the library.properties "depends" field.
824875
func LibraryPropertiesDependsFieldDisallowedCharacters() (result checkresult.Type, output string) {
825876
if checkdata.LibraryPropertiesLoadError() != nil {
@@ -849,11 +900,10 @@ func LibraryPropertiesDependsFieldNotInIndex() (result checkresult.Type, output
849900
return checkresult.NotRun, "Field not present"
850901
}
851902

852-
dependencies := strings.Split(depends, ",")
903+
dependencies := commaSeparatedToList(depends)
853904

854905
dependenciesNotInIndex := []string{}
855906
for _, dependency := range dependencies {
856-
dependency = strings.TrimSpace(dependency)
857907
if dependency == "" {
858908
continue
859909
}
@@ -933,10 +983,9 @@ func LibraryPropertiesIncludesFieldItemNotFound() (result checkresult.Type, outp
933983
return checkresult.NotRun, "Field not present"
934984
}
935985

936-
includesList := strings.Split(includes, ",")
986+
includesList := commaSeparatedToList(includes)
937987

938988
findInclude := func(include string) bool {
939-
include = strings.TrimSpace(include)
940989
if include == "" {
941990
return true
942991
}
@@ -1339,3 +1388,12 @@ func runRequiredLibraryPropertiesFieldCheck() (bool, string) {
13391388

13401389
return true, ""
13411390
}
1391+
1392+
func commaSeparatedToList(commaSeparated string) []string {
1393+
list := []string{}
1394+
for _, item := range strings.Split(commaSeparated, ",") {
1395+
list = append(list, strings.TrimSpace(item))
1396+
}
1397+
1398+
return list
1399+
}

check/checkfunctions/library_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,18 @@ func TestLibraryPropertiesUrlFieldDeadLink(t *testing.T) {
304304
checkLibraryCheckFunction(LibraryPropertiesUrlFieldDeadLink, testTables, t)
305305
}
306306

307+
func TestLibraryPropertiesArchitecturesFieldSoloAlias(t *testing.T) {
308+
testTables := []libraryCheckFunctionTestTable{
309+
{"Unable to load", "InvalidLibraryProperties", checkresult.NotRun, ""},
310+
{"Not defined", "MissingFields", checkresult.Skip, ""},
311+
{"Solo alias", "ArchitectureAliasSolo", checkresult.Fail, ""},
312+
{"Alias w/ true", "ArchitectureAliasWithTrue", checkresult.Pass, ""},
313+
{"No alias", "Recursive", checkresult.Pass, ""},
314+
}
315+
316+
checkLibraryCheckFunction(LibraryPropertiesArchitecturesFieldSoloAlias, testTables, t)
317+
}
318+
307319
func TestLibraryPropertiesDependsFieldNotInIndex(t *testing.T) {
308320
testTables := []libraryCheckFunctionTestTable{
309321
{"Unable to load", "InvalidLibraryProperties", checkresult.NotRun, ""},
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=ArchitectureAliasSolo
2+
version=1.0.0
3+
author=Cristian Maglie <[email protected]>, Pippo Pluto <[email protected]>
4+
maintainer=Cristian Maglie <[email protected]>
5+
sentence=A library that makes coding a web server a breeze.
6+
paragraph=Supports HTTP1.1 and you can do GET and POST.
7+
category=Communication
8+
url=http://example.com/
9+
architectures=atmelavr, samd

check/checkfunctions/testdata/libraries/ArchitectureAliasSolo/src/ArchitectureAliasSolo.h

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=ArchitectureAliasWithTrue
2+
version=1.0.0
3+
author=Cristian Maglie <[email protected]>, Pippo Pluto <[email protected]>
4+
maintainer=Cristian Maglie <[email protected]>
5+
sentence=A library that makes coding a web server a breeze.
6+
paragraph=Supports HTTP1.1 and you can do GET and POST.
7+
category=Communication
8+
url=http://example.com/
9+
architectures=avr, atmelavr, samd

check/checkfunctions/testdata/libraries/ArchitectureAliasWithTrue/src/ArchitectureAliasWithTrue.h

Whitespace-only changes.

0 commit comments

Comments
 (0)