Skip to content

Commit 850f22a

Browse files
authored
regression: allow monitor to not require to specify the board if the port cannot be identified. (#2647)
* Allow default monitor settings if board can't be detected * Improved messages at monitor startup * Moving variable near their usage location * Do not show warnings if the configs are provided by the user * Added a couple of examples in the help
1 parent 590e73b commit 850f22a

File tree

3 files changed

+48
-30
lines changed

3 files changed

+48
-30
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ func CalculateFQBNAndPort(ctx context.Context, portArgs *Port, fqbnArg *Fqbn, in
8080
if portArgs == nil || portArgs.address == "" {
8181
feedback.FatalError(&cmderrors.MissingFQBNError{}, feedback.ErrGeneric)
8282
}
83-
fqbn, port := portArgs.DetectFQBN(ctx, instance, srv)
84-
if fqbn == "" {
83+
fqbn, port, err := portArgs.DetectFQBN(ctx, instance, srv)
84+
if err != nil {
8585
feedback.FatalError(&cmderrors.MissingFQBNError{}, feedback.ErrGeneric)
8686
}
8787
return fqbn, port

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ package arguments
1818
import (
1919
"context"
2020
"errors"
21+
"fmt"
2122
"time"
2223

2324
"github.com/arduino/arduino-cli/commands"
2425
"github.com/arduino/arduino-cli/commands/cmderrors"
2526
f "github.com/arduino/arduino-cli/internal/algorithms"
26-
"github.com/arduino/arduino-cli/internal/cli/feedback"
2727
"github.com/arduino/arduino-cli/internal/i18n"
2828
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2929
"github.com/sirupsen/logrus"
@@ -132,13 +132,13 @@ func (p *Port) GetSearchTimeout() time.Duration {
132132
// DetectFQBN tries to identify the board connected to the port and returns the
133133
// discovered Port object together with the FQBN. If the port does not match
134134
// exactly 1 board,
135-
func (p *Port) DetectFQBN(ctx context.Context, inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) (string, *rpc.Port) {
135+
func (p *Port) DetectFQBN(ctx context.Context, inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) (string, *rpc.Port, error) {
136136
detectedPorts, err := srv.BoardList(ctx, &rpc.BoardListRequest{
137137
Instance: inst,
138138
Timeout: p.timeout.Get().Milliseconds(),
139139
})
140140
if err != nil {
141-
feedback.Fatal(i18n.Tr("Error during FQBN detection: %v", err), feedback.ErrGeneric)
141+
return "", nil, fmt.Errorf("%s: %w", i18n.Tr("Error during board detection"), err)
142142
}
143143
for _, detectedPort := range detectedPorts.GetPorts() {
144144
port := detectedPort.GetPort()
@@ -149,14 +149,14 @@ func (p *Port) DetectFQBN(ctx context.Context, inst *rpc.Instance, srv rpc.Ardui
149149
continue
150150
}
151151
if len(detectedPort.GetMatchingBoards()) > 1 {
152-
feedback.FatalError(&cmderrors.MultipleBoardsDetectedError{Port: port}, feedback.ErrBadArgument)
152+
return "", nil, &cmderrors.MultipleBoardsDetectedError{Port: port}
153153
}
154154
if len(detectedPort.GetMatchingBoards()) == 0 {
155-
feedback.FatalError(&cmderrors.NoBoardsDetectedError{Port: port}, feedback.ErrBadArgument)
155+
return "", nil, &cmderrors.NoBoardsDetectedError{Port: port}
156156
}
157-
return detectedPort.GetMatchingBoards()[0].GetFqbn(), port
157+
return detectedPort.GetMatchingBoards()[0].GetFqbn(), port, nil
158158
}
159-
return "", nil
159+
return "", nil, &cmderrors.NoBoardsDetectedError{Port: &rpc.Port{Address: p.address, Protocol: p.protocol}}
160160
}
161161

162162
// IsPortFlagSet returns true if the port address is provided

Diff for: internal/cli/monitor/monitor.go

+39-21
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import (
1919
"bytes"
2020
"context"
2121
"errors"
22-
"fmt"
2322
"io"
2423
"os"
24+
"slices"
2525
"sort"
2626
"strings"
2727
"time"
@@ -34,6 +34,7 @@ import (
3434
"github.com/arduino/arduino-cli/internal/cli/instance"
3535
"github.com/arduino/arduino-cli/internal/i18n"
3636
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
37+
"github.com/arduino/go-properties-orderedmap"
3738
"github.com/fatih/color"
3839
"github.com/sirupsen/logrus"
3940
"github.com/spf13/cobra"
@@ -58,6 +59,8 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
5859
Long: i18n.Tr("Open a communication port with a board."),
5960
Example: "" +
6061
" " + os.Args[0] + " monitor -p /dev/ttyACM0\n" +
62+
" " + os.Args[0] + " monitor -p /dev/ttyACM0 -b arduino:avr:uno\n" +
63+
" " + os.Args[0] + " monitor -p /dev/ttyACM0 --config 115200\n" +
6164
" " + os.Args[0] + " monitor -p /dev/ttyACM0 --describe",
6265
Run: func(cmd *cobra.Command, args []string) {
6366
sketchPath := ""
@@ -89,13 +92,6 @@ func runMonitorCmd(
8992
quiet = true
9093
}
9194

92-
var (
93-
inst *rpc.Instance
94-
profile *rpc.SketchProfile
95-
fqbn string
96-
defaultPort, defaultProtocol string
97-
)
98-
9995
// Flags takes maximum precedence over sketch.yaml
10096
// If {--port --fqbn --profile} are set we ignore the profile.
10197
// If both {--port --profile} are set we read the fqbn in the following order: profile -> default_fqbn -> discovery
@@ -110,9 +106,9 @@ func runMonitorCmd(
110106
)
111107
}
112108
sketch := resp.GetSketch()
113-
if sketch != nil {
114-
defaultPort, defaultProtocol = sketch.GetDefaultPort(), sketch.GetDefaultProtocol()
115-
}
109+
110+
var inst *rpc.Instance
111+
var profile *rpc.SketchProfile
116112
if fqbnArg.String() == "" {
117113
if profileArg.Get() == "" {
118114
inst, profile = instance.CreateAndInitWithProfile(ctx, srv, sketch.GetDefaultProfile().GetName(), sketchPath)
@@ -123,11 +119,13 @@ func runMonitorCmd(
123119
if inst == nil {
124120
inst = instance.CreateAndInit(ctx, srv)
125121
}
122+
126123
// Priority on how to retrieve the fqbn
127124
// 1. from flag
128125
// 2. from profile
129126
// 3. from default_fqbn specified in the sketch.yaml
130127
// 4. try to detect from the port
128+
var fqbn string
131129
switch {
132130
case fqbnArg.String() != "":
133131
fqbn = fqbnArg.String()
@@ -136,15 +134,19 @@ func runMonitorCmd(
136134
case sketch.GetDefaultFqbn() != "":
137135
fqbn = sketch.GetDefaultFqbn()
138136
default:
139-
fqbn, _ = portArgs.DetectFQBN(ctx, inst, srv)
137+
fqbn, _, _ = portArgs.DetectFQBN(ctx, inst, srv)
140138
}
141139

140+
var defaultPort, defaultProtocol string
141+
if sketch != nil {
142+
defaultPort, defaultProtocol = sketch.GetDefaultPort(), sketch.GetDefaultProtocol()
143+
}
142144
portAddress, portProtocol, err := portArgs.GetPortAddressAndProtocol(ctx, inst, srv, defaultPort, defaultProtocol)
143145
if err != nil {
144146
feedback.FatalError(err, feedback.ErrGeneric)
145147
}
146148

147-
enumerateResp, err := srv.EnumerateMonitorPortSettings(ctx, &rpc.EnumerateMonitorPortSettingsRequest{
149+
defaultSettings, err := srv.EnumerateMonitorPortSettings(ctx, &rpc.EnumerateMonitorPortSettingsRequest{
148150
Instance: inst,
149151
PortProtocol: portProtocol,
150152
Fqbn: fqbn,
@@ -153,14 +155,19 @@ func runMonitorCmd(
153155
feedback.Fatal(i18n.Tr("Error getting port settings details: %s", err), feedback.ErrGeneric)
154156
}
155157
if describe {
156-
settings := make([]*result.MonitorPortSettingDescriptor, len(enumerateResp.GetSettings()))
157-
for i, v := range enumerateResp.GetSettings() {
158+
settings := make([]*result.MonitorPortSettingDescriptor, len(defaultSettings.GetSettings()))
159+
for i, v := range defaultSettings.GetSettings() {
158160
settings[i] = result.NewMonitorPortSettingDescriptor(v)
159161
}
160162
feedback.PrintResult(&detailsResult{Settings: settings})
161163
return
162164
}
163165

166+
actualConfigurationLabels := properties.NewMap()
167+
for _, setting := range defaultSettings.GetSettings() {
168+
actualConfigurationLabels.Set(setting.GetSettingId(), setting.GetValue())
169+
}
170+
164171
configuration := &rpc.MonitorPortConfiguration{}
165172
if len(configs) > 0 {
166173
for _, config := range configs {
@@ -173,7 +180,7 @@ func runMonitorCmd(
173180
}
174181

175182
var setting *rpc.MonitorPortSettingDescriptor
176-
for _, s := range enumerateResp.GetSettings() {
183+
for _, s := range defaultSettings.GetSettings() {
177184
if k == "" {
178185
if contains(s.GetEnumValues(), v) {
179186
setting = s
@@ -196,10 +203,7 @@ func runMonitorCmd(
196203
SettingId: setting.GetSettingId(),
197204
Value: v,
198205
})
199-
if !quiet {
200-
feedback.Print(i18n.Tr("Monitor port settings:"))
201-
feedback.Print(fmt.Sprintf("%s=%s", setting.GetSettingId(), v))
202-
}
206+
actualConfigurationLabels.Set(setting.GetSettingId(), v)
203207
}
204208
}
205209

@@ -229,7 +233,6 @@ func runMonitorCmd(
229233
}
230234
ttyIn = io.TeeReader(ttyIn, ctrlCDetector)
231235
}
232-
233236
monitorServer, portProxy := commands.MonitorServerToReadWriteCloser(ctx, &rpc.MonitorPortOpenRequest{
234237
Instance: inst,
235238
Port: &rpc.Port{Address: portAddress, Protocol: portProtocol},
@@ -238,6 +241,21 @@ func runMonitorCmd(
238241
})
239242
go func() {
240243
if !quiet {
244+
if len(configs) == 0 {
245+
if fqbn != "" {
246+
feedback.Print(i18n.Tr("Using default monitor configuration for board: %s", fqbn))
247+
} else if portProtocol == "serial" {
248+
feedback.Print(i18n.Tr("Using generic monitor configuration.\nWARNING: Your board may require different settings to work!\n"))
249+
}
250+
}
251+
feedback.Print(i18n.Tr("Monitor port settings:"))
252+
keys := actualConfigurationLabels.Keys()
253+
slices.Sort(keys)
254+
for _, k := range keys {
255+
feedback.Printf(" %s=%s", k, actualConfigurationLabels.Get(k))
256+
}
257+
feedback.Print("")
258+
241259
feedback.Print(i18n.Tr("Connecting to %s. Press CTRL-C to exit.", portAddress))
242260
}
243261
if err := srv.Monitor(monitorServer); err != nil {

0 commit comments

Comments
 (0)