Skip to content

Commit 4602827

Browse files
authored
Merge pull request #110 from arduino/per1234/add-checks
Add checks for library.properties architectures field
2 parents dcda76a + 92905dd commit 4602827

File tree

11 files changed

+219
-4
lines changed

11 files changed

+219
-4
lines changed

Diff for: check/checkconfigurations/checkconfigurations.go

+30
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,36 @@ 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+
},
734+
{
735+
ProjectType: projecttype.Library,
736+
Category: "library.properties",
737+
Subcategory: "architectures field",
738+
ID: "",
739+
Brief: "miscased architecture",
740+
Description: "",
741+
MessageTemplate: "Incorrect case of library.properties architectures field item(s): {{.}}. Architectures are case sensitive. See https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format",
742+
DisableModes: nil,
743+
EnableModes: []checkmode.Type{checkmode.Default},
744+
InfoModes: nil,
745+
WarningModes: []checkmode.Type{checkmode.Default},
746+
ErrorModes: []checkmode.Type{checkmode.Strict},
747+
CheckFunction: checkfunctions.LibraryPropertiesArchitecturesFieldValueCase,
748+
},
719749
{
720750
ProjectType: projecttype.Library,
721751
Category: "library.properties",

Diff for: check/checkfunctions/library.go

+129-4
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,123 @@ func LibraryPropertiesArchitecturesFieldLTMinLength() (result checkresult.Type,
846846
return checkresult.Pass, ""
847847
}
848848

849+
// LibraryPropertiesArchitecturesFieldAlias checks whether an alias architecture name is present, but not its true Arduino architecture name.
850+
func LibraryPropertiesArchitecturesFieldSoloAlias() (result checkresult.Type, output string) {
851+
if checkdata.LibraryPropertiesLoadError() != nil {
852+
return checkresult.NotRun, "Couldn't load library.properties"
853+
}
854+
855+
architectures, ok := checkdata.LibraryProperties().GetOk("architectures")
856+
if !ok {
857+
return checkresult.Skip, "Field not present"
858+
}
859+
860+
architecturesList := commaSeparatedToList(strings.ToLower(architectures))
861+
862+
// Must be all lowercase (there is a separate check for incorrect architecture case).
863+
var aliases = map[string][]string{
864+
"atmelavr": {"avr"},
865+
"atmelmegaavr": {"megaavr"},
866+
"atmelsam": {"sam", "samd"},
867+
"espressif32": {"esp32"},
868+
"espressif8266": {"esp8266"},
869+
"intel_arc32": {"arc32"},
870+
"nordicnrf52": {"nRF5", "nrf52", "mbed"},
871+
}
872+
873+
trueArchitecturePresent := func(trueArchitecturesQuery []string) bool {
874+
for _, trueArchitectureQuery := range trueArchitecturesQuery {
875+
for _, architecture := range architecturesList {
876+
if architecture == trueArchitectureQuery {
877+
return true
878+
}
879+
}
880+
}
881+
882+
return false
883+
}
884+
885+
soloAliases := []string{}
886+
for _, architecture := range architecturesList {
887+
trueEquivalents, isAlias := aliases[architecture]
888+
if isAlias && !trueArchitecturePresent(trueEquivalents) {
889+
soloAliases = append(soloAliases, architecture)
890+
}
891+
}
892+
893+
if len(soloAliases) > 0 {
894+
return checkresult.Fail, strings.Join(soloAliases, ", ")
895+
}
896+
897+
return checkresult.Pass, ""
898+
}
899+
900+
// LibraryPropertiesArchitecturesFieldValueCase checks for incorrect case of common architectures.
901+
func LibraryPropertiesArchitecturesFieldValueCase() (result checkresult.Type, output string) {
902+
if checkdata.LibraryPropertiesLoadError() != nil {
903+
return checkresult.NotRun, "Couldn't load library.properties"
904+
}
905+
906+
architectures, ok := checkdata.LibraryProperties().GetOk("architectures")
907+
if !ok {
908+
return checkresult.Skip, "Field not present"
909+
}
910+
911+
architecturesList := commaSeparatedToList(architectures)
912+
913+
var commonArchitecturesList = []string{
914+
"apollo3",
915+
"arc32",
916+
"avr",
917+
"esp32",
918+
"esp8266",
919+
"i586",
920+
"i686",
921+
"k210",
922+
"mbed",
923+
"megaavr",
924+
"mraa",
925+
"nRF5",
926+
"nrf52",
927+
"pic32",
928+
"sam",
929+
"samd",
930+
"wiced",
931+
"win10",
932+
}
933+
934+
correctArchitecturePresent := func(correctArchitectureQuery string) bool {
935+
for _, architecture := range architecturesList {
936+
if architecture == correctArchitectureQuery {
937+
return true
938+
}
939+
}
940+
941+
return false
942+
}
943+
944+
miscasedArchitectures := []string{}
945+
for _, architecture := range architecturesList {
946+
for _, commonArchitecture := range commonArchitecturesList {
947+
if architecture == commonArchitecture {
948+
break
949+
}
950+
951+
if strings.EqualFold(architecture, commonArchitecture) && !correctArchitecturePresent(commonArchitecture) {
952+
// The architecture has incorrect case and the correctly cased name is not present in the architectures field.
953+
miscasedArchitectures = append(miscasedArchitectures, architecture)
954+
break
955+
}
956+
}
957+
}
958+
959+
if len(miscasedArchitectures) > 0 {
960+
return checkresult.Fail, strings.Join(miscasedArchitectures, ", ")
961+
}
962+
963+
return checkresult.Pass, ""
964+
}
965+
849966
// LibraryPropertiesDependsFieldDisallowedCharacters checks for disallowed characters in the library.properties "depends" field.
850967
func LibraryPropertiesDependsFieldDisallowedCharacters() (result checkresult.Type, output string) {
851968
if checkdata.LibraryPropertiesLoadError() != nil {
@@ -875,11 +992,10 @@ func LibraryPropertiesDependsFieldNotInIndex() (result checkresult.Type, output
875992
return checkresult.Skip, "Field not present"
876993
}
877994

878-
dependencies := strings.Split(depends, ",")
995+
dependencies := commaSeparatedToList(depends)
879996

880997
dependenciesNotInIndex := []string{}
881998
for _, dependency := range dependencies {
882-
dependency = strings.TrimSpace(dependency)
883999
if dependency == "" {
8841000
continue
8851001
}
@@ -959,10 +1075,9 @@ func LibraryPropertiesIncludesFieldItemNotFound() (result checkresult.Type, outp
9591075
return checkresult.Skip, "Field not present"
9601076
}
9611077

962-
includesList := strings.Split(includes, ",")
1078+
includesList := commaSeparatedToList(includes)
9631079

9641080
findInclude := func(include string) bool {
965-
include = strings.TrimSpace(include)
9661081
if include == "" {
9671082
return true
9681083
}
@@ -1357,3 +1472,13 @@ func nameInLibraryManagerIndex(name string) bool {
13571472

13581473
return false
13591474
}
1475+
1476+
// commaSeparatedToList returns the list equivalent of a comma-separated string.
1477+
func commaSeparatedToList(commaSeparated string) []string {
1478+
list := []string{}
1479+
for _, item := range strings.Split(commaSeparated, ",") {
1480+
list = append(list, strings.TrimSpace(item))
1481+
}
1482+
1483+
return list
1484+
}

Diff for: check/checkfunctions/library_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,30 @@ func TestLibraryPropertiesUrlFieldDeadLink(t *testing.T) {
325325
checkLibraryCheckFunction(LibraryPropertiesUrlFieldDeadLink, testTables, t)
326326
}
327327

328+
func TestLibraryPropertiesArchitecturesFieldSoloAlias(t *testing.T) {
329+
testTables := []libraryCheckFunctionTestTable{
330+
{"Unable to load", "InvalidLibraryProperties", checkresult.NotRun, ""},
331+
{"Not defined", "MissingFields", checkresult.Skip, ""},
332+
{"Solo alias", "ArchitectureAliasSolo", checkresult.Fail, ""},
333+
{"Alias w/ true", "ArchitectureAliasWithTrue", checkresult.Pass, ""},
334+
{"No alias", "Recursive", checkresult.Pass, ""},
335+
}
336+
337+
checkLibraryCheckFunction(LibraryPropertiesArchitecturesFieldSoloAlias, testTables, t)
338+
}
339+
340+
func TestLibraryPropertiesArchitecturesFieldValueCase(t *testing.T) {
341+
testTables := []libraryCheckFunctionTestTable{
342+
{"Unable to load", "InvalidLibraryProperties", checkresult.NotRun, ""},
343+
{"Not defined", "MissingFields", checkresult.Skip, ""},
344+
{"Miscased", "ArchitectureMiscased", checkresult.Fail, ""},
345+
{"Miscased w/ correct case", "ArchitectureMiscasedWithCorrect", checkresult.Pass, ""},
346+
{"Correct case", "Recursive", checkresult.Pass, ""},
347+
}
348+
349+
checkLibraryCheckFunction(LibraryPropertiesArchitecturesFieldValueCase, testTables, t)
350+
}
351+
328352
func TestLibraryPropertiesDependsFieldNotInIndex(t *testing.T) {
329353
testTables := []libraryCheckFunctionTestTable{
330354
{"Unable to load", "InvalidLibraryProperties", checkresult.NotRun, ""},
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

Diff for: check/checkfunctions/testdata/libraries/ArchitectureAliasSolo/src/ArchitectureAliasSolo.h

Whitespace-only changes.
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

Diff for: check/checkfunctions/testdata/libraries/ArchitectureAliasWithTrue/src/ArchitectureAliasWithTrue.h

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=ArchitectureMiscased
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, samd, foo

Diff for: check/checkfunctions/testdata/libraries/ArchitectureMiscased/src/ArchitectureMiscased.h

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=ArchitectureMiscasedWithCorrect
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, samd, avr, foo

Diff for: check/checkfunctions/testdata/libraries/ArchitectureMiscasedWithCorrect/src/ArchitectureMiscasedWithCorrect.h

Whitespace-only changes.

0 commit comments

Comments
 (0)