@@ -17,6 +17,7 @@ package monitor
17
17
18
18
import (
19
19
"bytes"
20
+ "cmp"
20
21
"context"
21
22
"errors"
22
23
"io"
@@ -163,50 +164,52 @@ func runMonitorCmd(
163
164
return
164
165
}
165
166
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 )
196
179
}
180
+ return s
197
181
}
198
182
}
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 )
207
183
}
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 )
208
193
}
209
194
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
+ }
210
213
ttyIn , ttyOut , err := feedback .InteractiveStreams ()
211
214
if err != nil {
212
215
feedback .FatalError (err , feedback .ErrGeneric )
@@ -233,26 +236,41 @@ func runMonitorCmd(
233
236
}
234
237
ttyIn = io .TeeReader (ttyIn , ctrlCDetector )
235
238
}
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
+ }
236
246
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
+ },
241
253
})
242
254
go func () {
243
255
if ! quiet {
244
- if len ( configs ) == 0 {
256
+ if layeredPortConfig . Size ( ) == 0 {
245
257
if fqbn != "" {
246
258
feedback .Print (i18n .Tr ("Using default monitor configuration for board: %s" , fqbn ))
247
259
} else if portProtocol == "serial" {
248
260
feedback .Print (i18n .Tr ("Using generic monitor configuration.\n WARNING: Your board may require different settings to work!\n " ))
249
261
}
250
262
}
251
263
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 )
256
274
}
257
275
feedback .Print ("" )
258
276
0 commit comments