@@ -120,21 +120,46 @@ func getUserFields(toolID string, platformRelease *cores.PlatformRelease) []*rpc
120120 return userFields
121121}
122122
123- // Upload FIXMEDOC
124- func Upload (ctx context.Context , req * rpc.UploadRequest , outStream io.Writer , errStream io.Writer ) (* rpc.UploadResult , error ) {
123+ // UploadToServerStreams return a server stream that forwards the output and error streams to the provided writers.
124+ // It also returns a function that can be used to retrieve the result of the upload.
125+ func UploadToServerStreams (ctx context.Context , outStream io.Writer , errStream io.Writer ) (rpc.ArduinoCoreService_UploadServer , func () * rpc.UploadResult ) {
126+ var result * rpc.UploadResult
127+ stream := streamResponseToCallback (ctx , func (resp * rpc.UploadResponse ) error {
128+ if errData := resp .GetErrStream (); len (errData ) > 0 {
129+ _ , err := errStream .Write (errData )
130+ return err
131+ }
132+ if outData := resp .GetOutStream (); len (outData ) > 0 {
133+ _ , err := outStream .Write (outData )
134+ return err
135+ }
136+ if res := resp .GetResult (); res != nil {
137+ result = res
138+ }
139+ return nil
140+ })
141+ return stream , func () * rpc.UploadResult {
142+ return result
143+ }
144+ }
145+
146+ // Upload performs the upload of a sketch to a board.
147+ func (s * arduinoCoreServerImpl ) Upload (req * rpc.UploadRequest , stream rpc.ArduinoCoreService_UploadServer ) error {
148+ syncSend := NewSynchronizedSend (stream .Send )
149+
125150 logrus .Tracef ("Upload %s on %s started" , req .GetSketchPath (), req .GetFqbn ())
126151
127152 // TODO: make a generic function to extract sketch from request
128153 // and remove duplication in commands/compile.go
129154 sketchPath := paths .New (req .GetSketchPath ())
130155 sk , err := sketch .New (sketchPath )
131156 if err != nil && req .GetImportDir () == "" && req .GetImportFile () == "" {
132- return nil , & cmderrors.CantOpenSketchError {Cause : err }
157+ return & cmderrors.CantOpenSketchError {Cause : err }
133158 }
134159
135160 pme , pmeRelease , err := instances .GetPackageManagerExplorer (req .GetInstance ())
136161 if err != nil {
137- return nil , err
162+ return err
138163 }
139164 defer pmeRelease ()
140165
@@ -151,6 +176,20 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er
151176 programmer = sk .GetDefaultProgrammer ()
152177 }
153178
179+ outStream := feedStreamTo (func (data []byte ) {
180+ syncSend .Send (& rpc.UploadResponse {
181+ Message : & rpc.UploadResponse_OutStream {OutStream : data },
182+ })
183+ })
184+ defer outStream .Close ()
185+ errStream := feedStreamTo (func (data []byte ) {
186+ syncSend .Send (& rpc.UploadResponse {
187+ Message : & rpc.UploadResponse_ErrStream {ErrStream : data },
188+ })
189+ })
190+ defer errStream .Close ()
191+ // TODO: inject context
192+ // ctx := stream.Context()
154193 updatedPort , err := runProgramAction (
155194 pme ,
156195 sk ,
@@ -168,22 +207,45 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er
168207 req .GetUserFields (),
169208 )
170209 if err != nil {
171- return nil , err
210+ return err
172211 }
173-
174- return & rpc.UploadResult {
175- UpdatedUploadPort : updatedPort ,
176- }, nil
212+ return syncSend .Send (& rpc.UploadResponse {
213+ Message : & rpc.UploadResponse_Result {
214+ Result : & rpc.UploadResult {
215+ UpdatedUploadPort : updatedPort ,
216+ },
217+ },
218+ })
177219}
178220
179221// UploadUsingProgrammer FIXMEDOC
180- func UploadUsingProgrammer (ctx context.Context , req * rpc.UploadUsingProgrammerRequest , outStream io.Writer , errStream io.Writer ) error {
222+ func (s * arduinoCoreServerImpl ) UploadUsingProgrammer (req * rpc.UploadUsingProgrammerRequest , stream rpc.ArduinoCoreService_UploadUsingProgrammerServer ) error {
223+ syncSend := NewSynchronizedSend (stream .Send )
224+ streamAdapter := streamResponseToCallback (stream .Context (), func (resp * rpc.UploadResponse ) error {
225+ if errData := resp .GetErrStream (); len (errData ) > 0 {
226+ syncSend .Send (& rpc.UploadUsingProgrammerResponse {
227+ Message : & rpc.UploadUsingProgrammerResponse_ErrStream {
228+ ErrStream : errData ,
229+ },
230+ })
231+ }
232+ if outData := resp .GetOutStream (); len (outData ) > 0 {
233+ syncSend .Send (& rpc.UploadUsingProgrammerResponse {
234+ Message : & rpc.UploadUsingProgrammerResponse_OutStream {
235+ OutStream : outData ,
236+ },
237+ })
238+ }
239+ // resp.GetResult() is ignored
240+ return nil
241+ })
242+
181243 logrus .Tracef ("Upload using programmer %s on %s started" , req .GetSketchPath (), req .GetFqbn ())
182244
183245 if req .GetProgrammer () == "" {
184246 return & cmderrors.MissingProgrammerError {}
185247 }
186- _ , err := Upload (ctx , & rpc.UploadRequest {
248+ return s . Upload (& rpc.UploadRequest {
187249 Instance : req .GetInstance (),
188250 SketchPath : req .GetSketchPath (),
189251 ImportFile : req .GetImportFile (),
@@ -194,8 +256,7 @@ func UploadUsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRe
194256 Verbose : req .GetVerbose (),
195257 Verify : req .GetVerify (),
196258 UserFields : req .GetUserFields (),
197- }, outStream , errStream )
198- return err
259+ }, streamAdapter )
199260}
200261
201262func runProgramAction (pme * packagemanager.Explorer ,
0 commit comments