@@ -120,21 +120,46 @@ func getUserFields(toolID string, platformRelease *cores.PlatformRelease) []*rpc
120
120
return userFields
121
121
}
122
122
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
+
125
150
logrus .Tracef ("Upload %s on %s started" , req .GetSketchPath (), req .GetFqbn ())
126
151
127
152
// TODO: make a generic function to extract sketch from request
128
153
// and remove duplication in commands/compile.go
129
154
sketchPath := paths .New (req .GetSketchPath ())
130
155
sk , err := sketch .New (sketchPath )
131
156
if err != nil && req .GetImportDir () == "" && req .GetImportFile () == "" {
132
- return nil , & cmderrors.CantOpenSketchError {Cause : err }
157
+ return & cmderrors.CantOpenSketchError {Cause : err }
133
158
}
134
159
135
160
pme , pmeRelease , err := instances .GetPackageManagerExplorer (req .GetInstance ())
136
161
if err != nil {
137
- return nil , err
162
+ return err
138
163
}
139
164
defer pmeRelease ()
140
165
@@ -151,6 +176,20 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er
151
176
programmer = sk .GetDefaultProgrammer ()
152
177
}
153
178
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()
154
193
updatedPort , err := runProgramAction (
155
194
pme ,
156
195
sk ,
@@ -168,22 +207,45 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er
168
207
req .GetUserFields (),
169
208
)
170
209
if err != nil {
171
- return nil , err
210
+ return err
172
211
}
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
+ })
177
219
}
178
220
179
221
// 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
+
181
243
logrus .Tracef ("Upload using programmer %s on %s started" , req .GetSketchPath (), req .GetFqbn ())
182
244
183
245
if req .GetProgrammer () == "" {
184
246
return & cmderrors.MissingProgrammerError {}
185
247
}
186
- _ , err := Upload (ctx , & rpc.UploadRequest {
248
+ return s . Upload (& rpc.UploadRequest {
187
249
Instance : req .GetInstance (),
188
250
SketchPath : req .GetSketchPath (),
189
251
ImportFile : req .GetImportFile (),
@@ -194,8 +256,7 @@ func UploadUsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRe
194
256
Verbose : req .GetVerbose (),
195
257
Verify : req .GetVerify (),
196
258
UserFields : req .GetUserFields (),
197
- }, outStream , errStream )
198
- return err
259
+ }, streamAdapter )
199
260
}
200
261
201
262
func runProgramAction (pme * packagemanager.Explorer ,
0 commit comments