Skip to content

Commit 59af89d

Browse files
committed
Allow port configuration from sketch profile
1 parent e22b2a1 commit 59af89d

File tree

1 file changed

+65
-47
lines changed

1 file changed

+65
-47
lines changed

internal/cli/monitor/monitor.go

+65-47
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package monitor
1717

1818
import (
1919
"bytes"
20+
"cmp"
2021
"context"
2122
"errors"
2223
"io"
@@ -163,50 +164,52 @@ func runMonitorCmd(
163164
return
164165
}
165166

166-
actualConfigurationLabels := properties.NewMap()
167-
for _, setting := range defaultSettings.GetSettings() {
168-
actualConfigurationLabels.Set(setting.GetSettingId(), setting.GetValue())
169-
}
170-
171-
configuration := &rpc.MonitorPortConfiguration{}
172-
if len(configs) > 0 {
173-
for _, config := range configs {
174-
split := strings.SplitN(config, "=", 2)
175-
k := ""
176-
v := config
177-
if len(split) == 2 {
178-
k = split[0]
179-
v = split[1]
180-
}
181-
182-
var setting *rpc.MonitorPortSettingDescriptor
183-
for _, s := range defaultSettings.GetSettings() {
184-
if k == "" {
185-
if contains(s.GetEnumValues(), v) {
186-
setting = s
187-
break
188-
}
189-
} else {
190-
if strings.EqualFold(s.GetSettingId(), k) {
191-
if !contains(s.GetEnumValues(), v) {
192-
feedback.Fatal(i18n.Tr("invalid port configuration value for %s: %s", k, v), feedback.ErrBadArgument)
193-
}
194-
setting = s
195-
break
167+
// This utility finds the settings descriptor from key/value or only from key.
168+
// It fails fatal if the key or value are invalid.
169+
searchSettingDescriptor := func(k, v string) *rpc.MonitorPortSettingDescriptor {
170+
for _, s := range defaultSettings.GetSettings() {
171+
if k == "" {
172+
if contains(s.GetEnumValues(), v) {
173+
return s
174+
}
175+
} else {
176+
if strings.EqualFold(s.GetSettingId(), k) {
177+
if !contains(s.GetEnumValues(), v) {
178+
feedback.Fatal(i18n.Tr("invalid port configuration value for %s: %s", k, v), feedback.ErrBadArgument)
196179
}
180+
return s
197181
}
198182
}
199-
if setting == nil {
200-
feedback.Fatal(i18n.Tr("invalid port configuration: %s", config), feedback.ErrBadArgument)
201-
}
202-
configuration.Settings = append(configuration.GetSettings(), &rpc.MonitorPortSetting{
203-
SettingId: setting.GetSettingId(),
204-
Value: v,
205-
})
206-
actualConfigurationLabels.Set(setting.GetSettingId(), v)
207183
}
184+
feedback.Fatal(i18n.Tr("invalid port configuration: %s=%s", k, v), feedback.ErrBadArgument)
185+
return nil
186+
}
187+
188+
// Build configuration by layering
189+
layeredPortConfig := properties.NewMap()
190+
setConfig := func(k, v string) {
191+
settingDesc := searchSettingDescriptor(k, v)
192+
layeredPortConfig.Set(settingDesc.GetSettingId(), v)
208193
}
209194

195+
// Layer 1: apply configuration from sketch profile...
196+
profileConfig := profile.GetPortConfig()
197+
if profileConfig == nil {
198+
// ...or from sketch default...
199+
profileConfig = sketch.GetDefaultPortConfig()
200+
}
201+
for _, setting := range profileConfig.GetSettings() {
202+
setConfig(setting.SettingId, setting.Value)
203+
}
204+
205+
// Layer 2: apply configuration from command line...
206+
for _, config := range configs {
207+
if split := strings.SplitN(config, "=", 2); len(split) == 2 {
208+
setConfig(split[0], split[1])
209+
} else {
210+
setConfig("", config)
211+
}
212+
}
210213
ttyIn, ttyOut, err := feedback.InteractiveStreams()
211214
if err != nil {
212215
feedback.FatalError(err, feedback.ErrGeneric)
@@ -233,26 +236,41 @@ func runMonitorCmd(
233236
}
234237
ttyIn = io.TeeReader(ttyIn, ctrlCDetector)
235238
}
239+
var portConfiguration []*rpc.MonitorPortSetting
240+
for k, v := range layeredPortConfig.AsMap() {
241+
portConfiguration = append(portConfiguration, &rpc.MonitorPortSetting{
242+
SettingId: k,
243+
Value: v,
244+
})
245+
}
236246
monitorServer, portProxy := commands.MonitorServerToReadWriteCloser(ctx, &rpc.MonitorPortOpenRequest{
237-
Instance: inst,
238-
Port: &rpc.Port{Address: portAddress, Protocol: portProtocol},
239-
Fqbn: fqbn,
240-
PortConfiguration: configuration,
247+
Instance: inst,
248+
Port: &rpc.Port{Address: portAddress, Protocol: portProtocol},
249+
Fqbn: fqbn,
250+
PortConfiguration: &rpc.MonitorPortConfiguration{
251+
Settings: portConfiguration,
252+
},
241253
})
242254
go func() {
243255
if !quiet {
244-
if len(configs) == 0 {
256+
if layeredPortConfig.Size() == 0 {
245257
if fqbn != "" {
246258
feedback.Print(i18n.Tr("Using default monitor configuration for board: %s", fqbn))
247259
} else if portProtocol == "serial" {
248260
feedback.Print(i18n.Tr("Using generic monitor configuration.\nWARNING: Your board may require different settings to work!\n"))
249261
}
250262
}
251263
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))
264+
slices.SortFunc(defaultSettings.GetSettings(), func(a, b *rpc.MonitorPortSettingDescriptor) int {
265+
return cmp.Compare(a.GetSettingId(), b.GetSettingId())
266+
})
267+
for _, defaultSetting := range defaultSettings.GetSettings() {
268+
k := defaultSetting.GetSettingId()
269+
v, ok := layeredPortConfig.GetOk(k)
270+
if !ok {
271+
v = defaultSetting.GetValue()
272+
}
273+
feedback.Printf(" %s=%s", k, v)
256274
}
257275
feedback.Print("")
258276

0 commit comments

Comments
 (0)