From 80e2c2e4a724cb35559bf9d3c7572de7b9f96ca7 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 2 Sep 2020 16:31:02 +0200 Subject: [PATCH 1/4] Refactored commaSeparatedToList function --- arduino/libraries/loader.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arduino/libraries/loader.go b/arduino/libraries/loader.go index 3c30fd1708c..b062570e228 100644 --- a/arduino/libraries/loader.go +++ b/arduino/libraries/loader.go @@ -56,6 +56,14 @@ func makeNewLibrary(libraryDir *paths.Path, location LibraryLocation) (*Library, } } + commaSeparatedToList := func(in string) []string { + res := []string{} + for _, e := range strings.Split(in, ",") { + res = append(res, strings.TrimSpace(e)) + } + return res + } + library := &Library{} library.Location = location library.InstallDir = libraryDir @@ -71,10 +79,7 @@ func makeNewLibrary(libraryDir *paths.Path, location LibraryLocation) (*Library, if libProperties.Get("architectures") == "" { libProperties.Set("architectures", "*") } - library.Architectures = []string{} - for _, arch := range strings.Split(libProperties.Get("architectures"), ",") { - library.Architectures = append(library.Architectures, strings.TrimSpace(arch)) - } + library.Architectures = commaSeparatedToList(libProperties.Get("architectures")) libProperties.Set("category", strings.TrimSpace(libProperties.Get("category"))) if !ValidCategories[libProperties.Get("category")] { From 63634c7411d30880f1bf8f05524aea26a1633f5e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 2 Sep 2020 16:32:48 +0200 Subject: [PATCH 2/4] Added 'provides_includes' field in 'lib list' output structures --- arduino/libraries/libraries.go | 20 ++++++++ arduino/libraries/librariesresolver/cpp.go | 8 ++- arduino/libraries/loader.go | 4 ++ commands/lib/list.go | 2 + rpc/commands/lib.pb.go | 57 +++++++++++++--------- rpc/commands/lib.proto | 3 ++ 6 files changed, 67 insertions(+), 27 deletions(-) diff --git a/arduino/libraries/libraries.go b/arduino/libraries/libraries.go index 6c939eec70f..4403fa2ce50 100644 --- a/arduino/libraries/libraries.go +++ b/arduino/libraries/libraries.go @@ -16,6 +16,8 @@ package libraries import ( + "fmt" + "github.com/arduino/arduino-cli/arduino/cores" paths "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" @@ -71,6 +73,7 @@ type Library struct { License string Properties *properties.Map Examples paths.PathList + sourceHeaders []string } func (library *Library) String() string { @@ -153,3 +156,20 @@ func (library *Library) LocationPriorityFor(platformRelease, refPlatformRelease } return 0 } + +// SourceHeaders returns the C++ headers in the library. +func (library *Library) SourceHeaders() ([]string, error) { + if library.sourceHeaders == nil { + cppHeaders, err := library.SourceDir.ReadDir() + if err != nil { + return nil, fmt.Errorf("reading lib src dir: %s", err) + } + cppHeaders.FilterSuffix(".h", ".hpp", ".hh") + res := []string{} + for _, cppHeader := range cppHeaders { + res = append(res, cppHeader.Base()) + } + library.sourceHeaders = res + } + return library.sourceHeaders, nil +} diff --git a/arduino/libraries/librariesresolver/cpp.go b/arduino/libraries/librariesresolver/cpp.go index 9baf3d098c7..04e64dbc330 100644 --- a/arduino/libraries/librariesresolver/cpp.go +++ b/arduino/libraries/librariesresolver/cpp.go @@ -52,13 +52,11 @@ func (resolver *Cpp) ScanFromLibrariesManager(lm *librariesmanager.LibrariesMana // ScanLibrary reads a library to find and cache C++ headers for later retrieval func (resolver *Cpp) ScanLibrary(lib *libraries.Library) error { - cppHeaders, err := lib.SourceDir.ReadDir() + cppHeaders, err := lib.SourceHeaders() if err != nil { - return fmt.Errorf("reading lib src dir: %s", err) + return fmt.Errorf("reading lib headers: %s", err) } - cppHeaders.FilterSuffix(".h", ".hpp", ".hh") - for _, cppHeaderPath := range cppHeaders { - cppHeader := cppHeaderPath.Base() + for _, cppHeader := range cppHeaders { l := resolver.headers[cppHeader] l.Add(lib) resolver.headers[cppHeader] = l diff --git a/arduino/libraries/loader.go b/arduino/libraries/loader.go index b062570e228..912fc312606 100644 --- a/arduino/libraries/loader.go +++ b/arduino/libraries/loader.go @@ -100,6 +100,10 @@ func makeNewLibrary(libraryDir *paths.Path, location LibraryLocation) (*Library, library.Version = v } + if includes := libProperties.Get("includes"); includes != "" { + library.sourceHeaders = commaSeparatedToList(includes) + } + if err := addExamples(library); err != nil { return nil, errors.Errorf("scanning examples: %s", err) } diff --git a/commands/lib/list.go b/commands/lib/list.go index 48dad1fc609..4a76f1efff0 100644 --- a/commands/lib/list.go +++ b/commands/lib/list.go @@ -143,6 +143,7 @@ func GetOutputLibrary(lib *libraries.Library) *rpc.Library { cntplat = lib.ContainerPlatform.String() } + libHeaders, _ := lib.SourceHeaders() return &rpc.Library{ Name: lib.Name, Author: lib.Author, @@ -167,6 +168,7 @@ func GetOutputLibrary(lib *libraries.Library) *rpc.Library { Version: lib.Version.String(), License: lib.License, Examples: lib.Examples.AsStrings(), + ProvidesIncludes: libHeaders, } } diff --git a/rpc/commands/lib.pb.go b/rpc/commands/lib.pb.go index f147239b5bb..913963df787 100644 --- a/rpc/commands/lib.pb.go +++ b/rpc/commands/lib.pb.go @@ -1564,6 +1564,9 @@ type Library struct { Layout LibraryLayout `protobuf:"varint,25,opt,name=layout,proto3,enum=cc.arduino.cli.commands.LibraryLayout" json:"layout,omitempty"` // The example sketches provided by the library Examples []string `protobuf:"bytes,26,rep,name=examples,proto3" json:"examples,omitempty"` + // Value of the `includes` field in library.properties or, if missing, the list of + // include files available on the library source root directory. + ProvidesIncludes []string `protobuf:"bytes,27,rep,name=provides_includes,json=providesIncludes,proto3" json:"provides_includes,omitempty"` } func (x *Library) Reset() { @@ -1766,6 +1769,13 @@ func (x *Library) GetExamples() []string { return nil } +func (x *Library) GetProvidesIncludes() []string { + if x != nil { + return x.ProvidesIncludes + } + return nil +} + var File_commands_lib_proto protoreflect.FileDescriptor var file_commands_lib_proto_rawDesc = []byte{ @@ -1969,7 +1979,7 @@ var file_commands_lib_proto_rawDesc = []byte{ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x22, 0x93, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x22, 0xc0, 0x07, 0x0a, 0x07, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, @@ -2023,27 +2033,30 @@ var file_commands_lib_proto_rawDesc = []byte{ 0x6e, 0x64, 0x73, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x2e, 0x0a, 0x13, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x66, - 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x10, 0x01, 0x2a, 0x36, 0x0a, 0x0d, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, - 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x0f, 0x0a, 0x0b, 0x66, 0x6c, 0x61, 0x74, 0x5f, 0x6c, 0x61, - 0x79, 0x6f, 0x75, 0x74, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, - 0x69, 0x76, 0x65, 0x5f, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x10, 0x01, 0x2a, 0x63, 0x0a, 0x0f, - 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x0f, 0x0a, 0x0b, 0x69, 0x64, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x10, 0x02, - 0x12, 0x1f, 0x0a, 0x1b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x5f, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x10, - 0x03, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, - 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x73, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x2a, 0x2e, 0x0a, 0x13, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x53, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, + 0x65, 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x10, + 0x01, 0x2a, 0x36, 0x0a, 0x0d, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4c, 0x61, 0x79, 0x6f, + 0x75, 0x74, 0x12, 0x0f, 0x0a, 0x0b, 0x66, 0x6c, 0x61, 0x74, 0x5f, 0x6c, 0x61, 0x79, 0x6f, 0x75, + 0x74, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, + 0x5f, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x10, 0x01, 0x2a, 0x63, 0x0a, 0x0f, 0x4c, 0x69, 0x62, + 0x72, 0x61, 0x72, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x0a, 0x0b, + 0x69, 0x64, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x10, 0x02, 0x12, 0x1f, 0x0a, + 0x1b, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x10, 0x03, 0x42, 0x2d, + 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, + 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, + 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/rpc/commands/lib.proto b/rpc/commands/lib.proto index 6779d36b7fe..cb8c5d24f7f 100644 --- a/rpc/commands/lib.proto +++ b/rpc/commands/lib.proto @@ -268,6 +268,9 @@ message Library { LibraryLayout layout = 25; // The example sketches provided by the library repeated string examples = 26; + // Value of the `includes` field in library.properties or, if missing, the list of + // include files available on the library source root directory. + repeated string provides_includes = 27; } enum LibraryLayout { From 1adce5ce9715e26ce3265e1bed1ba3614a076d41 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 2 Sep 2020 16:44:34 +0200 Subject: [PATCH 3/4] Added integration tests for 'provides_includes' field --- test/test_lib.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test_lib.py b/test/test_lib.py index e088076ddd1..a91696ef091 100644 --- a/test/test_lib.py +++ b/test/test_lib.py @@ -56,6 +56,21 @@ def test_list(run_command): assert 1 == len(data) # be sure data contains the available version assert "" != data[0]["release"]["version"] + # be sure data contains the correct provides_includes field + assert "ArduinoJson.h" == data[0]["library"]["provides_includes"][0] + assert "ArduinoJson.hpp" == data[0]["library"]["provides_includes"][1] + + # Install something we can list without provides_includes field given in library.properties + result = run_command("lib install Braccio@2.0.4") + assert result.ok + # Look at the JSON output + result = run_command("lib list Braccio --format json") + assert result.ok + assert "" == result.stderr + data = json.loads(result.stdout) + assert 1 == len(data) + # be sure data contains the correct provides_includes field + assert "Braccio.h" == data[0]["library"]["provides_includes"][0] def test_install(run_command): From 0ccbeb5bab6c05acbe2ceeaf232f446aecceed07 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 3 Sep 2020 10:43:17 +0200 Subject: [PATCH 4/4] Report errors while populating library output --- commands/lib/list.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/commands/lib/list.go b/commands/lib/list.go index 4a76f1efff0..beecf6bbab3 100644 --- a/commands/lib/list.go +++ b/commands/lib/list.go @@ -17,7 +17,6 @@ package lib import ( "context" - "errors" "fmt" "strings" @@ -27,6 +26,7 @@ import ( "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/commands" + "github.com/pkg/errors" ) type installedLib struct { @@ -87,7 +87,10 @@ func LibraryList(ctx context.Context, req *rpc.LibraryListReq) (*rpc.LibraryList if nameFilter != "" && strings.ToLower(lib.Library.Name) != nameFilter { continue } - libtmp := GetOutputLibrary(lib.Library) + libtmp, err := GetOutputLibrary(lib.Library) + if err != nil { + return nil, err + } release := GetOutputRelease(lib.Available) instaledLib = append(instaledLib, &rpc.InstalledLibrary{ Library: libtmp, @@ -125,7 +128,7 @@ func listLibraries(lm *librariesmanager.LibrariesManager, updatable bool, all bo } // GetOutputLibrary FIXMEDOC -func GetOutputLibrary(lib *libraries.Library) *rpc.Library { +func GetOutputLibrary(lib *libraries.Library) (*rpc.Library, error) { insdir := "" if lib.InstallDir != nil { insdir = lib.InstallDir.String() @@ -143,7 +146,11 @@ func GetOutputLibrary(lib *libraries.Library) *rpc.Library { cntplat = lib.ContainerPlatform.String() } - libHeaders, _ := lib.SourceHeaders() + libHeaders, err := lib.SourceHeaders() + if err != nil { + return nil, errors.Errorf("getting library headers: %s", err) + } + return &rpc.Library{ Name: lib.Name, Author: lib.Author, @@ -169,7 +176,7 @@ func GetOutputLibrary(lib *libraries.Library) *rpc.Library { License: lib.License, Examples: lib.Examples.AsStrings(), ProvidesIncludes: libHeaders, - } + }, nil } // GetOutputRelease FIXMEDOC