Skip to content

Commit 7651a14

Browse files
committed
Compatibility is now shown when calling lib list with fqbn
1 parent 8c2f90a commit 7651a14

File tree

6 files changed

+180
-46
lines changed

6 files changed

+180
-46
lines changed

arduino/libraries/libraries.go

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type Library struct {
7474
Properties *properties.Map
7575
Examples paths.PathList
7676
sourceHeaders []string
77+
Compatible bool
7778
}
7879

7980
func (library *Library) String() string {

cli/lib/list.go

+26-4
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,22 @@ func (ir installedResult) String() string {
108108
})
109109

110110
t := table.New()
111-
t.SetHeader("Name", "Installed", "Available", "Location", "Description")
111+
header := []interface{}{}
112+
if listFlags.fqbn == "" {
113+
header = []interface{}{
114+
"Name", "Installed", "Available", "Location", "Description",
115+
}
116+
t.SetColumnWidthMode(4, table.Average)
117+
} else {
118+
header = []interface{}{
119+
"Name", "Installed", "Available", "Compatible", "Location", "Description",
120+
}
121+
t.SetColumnWidthMode(3, table.Average)
122+
t.SetColumnWidthMode(5, table.Average)
123+
}
112124
t.SetColumnWidthMode(1, table.Average)
113125
t.SetColumnWidthMode(2, table.Average)
114-
t.SetColumnWidthMode(4, table.Average)
126+
t.SetHeader(header...)
115127

116128
lastName := ""
117129
for _, libMeta := range ir.installedLibs {
@@ -139,8 +151,18 @@ func (ir installedResult) String() string {
139151
} else if len(sentence) > 40 {
140152
sentence = sentence[:37] + "..."
141153
}
142-
143-
t.AddRow(name, lib.Version, available, location, sentence)
154+
if listFlags.fqbn == "" {
155+
t.AddRow(name, lib.Version, available, location, sentence)
156+
} else {
157+
var compatible string
158+
if lib.Compatible {
159+
compatible = "✓"
160+
} else {
161+
compatible = "✕"
162+
}
163+
164+
t.AddRow(name, lib.Version, available, compatible, location, sentence)
165+
}
144166
}
145167
}
146168

commands/lib/list.go

+52-39
Original file line numberDiff line numberDiff line change
@@ -50,57 +50,69 @@ func LibraryList(ctx context.Context, req *rpc.LibraryListReq) (*rpc.LibraryList
5050

5151
instaledLib := []*rpc.InstalledLibrary{}
5252
res := listLibraries(lm, req.GetUpdatable(), req.GetAll())
53-
if len(res) > 0 {
54-
if f := req.GetFqbn(); f != "" {
55-
fqbn, err := cores.ParseFQBN(req.GetFqbn())
56-
if err != nil {
57-
return nil, fmt.Errorf("parsing fqbn: %s", err)
58-
}
59-
_, boardPlatform, _, _, refBoardPlatform, err := pm.ResolveFQBN(fqbn)
60-
if err != nil {
61-
return nil, fmt.Errorf("loading board data: %s", err)
62-
}
53+
if f := req.GetFqbn(); f != "" {
54+
fqbn, err := cores.ParseFQBN(req.GetFqbn())
55+
if err != nil {
56+
return nil, fmt.Errorf("parsing fqbn: %s", err)
57+
}
58+
_, boardPlatform, _, _, refBoardPlatform, err := pm.ResolveFQBN(fqbn)
59+
if err != nil {
60+
return nil, fmt.Errorf("loading board data: %s", err)
61+
}
6362

64-
filteredRes := map[string]*installedLib{}
65-
for _, lib := range res {
66-
if cp := lib.Library.ContainerPlatform; cp != nil {
67-
if cp != boardPlatform && cp != refBoardPlatform {
68-
// Filter all libraries from extraneous platforms
69-
continue
70-
}
63+
filteredRes := map[string]*installedLib{}
64+
for _, lib := range res {
65+
if cp := lib.Library.ContainerPlatform; cp != nil {
66+
if cp != boardPlatform && cp != refBoardPlatform {
67+
// Filter all libraries from extraneous platforms
68+
continue
7169
}
72-
if latest, has := filteredRes[lib.Library.Name]; has {
73-
if latest.Library.LocationPriorityFor(boardPlatform, refBoardPlatform) >= lib.Library.LocationPriorityFor(boardPlatform, refBoardPlatform) {
74-
continue
75-
}
70+
}
71+
if latest, has := filteredRes[lib.Library.Name]; has {
72+
if latest.Library.LocationPriorityFor(boardPlatform, refBoardPlatform) >= lib.Library.LocationPriorityFor(boardPlatform, refBoardPlatform) {
73+
continue
7674
}
77-
filteredRes[lib.Library.Name] = lib
7875
}
7976

80-
res = []*installedLib{}
81-
for _, lib := range filteredRes {
82-
res = append(res, lib)
77+
// Check if library is compatible with board specified by FBQN
78+
lib.Library.Compatible = false
79+
for _, arch := range lib.Library.Architectures {
80+
if arch == fqbn.PlatformArch || arch == "*" {
81+
lib.Library.Compatible = true
82+
break
83+
}
8384
}
85+
86+
filteredRes[lib.Library.Name] = lib
8487
}
8588

89+
res = []*installedLib{}
90+
for _, lib := range filteredRes {
91+
res = append(res, lib)
92+
}
93+
} else {
94+
// If no FQBN has been specified mark every library as compatible
8695
for _, lib := range res {
87-
if nameFilter != "" && strings.ToLower(lib.Library.Name) != nameFilter {
88-
continue
89-
}
90-
libtmp, err := GetOutputLibrary(lib.Library)
91-
if err != nil {
92-
return nil, err
93-
}
94-
release := GetOutputRelease(lib.Available)
95-
instaledLib = append(instaledLib, &rpc.InstalledLibrary{
96-
Library: libtmp,
97-
Release: release,
98-
})
96+
lib.Library.Compatible = true
9997
}
98+
}
10099

101-
return &rpc.LibraryListResp{InstalledLibrary: instaledLib}, nil
100+
for _, lib := range res {
101+
if nameFilter != "" && strings.ToLower(lib.Library.Name) != nameFilter {
102+
continue
103+
}
104+
libtmp, err := GetOutputLibrary(lib.Library)
105+
if err != nil {
106+
return nil, err
107+
}
108+
release := GetOutputRelease(lib.Available)
109+
instaledLib = append(instaledLib, &rpc.InstalledLibrary{
110+
Library: libtmp,
111+
Release: release,
112+
})
102113
}
103-
return &rpc.LibraryListResp{}, nil
114+
115+
return &rpc.LibraryListResp{InstalledLibrary: instaledLib}, nil
104116
}
105117

106118
// listLibraries returns the list of installed libraries. If updatable is true it
@@ -176,6 +188,7 @@ func GetOutputLibrary(lib *libraries.Library) (*rpc.Library, error) {
176188
License: lib.License,
177189
Examples: lib.Examples.AsStrings(),
178190
ProvidesIncludes: libHeaders,
191+
Compatible: lib.Compatible,
179192
}, nil
180193
}
181194

rpc/commands/lib.pb.go

+14-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rpc/commands/lib.proto

+4-1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ message Library {
271271
// Value of the `includes` field in library.properties or, if missing, the list of
272272
// include files available on the library source root directory.
273273
repeated string provides_includes = 27;
274+
// True in case this library is compatible with the specified board.
275+
// Always true if no board is specified
276+
bool compatible = 28;
274277
}
275278

276279
enum LibraryLayout {
@@ -287,7 +290,7 @@ enum LibraryLocation {
287290
user = 1;
288291
// In the `libraries` subdirectory of a platform.
289292
platform_builtin = 2;
290-
// When `LibraryLocation` is used in a context where a board is specified,
293+
// When `LibraryLocation` is used in a context where a board is specified,
291294
// this indicates the library is in the `libraries` subdirectory of a
292295
// platform referenced by the board's platform.
293296
referenced_platform_builtin = 3;

test/test_lib.py

+83
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,89 @@ def test_list(run_command):
7373
assert "Braccio.h" == data[0]["library"]["provides_includes"][0]
7474

7575

76+
def test_list_exit_code(run_command):
77+
# Init the environment explicitly
78+
assert run_command("core update-index")
79+
80+
assert run_command("core list")
81+
82+
# Verifies lib list doesn't fail when platform is not specified
83+
result = run_command("lib list")
84+
assert result.ok
85+
assert result.stderr.strip() == ""
86+
87+
# Verify lib list command fails because specified platform is not installed
88+
result = run_command("lib list -b arduino:samd:mkr1000")
89+
assert result.failed
90+
assert (
91+
result.stderr.strip() == "Error listing Libraries: loading board data: platform arduino:samd is not installed"
92+
)
93+
94+
assert run_command('lib install "AllThingsTalk LoRaWAN SDK"')
95+
96+
# Verifies lib list command keeps failing
97+
result = run_command("lib list -b arduino:samd:mkr1000")
98+
assert result.failed
99+
assert (
100+
result.stderr.strip() == "Error listing Libraries: loading board data: platform arduino:samd is not installed"
101+
)
102+
103+
assert run_command("core install arduino:samd")
104+
105+
# Verifies lib list command now works since platform has been installed
106+
result = run_command("lib list -b arduino:samd:mkr1000")
107+
assert result.ok
108+
assert result.stderr.strip() == ""
109+
110+
111+
def test_list_with_fqbn(run_command):
112+
# Init the environment explicitly
113+
assert run_command("core update-index")
114+
115+
# Install core
116+
assert run_command("core install arduino:samd")
117+
118+
# Install some library
119+
assert run_command("lib install ArduinoJson")
120+
assert run_command("lib install wm8978-esp32")
121+
122+
# Look at the plain text output
123+
result = run_command("lib list -b arduino:samd:mkr1000")
124+
assert result.ok
125+
assert "" == result.stderr
126+
lines = result.stdout.strip().splitlines()
127+
assert 3 == len(lines)
128+
129+
# Verifies library is compatible
130+
toks = [t.strip() for t in lines[1].split(maxsplit=5)]
131+
assert 6 == len(toks)
132+
assert "ArduinoJson" == toks[0]
133+
assert "✓" == toks[3]
134+
135+
# Verifies library is not compatible
136+
toks = [t.strip() for t in lines[2].split(maxsplit=5)]
137+
assert 6 == len(toks)
138+
assert "wm8978-esp32" == toks[0]
139+
assert "✕" == toks[3]
140+
141+
# Look at the JSON output
142+
result = run_command("lib list -b arduino:samd:mkr1000 --format json")
143+
assert result.ok
144+
assert "" == result.stderr
145+
data = json.loads(result.stdout)
146+
assert 2 == len(data)
147+
148+
data = sorted(data, key=lambda lib: str.lower(lib["library"]["name"]))
149+
150+
# Verifies library is compatible
151+
assert data[0]["library"]["name"] == "ArduinoJson"
152+
assert data[0]["library"]["compatible"]
153+
154+
# Verifies library is not compatible
155+
assert data[1]["library"]["name"] == "wm8978-esp32"
156+
assert "compatible" not in data[1]["library"]
157+
158+
76159
def test_install(run_command):
77160
libs = ['"AzureIoTProtocol_MQTT"', '"CMMC MQTT Connector"', '"WiFiNINA"']
78161
# Should be safe to run install multiple times

0 commit comments

Comments
 (0)