@@ -17,6 +17,7 @@ package monitor
1717
1818import (
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.\n WARNING: 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