Skip to content

Commit fc367b7

Browse files
cmaglieper1234
andauthoredJul 22, 2021
Refactored board details to use pluggable discovery (#1332)
* Cache board identification properties * Board details now shows pluggable discovery identification props * Use new methods in go-properties-orderedmap to calculate subsets * Updated i18n * Added migration docs * Improved tests * Update arduino/cores/board.go Co-authored-by: per1234 <[email protected]> * Update docs/UPGRADING.md Co-authored-by: per1234 <[email protected]>
1 parent f610ed7 commit fc367b7

File tree

10 files changed

+498
-480
lines changed

10 files changed

+498
-480
lines changed
 

‎arduino/cores/board.go

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ import (
2424

2525
// Board represents a board loaded from an installed platform
2626
type Board struct {
27-
BoardID string
28-
Properties *properties.Map `json:"-"`
29-
PlatformRelease *PlatformRelease `json:"-"`
27+
BoardID string
28+
Properties *properties.Map `json:"-"`
29+
PlatformRelease *PlatformRelease `json:"-"`
30+
identificationProperties []*properties.Map
3031
}
3132

3233
// HasUsbID returns true if the board match the usb vid and pid parameters
@@ -140,14 +141,19 @@ func (b *Board) GeneratePropertiesForConfiguration(config string) (*properties.M
140141
return b.GetBuildProperties(fqbn.Configs)
141142
}
142143

144+
// GetIdentificationProperties calculates and returns a list of properties sets
145+
// containing the properties required to identify the board. The returned sets
146+
// must not be changed by the caller.
147+
func (b *Board) GetIdentificationProperties() []*properties.Map {
148+
if b.identificationProperties == nil {
149+
b.identificationProperties = b.Properties.ExtractSubIndexSets("upload_port")
150+
}
151+
return b.identificationProperties
152+
}
153+
143154
// IsBoardMatchingIDProperties returns true if the board match the given
144155
// identification properties
145156
func (b *Board) IsBoardMatchingIDProperties(query *properties.Map) bool {
146-
portIDPropsSet := b.Properties.SubTree("upload_port")
147-
if portIDPropsSet.Size() == 0 {
148-
return false
149-
}
150-
151157
// check checks if the given set of properties p match the "query"
152158
check := func(p *properties.Map) bool {
153159
for k, v := range p.AsMap() {
@@ -159,26 +165,10 @@ func (b *Board) IsBoardMatchingIDProperties(query *properties.Map) bool {
159165
}
160166

161167
// First check the identification properties with sub index "upload_port.N.xxx"
162-
idx := 0
163-
haveIndexedProperties := false
164-
for {
165-
idProps := portIDPropsSet.SubTree(fmt.Sprintf("%d", idx))
166-
idx++
167-
if idProps.Size() > 0 {
168-
haveIndexedProperties = true
169-
if check(idProps) {
170-
return true
171-
}
172-
} else if idx > 1 {
173-
// Always check sub-id 0 and 1 (https://github.com/arduino/arduino-cli/issues/456)
174-
break
168+
for _, idProps := range b.GetIdentificationProperties() {
169+
if check(idProps) {
170+
return true
175171
}
176172
}
177-
178-
// if there are no subindexed then check the whole "upload_port.xxx"
179-
if !haveIndexedProperties {
180-
return check(portIDPropsSet)
181-
}
182-
183173
return false
184174
}

‎cli/board/details.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,13 @@ func (dr detailsResult) String() string {
130130
table.NewCell("✔", color.New(color.FgGreen)))
131131
}
132132

133-
for i, idp := range details.IdentificationPrefs {
134-
if i == 0 {
135-
t.AddRow() // get some space from above
136-
t.AddRow(tr("Identification properties:"), "VID:"+idp.UsbId.Vid+" PID:"+idp.UsbId.Pid)
137-
continue
133+
for _, idp := range details.GetIdentificationProperties() {
134+
t.AddRow() // get some space from above
135+
header := tr("Identification properties:")
136+
for k, v := range idp.GetProperties() {
137+
t.AddRow(header, k+"="+v)
138+
header = ""
138139
}
139-
t.AddRow("", "VID:"+idp.UsbId.Vid+" PID:"+idp.UsbId.Pid)
140140
}
141141

142142
t.AddRow() // get some space from above
@@ -159,14 +159,14 @@ func (dr detailsResult) String() string {
159159

160160
t.AddRow() // get some space from above
161161
for _, tool := range details.ToolsDependencies {
162-
t.AddRow(tr("Required tool:"), tool.Packager+":"+tool.Name, "", tool.Version)
162+
t.AddRow(tr("Required tool:"), tool.Packager+":"+tool.Name, tool.Version)
163163
if showFullDetails {
164164
for _, sys := range tool.Systems {
165-
t.AddRow("", tr("OS:"), "", sys.Host)
166-
t.AddRow("", tr("File:"), "", sys.ArchiveFilename)
167-
t.AddRow("", tr("Size (bytes):"), "", fmt.Sprint(sys.Size))
168-
t.AddRow("", tr("Checksum:"), "", sys.Checksum)
169-
t.AddRow("", "URL:", "", sys.Url)
165+
t.AddRow("", tr("OS:"), sys.Host)
166+
t.AddRow("", tr("File:"), sys.ArchiveFilename)
167+
t.AddRow("", tr("Size (bytes):"), fmt.Sprint(sys.Size))
168+
t.AddRow("", tr("Checksum:"), sys.Checksum)
169+
t.AddRow("", "URL:", sys.Url)
170170
t.AddRow() // get some space from above
171171
}
172172
}

‎commands/board/details.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ func Details(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetai
5050
details.PropertiesId = board.BoardID
5151
details.Official = fqbn.Package == "arduino"
5252
details.Version = board.PlatformRelease.Version.String()
53+
details.IdentificationProperties = []*rpc.BoardIdentificationProperties{}
54+
for _, p := range board.GetIdentificationProperties() {
55+
details.IdentificationProperties = append(details.IdentificationProperties, &rpc.BoardIdentificationProperties{
56+
Properties: p.AsMap(),
57+
})
58+
}
5359

5460
details.DebuggingSupported = boardProperties.ContainsKey("debug.executable") ||
5561
boardPlatform.Properties.ContainsKey("debug.executable") ||
@@ -80,16 +86,6 @@ func Details(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetai
8086
details.Platform.Size = boardPlatform.Resource.Size
8187
}
8288

83-
details.IdentificationPrefs = []*rpc.IdentificationPref{}
84-
vids := board.Properties.SubTree("vid")
85-
pids := board.Properties.SubTree("pid")
86-
for id, vid := range vids.AsMap() {
87-
if pid, ok := pids.GetOk(id); ok {
88-
idPref := rpc.IdentificationPref{UsbId: &rpc.USBID{Vid: vid, Pid: pid}}
89-
details.IdentificationPrefs = append(details.IdentificationPrefs, &idPref)
90-
}
91-
}
92-
9389
details.ConfigOptions = []*rpc.ConfigOption{}
9490
options := board.GetConfigOptions()
9591
for _, option := range options.Keys() {

‎docs/UPGRADING.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,112 @@ removed, in its place:
9393

9494
`Context.Sketch` types has been changed from `Sketch` to `sketch.Sketch`.
9595

96+
### Change in `board details` response (gRPC and JSON output)
97+
98+
The `board details` output WRT board identification properties has changed, before it was:
99+
100+
```
101+
$ arduino-cli board details arduino:samd:mkr1000
102+
Board name: Arduino MKR1000
103+
FQBN: arduino:samd:mkr1000
104+
Board version: 1.8.11
105+
Debugging supported: ✔
106+
107+
Official Arduino board: ✔
108+
109+
Identification properties: VID:0x2341 PID:0x824e
110+
VID:0x2341 PID:0x024e
111+
VID:0x2341 PID:0x804e
112+
VID:0x2341 PID:0x004e
113+
[...]
114+
115+
$ arduino-cli board details arduino:samd:mkr1000 --format json
116+
[...]
117+
"identification_prefs": [
118+
{
119+
"usb_id": {
120+
"vid": "0x2341",
121+
"pid": "0x804e"
122+
}
123+
},
124+
{
125+
"usb_id": {
126+
"vid": "0x2341",
127+
"pid": "0x004e"
128+
}
129+
},
130+
{
131+
"usb_id": {
132+
"vid": "0x2341",
133+
"pid": "0x824e"
134+
}
135+
},
136+
{
137+
"usb_id": {
138+
"vid": "0x2341",
139+
"pid": "0x024e"
140+
}
141+
}
142+
],
143+
[...]
144+
```
145+
146+
now the properties have been renamed from `identification_prefs` to `identification_properties` and they are no longer
147+
specific to USB but they can theoretically be any set of key/values:
148+
149+
```
150+
$ arduino-cli board details arduino:samd:mkr1000
151+
Board name: Arduino MKR1000
152+
FQBN: arduino:samd:mkr1000
153+
Board version: 1.8.11
154+
Debugging supported: ✔
155+
156+
Official Arduino board: ✔
157+
158+
Identification properties: vid=0x2341
159+
pid=0x804e
160+
161+
Identification properties: vid=0x2341
162+
pid=0x004e
163+
164+
Identification properties: vid=0x2341
165+
pid=0x824e
166+
167+
Identification properties: vid=0x2341
168+
pid=0x024e
169+
[...]
170+
171+
$ arduino-cli board details arduino:samd:mkr1000 --format json
172+
[...]
173+
"identification_properties": [
174+
{
175+
"properties": {
176+
"pid": "0x804e",
177+
"vid": "0x2341"
178+
}
179+
},
180+
{
181+
"properties": {
182+
"pid": "0x004e",
183+
"vid": "0x2341"
184+
}
185+
},
186+
{
187+
"properties": {
188+
"pid": "0x824e",
189+
"vid": "0x2341"
190+
}
191+
},
192+
{
193+
"properties": {
194+
"pid": "0x024e",
195+
"vid": "0x2341"
196+
}
197+
}
198+
]
199+
}
200+
```
201+
96202
### Change of behaviour of gRPC `Init` function
97203

98204
Previously the `Init` function was used to both create a new `CoreInstance` and initialize it, so that the internal

‎go.mod

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ require (
1616
github.com/fluxio/iohelpers v0.0.0-20160419043813-3a4dd67a94d2 // indirect
1717
github.com/fluxio/multierror v0.0.0-20160419044231-9c68d39025e5 // indirect
1818
github.com/gofrs/uuid v3.2.0+incompatible
19-
github.com/golang/protobuf v1.5.2
2019
github.com/h2non/filetype v1.0.8 // indirect
2120
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect
2221
github.com/kr/text v0.2.0 // indirect
@@ -38,7 +37,6 @@ require (
3837
github.com/spf13/jwalterweatherman v1.0.0
3938
github.com/spf13/viper v1.6.2
4039
github.com/stretchr/testify v1.6.1
41-
github.com/xanzy/ssh-agent v0.2.1 // indirect
4240
go.bug.st/cleanup v1.0.0
4341
go.bug.st/downloader/v2 v2.1.1
4442
go.bug.st/relaxed-semver v0.0.0-20190922224835-391e10178d18
@@ -48,7 +46,7 @@ require (
4846
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125
4947
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6 // indirect
5048
golang.org/x/text v0.3.6
51-
google.golang.org/genproto v0.0.0-20210504143626-3b2ad6ccc450 // indirect
49+
google.golang.org/genproto v0.0.0-20210504143626-3b2ad6ccc450
5250
google.golang.org/grpc v1.37.0
5351
google.golang.org/protobuf v1.26.0
5452
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect

‎i18n/data/en.po

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ msgstr "Global Flags:"
5454
msgid "Id"
5555
msgstr "Id"
5656

57-
#: cli/board/details.go:136
57+
#: cli/board/details.go:135
5858
msgid "Identification properties:"
5959
msgstr "Identification properties:"
6060

‎i18n/rice-box.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎rpc/cc/arduino/cli/commands/v1/board.pb.go

Lines changed: 331 additions & 393 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎rpc/cc/arduino/cli/commands/v1/board.proto

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,17 @@ message BoardDetailsResponse {
5353
repeated ToolsDependencies tools_dependencies = 10;
5454
// The board's custom configuration options.
5555
repeated ConfigOption config_options = 11;
56-
// Identifying information for the board (e.g., USB VID/PID).
57-
repeated IdentificationPref identification_prefs = 12;
5856
// List of programmers supported by the board
5957
repeated Programmer programmers = 13;
6058
// Set to true if the board supports debugging
6159
bool debugging_supported = 14;
60+
// Identifying information for the board (e.g., USB VID/PID).
61+
repeated BoardIdentificationProperties identification_properties = 15;
6262
}
6363

64-
message IdentificationPref {
65-
// Identifying information for USB-connected boards.
66-
USBID usb_id = 1;
67-
}
68-
69-
message USBID {
70-
// USB vendor ID.
71-
string vid = 1;
72-
// USB product ID.
73-
string pid = 2;
64+
message BoardIdentificationProperties {
65+
// A set of properties that must all be matched to identify the board
66+
map<string, string> properties = 1;
7467
}
7568

7669
message Package {

‎test/test_board.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -353,15 +353,15 @@
353353
]
354354
}
355355
],
356-
"identification_prefs": [
356+
"identification_properties": [
357357
{
358-
"usb_id": {
358+
"properties": {
359359
"vid": "0x2341",
360360
"pid": "0x8057"
361361
}
362362
},
363363
{
364-
"usb_id": {
364+
"properties": {
365365
"vid": "0x2341",
366366
"pid": "0x0057"
367367
}
@@ -483,8 +483,8 @@ def test_board_details(run_command):
483483
assert result["official"] == gold_board_details["official"]
484484
assert result["package"] == gold_board_details["package"]
485485
assert result["platform"] == gold_board_details["platform"]
486-
for usb_id in gold_board_details["identification_prefs"]:
487-
assert usb_id in result["identification_prefs"]
486+
for usb_id in gold_board_details["identification_properties"]:
487+
assert usb_id in result["identification_properties"]
488488
for programmer in gold_board_details["programmers"]:
489489
assert programmer in result["programmers"]
490490

@@ -515,8 +515,8 @@ def test_board_details_old(run_command):
515515
assert result["official"] == gold_board_details["official"]
516516
assert result["package"] == gold_board_details["package"]
517517
assert result["platform"] == gold_board_details["platform"]
518-
for usb_id in gold_board_details["identification_prefs"]:
519-
assert usb_id in result["identification_prefs"]
518+
for usb_id in gold_board_details["identification_properties"]:
519+
assert usb_id in result["identification_properties"]
520520
for programmer in gold_board_details["programmers"]:
521521
assert programmer in result["programmers"]
522522

@@ -537,14 +537,11 @@ def test_board_details_list_programmers_without_flag(run_command):
537537
run_command("core install arduino:samd@1.8.6")
538538
result = run_command("board details -b arduino:samd:nano_33_iot")
539539
assert result.ok
540-
lines = [l.strip() for l in result.stdout.splitlines()]
541-
assert (
542-
"Programmers: Id Name"
543-
in lines
544-
)
545-
assert "edbg Atmel EDBG" in lines
546-
assert "atmel_ice Atmel-ICE" in lines
547-
assert "sam_ice Atmel SAM-ICE" in lines
540+
lines = [l.strip().split() for l in result.stdout.splitlines()]
541+
assert ["Programmers:", "Id", "Name"] in lines
542+
assert ["edbg", "Atmel", "EDBG"] in lines
543+
assert ["atmel_ice", "Atmel-ICE"] in lines
544+
assert ["sam_ice", "Atmel", "SAM-ICE"] in lines
548545

549546

550547
def test_board_details_list_programmers_flag(run_command):

0 commit comments

Comments
 (0)
Please sign in to comment.