Skip to content

Commit 24f05cf

Browse files
committed
Add checks for library layout incompatibility with library.properties configuration
Some of the library.properties configurations are only supported for libraries with a "recursive" layout.
1 parent 336fc8f commit 24f05cf

File tree

17 files changed

+196
-0
lines changed

17 files changed

+196
-0
lines changed

check/checkconfigurations/checkconfigurations.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,36 @@ var configurations = []Type{
161161
ErrorModes: nil,
162162
CheckFunction: checkfunctions.LibraryPropertiesDependsFieldNotInIndex,
163163
},
164+
{
165+
ProjectType: projecttype.Library,
166+
Category: "library.properties",
167+
Subcategory: "dot_a_linkage field",
168+
ID: "",
169+
Brief: `"true" with "1.5" library format`,
170+
Description: `dot_a_linkage feature is only supported for the "1.5" or "recursive" library format.`,
171+
MessageTemplate: `library.properties dot_a_linkage field enabled but library is not in "1.5" format. See: https://arduino.github.io/arduino-cli/latest/library-specification/#source-code`,
172+
DisableModes: nil,
173+
EnableModes: []checkmode.Type{checkmode.All},
174+
InfoModes: nil,
175+
WarningModes: []checkmode.Type{checkmode.Permissive},
176+
ErrorModes: []checkmode.Type{checkmode.Default},
177+
CheckFunction: checkfunctions.LibraryPropertiesDotALinkageFieldTrueWithFlatLayout,
178+
},
179+
{
180+
ProjectType: projecttype.Library,
181+
Category: "library.properties",
182+
Subcategory: "precompiled field",
183+
ID: "",
184+
Brief: "precompiled with flat layout",
185+
Description: `precompiled feature is only supported for the "1.5" or "recursive" library format.`,
186+
MessageTemplate: `library.properties precompiled field value {{.}}, is not supported with "1.0" format. See: https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format`,
187+
DisableModes: nil,
188+
EnableModes: []checkmode.Type{checkmode.All},
189+
InfoModes: nil,
190+
WarningModes: []checkmode.Type{checkmode.Permissive},
191+
ErrorModes: []checkmode.Type{checkmode.Default},
192+
CheckFunction: checkfunctions.LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout,
193+
},
164194
{
165195
ProjectType: projecttype.Sketch,
166196
Category: "structure",

check/checkdata/library.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/arduino/arduino-check/project"
2626
"github.com/arduino/arduino-check/project/library/libraryproperties"
2727
"github.com/arduino/arduino-check/result/feedback"
28+
"github.com/arduino/arduino-cli/arduino/libraries"
2829
"github.com/arduino/go-paths-helper"
2930
"github.com/arduino/go-properties-orderedmap"
3031
"github.com/ory/jsonschema/v3"
@@ -33,6 +34,8 @@ import (
3334

3435
// Initialize gathers the library check data for the specified project.
3536
func InitializeForLibrary(project project.Type, schemasPath *paths.Path) {
37+
var err error
38+
3639
libraryProperties, libraryPropertiesLoadError = libraryproperties.Properties(project.Path)
3740
if libraryPropertiesLoadError != nil {
3841
logrus.Errorf("Error loading library.properties from %s: %s", project.Path, libraryPropertiesLoadError)
@@ -42,6 +45,18 @@ func InitializeForLibrary(project project.Type, schemasPath *paths.Path) {
4245
libraryPropertiesSchemaValidationResult = libraryproperties.Validate(libraryProperties, schemasPath)
4346
}
4447

48+
loadedLibrary, err = libraries.Load(project.Path, libraries.User)
49+
if err != nil {
50+
logrus.Errorf("Error loading library from %s: %s", project.Path, err)
51+
loadedLibrary = nil
52+
sourceHeaders = nil
53+
} else {
54+
sourceHeaders, err = loadedLibrary.SourceHeaders()
55+
if err != nil {
56+
panic(err)
57+
}
58+
}
59+
4560
if libraryManagerIndex == nil { // Only download the Library Manager index once
4661
url := "http://downloads.arduino.cc/libraries/library_index.json"
4762
httpResponse, err := http.Get(url)
@@ -84,6 +99,20 @@ func LibraryPropertiesSchemaValidationResult() map[compliancelevel.Type]*jsonsch
8499
return libraryPropertiesSchemaValidationResult
85100
}
86101

102+
var loadedLibrary *libraries.Library
103+
104+
// LoadedLibrary returns the library object generated by Arduino CLI.
105+
func LoadedLibrary() *libraries.Library {
106+
return loadedLibrary
107+
}
108+
109+
var sourceHeaders []string
110+
111+
// SourceHeaders returns the list of library source header filenames discovered by Arduino CLI.
112+
func SourceHeaders() []string {
113+
return sourceHeaders
114+
}
115+
87116
var libraryManagerIndex map[string]interface{}
88117

89118
// LibraryManagerIndex returns the Library Manager index data.

check/checkfunctions/library.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/arduino/arduino-check/check/checkdata/schema/compliancelevel"
2626
"github.com/arduino/arduino-check/check/checkresult"
2727
"github.com/arduino/arduino-check/configuration"
28+
"github.com/arduino/arduino-cli/arduino/libraries"
2829
"github.com/arduino/go-properties-orderedmap"
2930
"github.com/sirupsen/logrus"
3031
)
@@ -140,6 +141,42 @@ func LibraryPropertiesDependsFieldNotInIndex() (result checkresult.Type, output
140141
return checkresult.Pass, ""
141142
}
142143

144+
// LibraryPropertiesDotALinkageFieldTrueWithFlatLayout checks whether a library using the "dot_a_linkage" feature has the required recursive layout type.
145+
func LibraryPropertiesDotALinkageFieldTrueWithFlatLayout() (result checkresult.Type, output string) {
146+
if checkdata.LoadedLibrary() == nil {
147+
return checkresult.NotRun, ""
148+
}
149+
150+
_, ok := checkdata.LibraryProperties().GetOk("dot_a_linkage")
151+
if !ok {
152+
return checkresult.NotRun, ""
153+
}
154+
155+
if checkdata.LoadedLibrary().DotALinkage && checkdata.LoadedLibrary().Layout == libraries.FlatLayout {
156+
return checkresult.Fail, ""
157+
}
158+
159+
return checkresult.Pass, ""
160+
}
161+
162+
// LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout checks whether a precompiled library has the required recursive layout type.
163+
func LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout() (result checkresult.Type, output string) {
164+
if checkdata.LoadedLibrary() == nil || checkdata.LibraryPropertiesLoadError() != nil {
165+
return checkresult.NotRun, ""
166+
}
167+
168+
precompiled, ok := checkdata.LibraryProperties().GetOk("precompiled")
169+
if !ok {
170+
return checkresult.NotRun, ""
171+
}
172+
173+
if checkdata.LoadedLibrary().Precompiled && checkdata.LoadedLibrary().Layout == libraries.FlatLayout {
174+
return checkresult.Fail, precompiled
175+
}
176+
177+
return checkresult.Pass, ""
178+
}
179+
143180
// nameInLibraryManagerIndex returns whether there is a library in Library Manager index using the given name.
144181
func nameInLibraryManagerIndex(name string) bool {
145182
libraries := checkdata.LibraryManagerIndex()["libraries"].([]interface{})

check/checkfunctions/library_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,25 @@ func TestLibraryPropertiesDependsFieldNotInIndex(t *testing.T) {
9292

9393
checkCheckFunction(LibraryPropertiesDependsFieldNotInIndex, testTables, t)
9494
}
95+
96+
func TestLibraryPropertiesDotALinkageFieldTrueWithFlatLayout(t *testing.T) {
97+
testTables := []checkFunctionTestTable{
98+
{"Unable to load", "InvalidLibraryProperties", checkresult.NotRun, ""},
99+
{"Flat layout", "DotALinkageFlat", checkresult.Fail, ""},
100+
{"Recursive layout", "DotALinkage", checkresult.Pass, ""},
101+
}
102+
103+
checkCheckFunction(LibraryPropertiesDotALinkageFieldTrueWithFlatLayout, testTables, t)
104+
}
105+
106+
func TestLibraryPropertiesPrecompiledFieldEnabledWithFlatLayout(t *testing.T) {
107+
testTables := []checkFunctionTestTable{
108+
{"Unable to load", "InvalidLibraryProperties", checkresult.NotRun, ""},
109+
{"Flat layout", "PrecompiledFlat", checkresult.Fail, "^true$"},
110+
{"Recursive layout", "Precompiled", checkresult.Pass, ""},
111+
{"Recursive, not precompiled", "NotPrecompiled", checkresult.NotRun, ""},
112+
{"Flat, not precompiled", "NotPrecompiledFlat", checkresult.NotRun, ""},
113+
}
114+
115+
checkCheckFunction(LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout, testTables, t)
116+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=DotALinkage
2+
version=1.0.0
3+
author=Cristian Maglie <c.maglie@example.com>, Pippo Pluto <pippo@example.com>
4+
maintainer=Cristian Maglie <c.maglie@example.com>
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
10+
dot_a_linkage=true

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

Whitespace-only changes.

check/checkfunctions/testdata/libraries/DotALinkageFlat/DotALinkageFlat.h

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=DotALinkageFlat
2+
version=1.0.0
3+
author=Cristian Maglie <c.maglie@example.com>, Pippo Pluto <pippo@example.com>
4+
maintainer=Cristian Maglie <c.maglie@example.com>
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
10+
dot_a_linkage=true
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=NotPrecompiled
2+
version=1.0.0
3+
author=Cristian Maglie <c.maglie@example.com>, Pippo Pluto <pippo@example.com>
4+
maintainer=Cristian Maglie <c.maglie@example.com>
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
10+
includes=Recursive.h

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

Whitespace-only changes.

check/checkfunctions/testdata/libraries/NotPrecompiledFlat/NotPrecompiledFlat.h

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=NotPrecompiledFlat
2+
version=1.0.0
3+
author=Cristian Maglie <c.maglie@example.com>, Pippo Pluto <pippo@example.com>
4+
maintainer=Cristian Maglie <c.maglie@example.com>
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
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name=Precompiled
2+
version=1.0.0
3+
author=Cristian Maglie <c.maglie@example.com>, Pippo Pluto <pippo@example.com>
4+
maintainer=Cristian Maglie <c.maglie@example.com>
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
10+
includes=Recursive.h
11+
precompiled=true

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

Whitespace-only changes.

check/checkfunctions/testdata/libraries/PrecompiledFlat/PrecompiledFlat.h

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=PrecompiledFlat
2+
version=1.0.0
3+
author=Cristian Maglie <c.maglie@example.com>, Pippo Pluto <pippo@example.com>
4+
maintainer=Cristian Maglie <c.maglie@example.com>
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
10+
precompiled=true

0 commit comments

Comments
 (0)