Skip to content

Commit 5694bb9

Browse files
author
Luca Bianconi
committed
fix: add board options to fqbn filter
1 parent 74441de commit 5694bb9

File tree

5 files changed

+67
-19
lines changed

5 files changed

+67
-19
lines changed

Diff for: arduino/cores/fqbn.go

+23
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,29 @@ func (fqbn *FQBN) String() string {
7676
return res
7777
}
7878

79+
// Match check if the target FQBN corresponds to the receiver one.
80+
// The core parts are checked for exact equality while board options are loosely
81+
// matched: the set of boards options of the target must be fully contained within
82+
// the one of the receiver and their values must be equal.
83+
func (fqbn *FQBN) Match(target *FQBN) bool {
84+
if fqbn.StringWithoutConfig() != target.StringWithoutConfig() {
85+
return false
86+
}
87+
searchedProperties := target.Configs.Clone()
88+
actualConfigs := fqbn.Configs.AsMap()
89+
for neededKey, neededValue := range searchedProperties.AsMap() {
90+
targetValue, hasKey := actualConfigs[neededKey]
91+
if !hasKey {
92+
return false
93+
}
94+
if targetValue != neededValue {
95+
return false
96+
}
97+
}
98+
99+
return true
100+
}
101+
79102
// StringWithoutConfig returns the FQBN without the Config part
80103
func (fqbn *FQBN) StringWithoutConfig() string {
81104
return fqbn.Package + ":" + fqbn.PlatformArch + ":" + fqbn.BoardID

Diff for: arduino/cores/fqbn_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,37 @@ func TestFQBN(t *testing.T) {
121121
"properties.Map{\n \"cpu\": \"atmega\",\n \"speed\": \"1000\",\n \"extra\": \"core=arduino\",\n}",
122122
f.Configs.Dump())
123123
}
124+
125+
func TestMatch(t *testing.T) {
126+
expectedMatches := [][]string{
127+
{"arduino:avr:uno", "arduino:avr:uno"},
128+
{"arduino:avr:uno", "arduino:avr:uno:opt1=1,opt2=2"},
129+
{"arduino:avr:uno:opt1=1", "arduino:avr:uno:opt1=1,opt2=2"},
130+
{"arduino:avr:uno:opt1=1,opt2=2", "arduino:avr:uno:opt1=1,opt2=2"},
131+
{"arduino:avr:uno:opt3=3,opt1=1,opt2=2", "arduino:avr:uno:opt2=2,opt3=3,opt1=1,opt4=4"},
132+
}
133+
134+
for _, pair := range expectedMatches {
135+
a, err := ParseFQBN(pair[0])
136+
require.NoError(t, err)
137+
b, err := ParseFQBN(pair[1])
138+
require.NoError(t, err)
139+
require.True(t, b.Match(a))
140+
}
141+
142+
expectedMismatches := [][]string{
143+
{"arduino:avr:uno", "arduino:avr:due"},
144+
{"arduino:avr:uno", "arduino:avr:due:opt1=1,opt2=2"},
145+
{"arduino:avr:uno:opt1=1", "arduino:avr:uno"},
146+
{"arduino:avr:uno:opt1=1,opt2=", "arduino:avr:uno:opt1=1,opt2=3"},
147+
{"arduino:avr:uno:opt1=1,opt2=2", "arduino:avr:uno:opt2=2"},
148+
}
149+
150+
for _, pair := range expectedMismatches {
151+
a, err := ParseFQBN(pair[0])
152+
require.NoError(t, err)
153+
b, err := ParseFQBN(pair[1])
154+
require.NoError(t, err)
155+
require.False(t, b.Match(a))
156+
}
157+
}

Diff for: commands/board/list.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,13 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStartError
239239
return retVal, discoveryStartErrors, nil
240240
}
241241

242-
func hasMatchingBoard(b *rpc.DetectedPort, requestedFqbn *cores.FQBN) bool {
242+
func hasMatchingBoard(b *rpc.DetectedPort, fqbnFilter *cores.FQBN) bool {
243243
for _, detectedBoard := range b.MatchingBoards {
244-
if detectedBoard.Fqbn == requestedFqbn.String() {
244+
detectedFqbn, err := cores.ParseFQBN(detectedBoard.Fqbn)
245+
if err != nil {
246+
continue
247+
}
248+
if detectedFqbn.Match(fqbnFilter) {
245249
return true
246250
}
247251
}

Diff for: internal/cli/arguments/fqbn.go

+3-16
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,14 @@ type Fqbn struct {
3333
boardOptions []string // List of boards specific options separated by commas. Or can be used multiple times for multiple options.
3434
}
3535

36-
// AddToCommand adds the flags used to set fqbn and the board options to the specified Command
36+
// AddToCommand adds the flags used to set fqbn to the specified Command
3737
func (f *Fqbn) AddToCommand(cmd *cobra.Command) {
38-
f.configureForCommand(cmd, true)
39-
}
40-
41-
// AddToCommandWithoutBoardOptions adds the flags used to set fqbn to the specified Command, board options flag is not provided
42-
func (f *Fqbn) AddToCommandWithoutBoardOptions(cmd *cobra.Command) {
43-
f.configureForCommand(cmd, false)
44-
}
45-
46-
func (f *Fqbn) configureForCommand(cmd *cobra.Command, enableBoardOptions bool) bool {
4738
cmd.Flags().StringVarP(&f.fqbn, "fqbn", "b", "", tr("Fully Qualified Board Name, e.g.: arduino:avr:uno"))
4839
cmd.RegisterFlagCompletionFunc("fqbn", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
4940
return GetInstalledBoards(), cobra.ShellCompDirectiveDefault
5041
})
51-
52-
if enableBoardOptions {
53-
cmd.Flags().StringSliceVar(&f.boardOptions, "board-options", []string{},
54-
tr("List of board options separated by commas. Or can be used multiple times for multiple options."))
55-
}
56-
return false
42+
cmd.Flags().StringSliceVar(&f.boardOptions, "board-options", []string{},
43+
tr("List of board options separated by commas. Or can be used multiple times for multiple options."))
5744
}
5845

5946
// String returns the fqbn with the board options if there are any

Diff for: internal/cli/board/list.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func initListCommand() *cobra.Command {
4949
}
5050

5151
timeoutArg.AddToCommand(listCommand)
52-
fqbn.AddToCommandWithoutBoardOptions(listCommand)
52+
fqbn.AddToCommand(listCommand)
5353
listCommand.Flags().BoolVarP(&watch, "watch", "w", false, tr("Command keeps running and prints list of connected boards whenever there is a change."))
5454

5555
return listCommand

0 commit comments

Comments
 (0)