Skip to content

Commit 827eb6e

Browse files
committed
Inlining methods in ArduinoCoreServiceImpl (part 9: Compile)
1 parent c048f80 commit 827eb6e

File tree

4 files changed

+87
-73
lines changed

4 files changed

+87
-73
lines changed

Diff for: commands/service.go

-35
Original file line numberDiff line numberDiff line change
@@ -64,41 +64,6 @@ func (s *arduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.
6464
return SetSketchDefaults(ctx, req)
6565
}
6666

67-
// Compile FIXMEDOC
68-
func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error {
69-
syncSend := NewSynchronizedSend(stream.Send)
70-
outStream := feedStreamTo(func(data []byte) {
71-
syncSend.Send(&rpc.CompileResponse{
72-
Message: &rpc.CompileResponse_OutStream{OutStream: data},
73-
})
74-
})
75-
errStream := feedStreamTo(func(data []byte) {
76-
syncSend.Send(&rpc.CompileResponse{
77-
Message: &rpc.CompileResponse_ErrStream{ErrStream: data},
78-
})
79-
})
80-
progressStream := func(p *rpc.TaskProgress) {
81-
syncSend.Send(&rpc.CompileResponse{
82-
Message: &rpc.CompileResponse_Progress{Progress: p},
83-
})
84-
}
85-
compileRes, compileErr := Compile(stream.Context(), req, outStream, errStream, progressStream)
86-
outStream.Close()
87-
errStream.Close()
88-
var compileRespSendErr error
89-
if compileRes != nil {
90-
compileRespSendErr = syncSend.Send(&rpc.CompileResponse{
91-
Message: &rpc.CompileResponse_Result{
92-
Result: compileRes,
93-
},
94-
})
95-
}
96-
if compileErr != nil {
97-
return compileErr
98-
}
99-
return compileRespSendErr
100-
}
101-
10267
// PlatformInstall FIXMEDOC
10368
func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error {
10469
syncSend := NewSynchronizedSend(stream.Send)

Diff for: commands/service_compile.go

+82-37
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,33 @@ import (
3838
"github.com/sirupsen/logrus"
3939
)
4040

41-
// Compile FIXMEDOC
42-
func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream io.Writer, progressCB rpc.TaskProgressCB) (r *rpc.BuilderResult, e error) {
41+
// CompilerServerToStreams creates a gRPC CompileServer that sends the responses to the provided streams.
42+
// The returned callback function can be used to retrieve the builder result after the compilation is done.
43+
func CompilerServerToStreams(ctx context.Context, stdOut, stderr io.Writer) (server rpc.ArduinoCoreService_CompileServer, resultCB func() *rpc.BuilderResult) {
44+
var builderResult *rpc.BuilderResult
45+
stream := streamResponseToCallback(ctx, func(resp *rpc.CompileResponse) error {
46+
if out := resp.GetOutStream(); len(out) > 0 {
47+
if _, err := stdOut.Write(out); err != nil {
48+
return err
49+
}
50+
}
51+
if err := resp.GetErrStream(); len(err) > 0 {
52+
if _, err := stderr.Write(err); err != nil {
53+
return err
54+
}
55+
}
56+
if result := resp.GetResult(); result != nil {
57+
builderResult = result
58+
}
59+
return nil
60+
})
61+
return stream, func() *rpc.BuilderResult { return builderResult }
62+
}
63+
64+
// Compile performs a compilation of a sketch.
65+
func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error {
66+
ctx := stream.Context()
67+
syncSend := NewSynchronizedSend(stream.Send)
4368

4469
// There is a binding between the export binaries setting and the CLI flag to explicitly set it,
4570
// since we want this binding to work also for the gRPC interface we must read it here in this
@@ -56,27 +81,27 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
5681

5782
pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance())
5883
if err != nil {
59-
return nil, err
84+
return err
6085
}
6186
defer release()
6287

6388
if pme.Dirty() {
64-
return nil, &cmderrors.InstanceNeedsReinitialization{}
89+
return &cmderrors.InstanceNeedsReinitialization{}
6590
}
6691

6792
lm, err := instances.GetLibraryManager(req.GetInstance())
6893
if err != nil {
69-
return nil, err
94+
return err
7095
}
7196

7297
logrus.Tracef("Compile %s for %s started", req.GetSketchPath(), req.GetFqbn())
7398
if req.GetSketchPath() == "" {
74-
return nil, &cmderrors.MissingSketchPathError{}
99+
return &cmderrors.MissingSketchPathError{}
75100
}
76101
sketchPath := paths.New(req.GetSketchPath())
77102
sk, err := sketch.New(sketchPath)
78103
if err != nil {
79-
return nil, &cmderrors.CantOpenSketchError{Cause: err}
104+
return &cmderrors.CantOpenSketchError{Cause: err}
80105
}
81106

82107
fqbnIn := req.GetFqbn()
@@ -88,25 +113,30 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
88113
}
89114
}
90115
if fqbnIn == "" {
91-
return nil, &cmderrors.MissingFQBNError{}
116+
return &cmderrors.MissingFQBNError{}
92117
}
93118

94119
fqbn, err := cores.ParseFQBN(fqbnIn)
95120
if err != nil {
96-
return nil, &cmderrors.InvalidFQBNError{Cause: err}
121+
return &cmderrors.InvalidFQBNError{Cause: err}
97122
}
98123
_, targetPlatform, targetBoard, boardBuildProperties, buildPlatform, err := pme.ResolveFQBN(fqbn)
99124
if err != nil {
100125
if targetPlatform == nil {
101-
return nil, &cmderrors.PlatformNotFoundError{
126+
return &cmderrors.PlatformNotFoundError{
102127
Platform: fmt.Sprintf("%s:%s", fqbn.Package, fqbn.PlatformArch),
103128
Cause: fmt.Errorf(tr("platform not installed")),
104129
}
105130
}
106-
return nil, &cmderrors.InvalidFQBNError{Cause: err}
131+
return &cmderrors.InvalidFQBNError{Cause: err}
107132
}
108133

109-
r = &rpc.BuilderResult{}
134+
r := &rpc.BuilderResult{}
135+
defer func() {
136+
syncSend.Send(&rpc.CompileResponse{
137+
Message: &rpc.CompileResponse_Result{Result: r},
138+
})
139+
}()
110140
r.BoardPlatform = targetPlatform.ToRPCPlatformReference()
111141
r.BuildPlatform = buildPlatform.ToRPCPlatformReference()
112142

@@ -129,7 +159,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
129159
encryptProp := boardBuildProperties.ContainsKey("build.keys.encrypt_key")
130160
// we verify that all the properties for the secure boot keys are defined or none of them is defined.
131161
if !(keychainProp == signProp && signProp == encryptProp) {
132-
return nil, fmt.Errorf(tr("Firmware encryption/signing requires all the following properties to be defined: %s", "build.keys.keychain, build.keys.sign_key, build.keys.encrypt_key"))
162+
return fmt.Errorf(tr("Firmware encryption/signing requires all the following properties to be defined: %s", "build.keys.keychain, build.keys.sign_key, build.keys.encrypt_key"))
133163
}
134164

135165
// Generate or retrieve build path
@@ -138,15 +168,15 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
138168
buildPath = paths.New(req.GetBuildPath()).Canonical()
139169
if in, _ := buildPath.IsInsideDir(sk.FullPath); in && buildPath.IsDir() {
140170
if sk.AdditionalFiles, err = removeBuildFromSketchFiles(sk.AdditionalFiles, buildPath); err != nil {
141-
return nil, err
171+
return err
142172
}
143173
}
144174
}
145175
if buildPath == nil {
146176
buildPath = sk.DefaultBuildPath()
147177
}
148178
if err = buildPath.MkdirAll(); err != nil {
149-
return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build directory"), Cause: err}
179+
return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build directory"), Cause: err}
150180
}
151181
buildcache.New(buildPath.Parent()).GetOrCreate(buildPath.Base())
152182
// cache is purged after compilation to not remove entries that might be required
@@ -158,16 +188,16 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
158188
} else {
159189
buildCachePath, err := paths.New(req.GetBuildCachePath()).Abs()
160190
if err != nil {
161-
return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
191+
return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
162192
}
163193
if err := buildCachePath.MkdirAll(); err != nil {
164-
return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
194+
return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
165195
}
166196
coreBuildCachePath = buildCachePath.Join("core")
167197
}
168198

169199
if _, err := pme.FindToolsRequiredForBuild(targetPlatform, buildPlatform); err != nil {
170-
return nil, err
200+
return err
171201
}
172202

173203
actualPlatform := buildPlatform
@@ -179,7 +209,25 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
179209
libsManager = lm
180210
}
181211

212+
outStream := feedStreamTo(func(data []byte) {
213+
syncSend.Send(&rpc.CompileResponse{
214+
Message: &rpc.CompileResponse_OutStream{OutStream: data},
215+
})
216+
})
217+
defer outStream.Close()
218+
errStream := feedStreamTo(func(data []byte) {
219+
syncSend.Send(&rpc.CompileResponse{
220+
Message: &rpc.CompileResponse_ErrStream{ErrStream: data},
221+
})
222+
})
223+
defer errStream.Close()
224+
progressCB := func(p *rpc.TaskProgress) {
225+
syncSend.Send(&rpc.CompileResponse{
226+
Message: &rpc.CompileResponse_Progress{Progress: p},
227+
})
228+
}
182229
sketchBuilder, err := builder.NewBuilder(
230+
ctx,
183231
sk,
184232
boardBuildProperties,
185233
buildPath,
@@ -204,14 +252,14 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
204252
)
205253
if err != nil {
206254
if strings.Contains(err.Error(), "invalid build properties") {
207-
return nil, &cmderrors.InvalidArgumentError{Message: tr("Invalid build properties"), Cause: err}
255+
return &cmderrors.InvalidArgumentError{Message: tr("Invalid build properties"), Cause: err}
208256
}
209257
if errors.Is(err, builder.ErrSketchCannotBeLocatedInBuildPath) {
210-
return r, &cmderrors.CompileFailedError{
258+
return &cmderrors.CompileFailedError{
211259
Message: tr("Sketch cannot be located in build path. Please specify a different build path"),
212260
}
213261
}
214-
return r, &cmderrors.CompileFailedError{Message: err.Error()}
262+
return &cmderrors.CompileFailedError{Message: err.Error()}
215263
}
216264

217265
defer func() {
@@ -241,18 +289,18 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
241289

242290
// Just get build properties and exit
243291
if req.GetShowProperties() {
244-
return r, nil
292+
return nil
245293
}
246294

247295
if req.GetPreprocess() {
248296
// Just output preprocessed source code and exit
249297
preprocessedSketch, err := sketchBuilder.Preprocess()
250298
if err != nil {
251299
err = &cmderrors.CompileFailedError{Message: err.Error()}
252-
return r, err
300+
return err
253301
}
254302
_, err = outStream.Write(preprocessedSketch)
255-
return r, err
303+
return err
256304
}
257305

258306
defer func() {
@@ -294,7 +342,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
294342
}
295343

296344
if err := sketchBuilder.Build(); err != nil {
297-
return r, &cmderrors.CompileFailedError{Message: err.Error()}
345+
return &cmderrors.CompileFailedError{Message: err.Error()}
298346
}
299347

300348
// If the export directory is set we assume you want to export the binaries
@@ -306,9 +354,8 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
306354
exportBinaries = false
307355
}
308356
if exportBinaries {
309-
err := sketchBuilder.RunRecipe("recipe.hooks.savehex.presavehex", ".pattern", false)
310-
if err != nil {
311-
return r, err
357+
if err := sketchBuilder.RunRecipe("recipe.hooks.savehex.presavehex", ".pattern", false); err != nil {
358+
return err
312359
}
313360

314361
exportPath := paths.New(req.GetExportDir())
@@ -322,38 +369,36 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
322369
if !buildPath.EqualsTo(exportPath) {
323370
logrus.WithField("path", exportPath).Trace("Saving sketch to export path.")
324371
if err := exportPath.MkdirAll(); err != nil {
325-
return r, &cmderrors.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err}
372+
return &cmderrors.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err}
326373
}
327374

328375
baseName, ok := sketchBuilder.GetBuildProperties().GetOk("build.project_name") // == "sketch.ino"
329376
if !ok {
330-
return r, &cmderrors.MissingPlatformPropertyError{Property: "build.project_name"}
377+
return &cmderrors.MissingPlatformPropertyError{Property: "build.project_name"}
331378
}
332379
buildFiles, err := sketchBuilder.GetBuildPath().ReadDir()
333380
if err != nil {
334-
return r, &cmderrors.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err}
381+
return &cmderrors.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err}
335382
}
336383
buildFiles.FilterPrefix(baseName)
337384
for _, buildFile := range buildFiles {
338385
exportedFile := exportPath.Join(buildFile.Base())
339386
logrus.WithField("src", buildFile).WithField("dest", exportedFile).Trace("Copying artifact.")
340387
if err = buildFile.CopyTo(exportedFile); err != nil {
341-
return r, &cmderrors.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err}
388+
return &cmderrors.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err}
342389
}
343390
}
344391
}
345392

346-
err = sketchBuilder.RunRecipe("recipe.hooks.savehex.postsavehex", ".pattern", false)
347-
if err != nil {
348-
return r, err
393+
if err = sketchBuilder.RunRecipe("recipe.hooks.savehex.postsavehex", ".pattern", false); err != nil {
394+
return err
349395
}
350396
}
351397

352398
r.ExecutableSectionsSize = sketchBuilder.ExecutableSectionsSize().ToRPCExecutableSectionSizeArray()
353399

354400
logrus.Tracef("Compile %s for %s successful", sk.Name, fqbnIn)
355-
356-
return r, nil
401+
return nil
357402
}
358403

359404
// maybePurgeBuildCache runs the build files cache purge if the policy conditions are met.

Diff for: internal/arduino/builder/builder.go

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package builder
1717

1818
import (
19+
"context"
1920
"errors"
2021
"fmt"
2122
"io"
@@ -111,6 +112,7 @@ type buildArtifacts struct {
111112

112113
// NewBuilder creates a sketch Builder.
113114
func NewBuilder(
115+
ctx context.Context,
114116
sk *sketch.Sketch,
115117
boardBuildProperties *properties.Map,
116118
buildPath *paths.Path,

Diff for: internal/cli/compile/compile.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer
248248
DoNotExpandBuildProperties: showProperties == arguments.ShowPropertiesUnexpanded,
249249
Jobs: jobs,
250250
}
251-
builderRes, compileError := commands.Compile(context.Background(), compileRequest, stdOut, stdErr, nil)
251+
server, builderResCB := commands.CompilerServerToStreams(ctx, stdOut, stdErr)
252+
compileError := srv.Compile(compileRequest, server)
253+
builderRes := builderResCB()
252254

253255
var uploadRes *rpc.UploadResult
254256
if compileError == nil && uploadAfterCompile {

0 commit comments

Comments
 (0)