Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 743c3e9

Browse files
committedSep 29, 2020
lib list command now only shows compatible libraries when specifying fqbn
1 parent 27316e3 commit 743c3e9

File tree

6 files changed

+203
-90
lines changed

6 files changed

+203
-90
lines changed
 

‎arduino/libraries/libraries.go

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ type Library struct {
7575
Examples paths.PathList
7676
declaredHeaders []string
7777
sourceHeaders []string
78+
CompatibleWith map[string]bool
7879
}
7980

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

‎cli/lib/list.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,16 @@ func runListCommand(cmd *cobra.Command, args []string) {
7676
os.Exit(errorcodes.ErrGeneric)
7777
}
7878

79-
libs := res.GetInstalledLibrary()
79+
libs := []*rpc.InstalledLibrary{}
80+
if listFlags.fqbn == "" {
81+
libs = res.GetInstalledLibrary()
82+
} else {
83+
for _, lib := range res.GetInstalledLibrary() {
84+
if lib.Library.CompatibleWith[listFlags.fqbn] {
85+
libs = append(libs, lib)
86+
}
87+
}
88+
}
8089

8190
// To uniform the output to other commands, when there are no result
8291
// print out an empty slice.
@@ -139,7 +148,6 @@ func (ir installedResult) String() string {
139148
} else if len(sentence) > 40 {
140149
sentence = sentence[:37] + "..."
141150
}
142-
143151
t.AddRow(name, lib.Version, available, location, sentence)
144152
}
145153
}

‎commands/lib/list.go

+51-40
Original file line numberDiff line numberDiff line change
@@ -50,57 +50,67 @@ 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+
compatible := false
79+
for _, arch := range lib.Library.Architectures {
80+
compatible = (arch == fqbn.PlatformArch || arch == "*")
81+
if compatible {
82+
break
83+
}
84+
}
85+
lib.Library.CompatibleWith = map[string]bool{
86+
f: compatible,
8387
}
88+
89+
filteredRes[lib.Library.Name] = lib
8490
}
8591

86-
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-
})
92+
res = []*installedLib{}
93+
for _, lib := range filteredRes {
94+
res = append(res, lib)
9995
}
96+
}
10097

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

106116
// listLibraries returns the list of installed libraries. If updatable is true it
@@ -171,6 +181,7 @@ func GetOutputLibrary(lib *libraries.Library) (*rpc.Library, error) {
171181
License: lib.License,
172182
Examples: lib.Examples.AsStrings(),
173183
ProvidesIncludes: lib.DeclaredHeaders(),
184+
CompatibleWith: lib.CompatibleWith,
174185
}, nil
175186
}
176187

‎rpc/commands/lib.pb.go

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

‎rpc/commands/lib.proto

+3-1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ 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+
// Map of FQBNs that specifies if library is compatible with this library
275+
map<string, bool> compatible_with = 28;
274276
}
275277

276278
enum LibraryLayout {
@@ -287,7 +289,7 @@ enum LibraryLocation {
287289
user = 1;
288290
// In the `libraries` subdirectory of a platform.
289291
platform_builtin = 2;
290-
// When `LibraryLocation` is used in a context where a board is specified,
292+
// When `LibraryLocation` is used in a context where a board is specified,
291293
// this indicates the library is in the `libraries` subdirectory of a
292294
// platform referenced by the board's platform.
293295
referenced_platform_builtin = 3;

‎test/test_lib.py

+70
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,76 @@ def test_list(run_command):
7070
assert "Arduino_APDS9960.h" == data[0]["library"]["provides_includes"][0]
7171

7272

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

0 commit comments

Comments
 (0)
Please sign in to comment.