@@ -19,7 +19,6 @@ import (
1919 "context"
2020 "fmt"
2121 "io"
22- "net/url"
2322 "path/filepath"
2423 "strings"
2524
@@ -37,6 +36,22 @@ import (
3736 "github.com/sirupsen/logrus"
3837)
3938
39+ // getToolId returns the ID of the tool that supports the action and protocol combination by searching in props.
40+ // Returns error if tool cannot be found.
41+ func getToolId (props * properties.Map , action , protocol string ) (string , error ) {
42+ toolProperty := fmt .Sprintf ("%s.tool.%s" , action , protocol )
43+ defaultToolProperty := fmt .Sprintf ("%s.tool.default" , action )
44+
45+ if t , ok := props .GetOk (toolProperty ); ok {
46+ return t , nil
47+ } else if t , ok := props .GetOk (defaultToolProperty ); ok {
48+ // Fallback for platform that don't support the specified protocol for specified action:
49+ // https://github.com/arduino/tooling-rfcs/blob/main/RFCs/0002-pluggable-discovery.md#support-for-default-fallback-allows-upload-without-a-port
50+ return t , nil
51+ }
52+ return "" , fmt .Errorf ("cannot find tool: undefined '%s' property" , toolProperty )
53+ }
54+
4055// Upload FIXMEDOC
4156func Upload (ctx context.Context , req * rpc.UploadRequest , outStream io.Writer , errStream io.Writer ) (* rpc.UploadResponse , error ) {
4257 logrus .Tracef ("Upload %s on %s started" , req .GetSketchPath (), req .GetFqbn ())
@@ -95,7 +110,7 @@ func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest,
95110
96111func runProgramAction (pm * packagemanager.PackageManager ,
97112 sk * sketch.Sketch ,
98- importFile , importDir , fqbnIn , port string ,
113+ importFile , importDir , fqbnIn string , port * rpc. Port ,
99114 programmerID string ,
100115 verbose , verify , burnBootloader bool ,
101116 outStream , errStream io.Writer ,
@@ -105,16 +120,6 @@ func runProgramAction(pm *packagemanager.PackageManager,
105120 return fmt .Errorf ("no programmer specified for burning bootloader" )
106121 }
107122
108- // FIXME: make a specification on how a port is specified via command line
109- if port == "" && sk != nil && sk .Metadata != nil {
110- deviceURI , err := url .Parse (sk .Metadata .CPU .Port )
111- if err != nil {
112- return fmt .Errorf ("invalid Device URL format: %s" , err )
113- }
114- if deviceURI .Scheme == "serial" {
115- port = deviceURI .Host + deviceURI .Path
116- }
117- }
118123 logrus .WithField ("port" , port ).Tracef ("Upload port" )
119124
120125 if fqbnIn == "" && sk != nil && sk .Metadata != nil {
@@ -154,28 +159,23 @@ func runProgramAction(pm *packagemanager.PackageManager,
154159 }
155160
156161 // Determine upload tool
157- var uploadToolID string
158- {
159- toolProperty := "upload.tool"
160- if burnBootloader {
161- toolProperty = "bootloader.tool"
162- } else if programmer != nil {
163- toolProperty = "program.tool"
164- }
165-
166- // create a temporary configuration only for the selection of upload tool
167- props := properties .NewMap ()
168- props .Merge (boardPlatform .Properties )
169- props .Merge (boardPlatform .RuntimeProperties ())
170- props .Merge (boardProperties )
171- if programmer != nil {
172- props .Merge (programmer .Properties )
173- }
174- if t , ok := props .GetOk (toolProperty ); ok {
175- uploadToolID = t
176- } else {
177- return fmt .Errorf ("cannot get programmer tool: undefined '%s' property" , toolProperty )
178- }
162+ // create a temporary configuration only for the selection of upload tool
163+ props := properties .NewMap ()
164+ props .Merge (boardPlatform .Properties )
165+ props .Merge (boardPlatform .RuntimeProperties ())
166+ props .Merge (boardProperties )
167+ if programmer != nil {
168+ props .Merge (programmer .Properties )
169+ }
170+ action := "upload"
171+ if burnBootloader {
172+ action = "bootloader"
173+ } else if programmer != nil {
174+ action = "program"
175+ }
176+ uploadToolID , err := getToolId (props , action , port .Protocol )
177+ if err != nil {
178+ return err
179179 }
180180
181181 var uploadToolPlatform * cores.PlatformRelease
@@ -299,7 +299,7 @@ func runProgramAction(pm *packagemanager.PackageManager,
299299 wait := false
300300 portToTouch := ""
301301 if touch {
302- portToTouch = port
302+ portToTouch = port . Address
303303 // Waits for upload port only if a 1200bps touch is done
304304 wait = uploadProperties .GetBoolean ("upload.wait_for_upload_port" )
305305 }
@@ -349,18 +349,18 @@ func runProgramAction(pm *packagemanager.PackageManager,
349349 outStream .Write ([]byte (fmt .Sprintln ()))
350350 } else {
351351 if newPort != "" {
352- actualPort = newPort
352+ actualPort . Address = newPort
353353 }
354354 }
355355 }
356356
357- if actualPort != "" {
357+ if actualPort . Address != "" {
358358 // Set serial port property
359- uploadProperties .Set ("serial.port" , actualPort )
360- if strings . HasPrefix ( actualPort , "/dev/" ) {
361- uploadProperties . Set ( " serial.port.file" , actualPort [ 5 :])
362- } else {
363- uploadProperties .Set ("serial.port.file" , actualPort )
359+ uploadProperties .Set ("serial.port" , actualPort . Address )
360+ if actualPort . Protocol == "serial" {
361+ // This must be done only for serial ports
362+ portFile := strings . TrimPrefix ( actualPort . Address , "/dev/" )
363+ uploadProperties .Set ("serial.port.file" , portFile )
364364 }
365365 }
366366
0 commit comments