Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 12caaa8

Browse files
author
Luca Bianconi
committed
feat: filter boards by fqbn in connected list
1 parent a63aff4 commit 12caaa8

File tree

19 files changed

+187
-99
lines changed

19 files changed

+187
-99
lines changed

‎commands/board/list.go‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,15 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStartError
205205
}
206206
defer release()
207207

208+
var fqbnFilter *cores.FQBN
209+
if f := req.GetFqbn(); f != "" {
210+
var err error
211+
fqbnFilter, err = cores.ParseFQBN(f)
212+
if err != nil {
213+
return nil, nil, &arduino.InvalidFQBNError{Cause: err}
214+
}
215+
}
216+
208217
dm := pme.DiscoveryManager()
209218
discoveryStartErrors = dm.Start()
210219
time.Sleep(time.Duration(req.GetTimeout()) * time.Millisecond)
@@ -222,11 +231,23 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStartError
222231
Port: port.ToRPC(),
223232
MatchingBoards: boards,
224233
}
225-
retVal = append(retVal, b)
234+
235+
if fqbnFilter == nil || hasMatchingBoard(b, fqbnFilter) {
236+
retVal = append(retVal, b)
237+
}
226238
}
227239
return retVal, discoveryStartErrors, nil
228240
}
229241

242+
func hasMatchingBoard(b *rpc.DetectedPort, requestedFqbn *cores.FQBN) bool {
243+
for _, detectedBoard := range b.MatchingBoards {
244+
if detectedBoard.Fqbn == requestedFqbn.String() {
245+
return true
246+
}
247+
}
248+
return false
249+
}
250+
230251
// Watch returns a channel that receives boards connection and disconnection events.
231252
// It also returns a callback function that must be used to stop and dispose the watch.
232253
func Watch(req *rpc.BoardListWatchRequest) (<-chan *rpc.BoardListWatchResponse, func(), error) {

‎internal/cli/arguments/fqbn.go‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,27 @@ 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 to the specified Command
36+
// AddToCommand adds the flags used to set fqbn and the board options to the specified Command
3737
func (f *Fqbn) AddToCommand(cmd *cobra.Command) {
38+
f.addToCommand(cmd, true)
39+
}
40+
41+
// AddToCommand 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.addToCommand(cmd, false)
44+
}
45+
46+
func (f *Fqbn) addToCommand(cmd *cobra.Command, enableBoardOptions bool) bool {
3847
cmd.Flags().StringVarP(&f.fqbn, "fqbn", "b", "", tr("Fully Qualified Board Name, e.g.: arduino:avr:uno"))
3948
cmd.RegisterFlagCompletionFunc("fqbn", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
4049
return GetInstalledBoards(), cobra.ShellCompDirectiveDefault
4150
})
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."))
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
4457
}
4558

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

‎internal/cli/board/list.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"os"
2121
"sort"
2222

23+
"github.com/arduino/arduino-cli/arduino"
2324
"github.com/arduino/arduino-cli/arduino/cores"
2425
"github.com/arduino/arduino-cli/commands/board"
2526
"github.com/arduino/arduino-cli/internal/cli/arguments"
@@ -47,6 +48,7 @@ func initListCommand() *cobra.Command {
4748
}
4849

4950
timeoutArg.AddToCommand(listCommand)
51+
fqbn.AddToCommandWithoutBoardOptions(listCommand)
5052
listCommand.Flags().BoolVarP(&watch, "watch", "w", false, tr("Command keeps running and prints list of connected boards whenever there is a change."))
5153

5254
return listCommand
@@ -66,8 +68,12 @@ func runListCommand(cmd *cobra.Command, args []string) {
6668
ports, discvoeryErrors, err := board.List(&rpc.BoardListRequest{
6769
Instance: inst,
6870
Timeout: timeoutArg.Get().Milliseconds(),
71+
Fqbn: fqbn.String(),
6972
})
7073
if err != nil {
74+
if _, isFqbnError := err.(*arduino.InvalidFQBNError); isFqbnError {
75+
feedback.Fatal(tr(err.Error()), feedback.ErrBadArgument)
76+
}
7177
feedback.Warning(tr("Error detecting boards: %v", err))
7278
}
7379
for _, err := range discvoeryErrors {

‎internal/integrationtest/board/board_test.go‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,39 @@ func TestBoardList(t *testing.T) {
9191
MustBeEmpty()
9292
}
9393

94+
func TestBoardListWithFqbnFilter(t *testing.T) {
95+
if os.Getenv("CI") != "" {
96+
t.Skip("VMs have no serial ports")
97+
}
98+
99+
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
100+
defer env.CleanUp()
101+
102+
_, _, err := cli.Run("core", "update-index")
103+
require.NoError(t, err)
104+
stdout, _, err := cli.Run("board", "list", "-b", "arduino:avr:uno", "--format", "json")
105+
require.NoError(t, err)
106+
// this is a bit of a passpartout test, it actually filters the "bluetooth boards" locally
107+
// but it would succeed even if the filtering wasn't working properly
108+
// TODO: find a way to simulate connected boards or create a unit test which
109+
// mocks or initializes multiple components
110+
requirejson.Parse(t, stdout).
111+
MustBeEmpty()
112+
}
113+
114+
func TestBoardListWithFqbnFilterInvalid(t *testing.T) {
115+
if os.Getenv("CI") != "" {
116+
t.Skip("VMs have no serial ports")
117+
}
118+
119+
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
120+
defer env.CleanUp()
121+
122+
_, stderr, err := cli.Run("board", "list", "-b", "yadayada", "--format", "json")
123+
require.Error(t, err)
124+
requirejson.Query(t, stderr, ".error", `"Invalid FQBN: not an FQBN: yadayada"`)
125+
}
126+
94127
func TestBoardListWithInvalidDiscovery(t *testing.T) {
95128
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
96129
defer env.CleanUp()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /