Skip to content

Commit 34d81b4

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 dcda76a commit 34d81b4

File tree

7 files changed

+108
-4
lines changed

7 files changed

+108
-4
lines changed

Diff for: check/checkconfigurations/checkconfigurations.go

+15
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",

Diff for: check/checkfunctions/library.go

+63-4
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,57 @@ 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+
849900
// LibraryPropertiesDependsFieldDisallowedCharacters checks for disallowed characters in the library.properties "depends" field.
850901
func LibraryPropertiesDependsFieldDisallowedCharacters() (result checkresult.Type, output string) {
851902
if checkdata.LibraryPropertiesLoadError() != nil {
@@ -875,11 +926,10 @@ func LibraryPropertiesDependsFieldNotInIndex() (result checkresult.Type, output
875926
return checkresult.Skip, "Field not present"
876927
}
877928

878-
dependencies := strings.Split(depends, ",")
929+
dependencies := commaSeparatedToList(depends)
879930

880931
dependenciesNotInIndex := []string{}
881932
for _, dependency := range dependencies {
882-
dependency = strings.TrimSpace(dependency)
883933
if dependency == "" {
884934
continue
885935
}
@@ -959,10 +1009,9 @@ func LibraryPropertiesIncludesFieldItemNotFound() (result checkresult.Type, outp
9591009
return checkresult.Skip, "Field not present"
9601010
}
9611011

962-
includesList := strings.Split(includes, ",")
1012+
includesList := commaSeparatedToList(includes)
9631013

9641014
findInclude := func(include string) bool {
965-
include = strings.TrimSpace(include)
9661015
if include == "" {
9671016
return true
9681017
}
@@ -1357,3 +1406,13 @@ func nameInLibraryManagerIndex(name string) bool {
13571406

13581407
return false
13591408
}
1409+
1410+
// commaSeparatedToList returns the list equivalent of a comma-separated string.
1411+
func commaSeparatedToList(commaSeparated string) []string {
1412+
list := []string{}
1413+
for _, item := range strings.Split(commaSeparated, ",") {
1414+
list = append(list, strings.TrimSpace(item))
1415+
}
1416+
1417+
return list
1418+
}

Diff for: check/checkfunctions/library_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,18 @@ 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+
328340
func TestLibraryPropertiesDependsFieldNotInIndex(t *testing.T) {
329341
testTables := []libraryCheckFunctionTestTable{
330342
{"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.

0 commit comments

Comments
 (0)