Skip to content

Commit 0f016db

Browse files
committed
Inlining methods in ArduinoCoreServiceImpl (part 9: Compile)
1 parent 7847cb9 commit 0f016db

File tree

4 files changed

+88
-73
lines changed

4 files changed

+88
-73
lines changed

commands/service.go

-35
Original file line numberDiff line numberDiff line change
@@ -76,41 +76,6 @@ func (s *arduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.
7676
return SetSketchDefaults(ctx, req)
7777
}
7878

79-
// Compile FIXMEDOC
80-
func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error {
81-
syncSend := NewSynchronizedSend(stream.Send)
82-
outStream := feedStreamTo(func(data []byte) {
83-
syncSend.Send(&rpc.CompileResponse{
84-
Message: &rpc.CompileResponse_OutStream{OutStream: data},
85-
})
86-
})
87-
errStream := feedStreamTo(func(data []byte) {
88-
syncSend.Send(&rpc.CompileResponse{
89-
Message: &rpc.CompileResponse_ErrStream{ErrStream: data},
90-
})
91-
})
92-
progressStream := func(p *rpc.TaskProgress) {
93-
syncSend.Send(&rpc.CompileResponse{
94-
Message: &rpc.CompileResponse_Progress{Progress: p},
95-
})
96-
}
97-
compileRes, compileErr := Compile(stream.Context(), req, outStream, errStream, progressStream)
98-
outStream.Close()
99-
errStream.Close()
100-
var compileRespSendErr error
101-
if compileRes != nil {
102-
compileRespSendErr = syncSend.Send(&rpc.CompileResponse{
103-
Message: &rpc.CompileResponse_Result{
104-
Result: compileRes,
105-
},
106-
})
107-
}
108-
if compileErr != nil {
109-
return compileErr
110-
}
111-
return compileRespSendErr
112-
}
113-
11479
// PlatformInstall FIXMEDOC
11580
func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error {
11681
syncSend := NewSynchronizedSend(stream.Send)

commands/service_compile.go

+83-37
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,62 @@ 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)
68+
4369
exportBinaries := configuration.Settings.GetBool("sketch.always_export_binaries")
4470
if e := req.ExportBinaries; e != nil {
4571
exportBinaries = *e
4672
}
4773

4874
pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance())
4975
if err != nil {
50-
return nil, err
76+
return err
5177
}
5278
defer release()
5379

5480
if pme.Dirty() {
55-
return nil, &cmderrors.InstanceNeedsReinitialization{}
81+
return &cmderrors.InstanceNeedsReinitialization{}
5682
}
5783

5884
lm, err := instances.GetLibraryManager(req.GetInstance())
5985
if err != nil {
60-
return nil, err
86+
return err
6187
}
6288

6389
logrus.Tracef("Compile %s for %s started", req.GetSketchPath(), req.GetFqbn())
6490
if req.GetSketchPath() == "" {
65-
return nil, &cmderrors.MissingSketchPathError{}
91+
return &cmderrors.MissingSketchPathError{}
6692
}
6793
sketchPath := paths.New(req.GetSketchPath())
6894
sk, err := sketch.New(sketchPath)
6995
if err != nil {
70-
return nil, &cmderrors.CantOpenSketchError{Cause: err}
96+
return &cmderrors.CantOpenSketchError{Cause: err}
7197
}
7298

7399
fqbnIn := req.GetFqbn()
@@ -79,25 +105,30 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
79105
}
80106
}
81107
if fqbnIn == "" {
82-
return nil, &cmderrors.MissingFQBNError{}
108+
return &cmderrors.MissingFQBNError{}
83109
}
84110

85111
fqbn, err := cores.ParseFQBN(fqbnIn)
86112
if err != nil {
87-
return nil, &cmderrors.InvalidFQBNError{Cause: err}
113+
return &cmderrors.InvalidFQBNError{Cause: err}
88114
}
89115
_, targetPlatform, targetBoard, boardBuildProperties, buildPlatform, err := pme.ResolveFQBN(fqbn)
90116
if err != nil {
91117
if targetPlatform == nil {
92-
return nil, &cmderrors.PlatformNotFoundError{
118+
return &cmderrors.PlatformNotFoundError{
93119
Platform: fmt.Sprintf("%s:%s", fqbn.Package, fqbn.PlatformArch),
94120
Cause: fmt.Errorf(tr("platform not installed")),
95121
}
96122
}
97-
return nil, &cmderrors.InvalidFQBNError{Cause: err}
123+
return &cmderrors.InvalidFQBNError{Cause: err}
98124
}
99125

100-
r = &rpc.BuilderResult{}
126+
r := &rpc.BuilderResult{}
127+
defer func() {
128+
syncSend.Send(&rpc.CompileResponse{
129+
Message: &rpc.CompileResponse_Result{Result: r},
130+
})
131+
}()
101132
r.BoardPlatform = targetPlatform.ToRPCPlatformReference()
102133
r.BuildPlatform = buildPlatform.ToRPCPlatformReference()
103134

@@ -120,7 +151,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
120151
encryptProp := boardBuildProperties.ContainsKey("build.keys.encrypt_key")
121152
// we verify that all the properties for the secure boot keys are defined or none of them is defined.
122153
if !(keychainProp == signProp && signProp == encryptProp) {
123-
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"))
154+
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"))
124155
}
125156

126157
// Generate or retrieve build path
@@ -129,15 +160,15 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
129160
buildPath = paths.New(req.GetBuildPath()).Canonical()
130161
if in, _ := buildPath.IsInsideDir(sk.FullPath); in && buildPath.IsDir() {
131162
if sk.AdditionalFiles, err = removeBuildFromSketchFiles(sk.AdditionalFiles, buildPath); err != nil {
132-
return nil, err
163+
return err
133164
}
134165
}
135166
}
136167
if buildPath == nil {
137168
buildPath = sk.DefaultBuildPath()
138169
}
139170
if err = buildPath.MkdirAll(); err != nil {
140-
return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build directory"), Cause: err}
171+
return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build directory"), Cause: err}
141172
}
142173
buildcache.New(buildPath.Parent()).GetOrCreate(buildPath.Base())
143174
// cache is purged after compilation to not remove entries that might be required
@@ -149,16 +180,16 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
149180
} else {
150181
buildCachePath, err := paths.New(req.GetBuildCachePath()).Abs()
151182
if err != nil {
152-
return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
183+
return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
153184
}
154185
if err := buildCachePath.MkdirAll(); err != nil {
155-
return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
186+
return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err}
156187
}
157188
coreBuildCachePath = buildCachePath.Join("core")
158189
}
159190

160191
if _, err := pme.FindToolsRequiredForBuild(targetPlatform, buildPlatform); err != nil {
161-
return nil, err
192+
return err
162193
}
163194

164195
actualPlatform := buildPlatform
@@ -170,7 +201,25 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
170201
libsManager = lm
171202
}
172203

204+
outStream := feedStreamTo(func(data []byte) {
205+
syncSend.Send(&rpc.CompileResponse{
206+
Message: &rpc.CompileResponse_OutStream{OutStream: data},
207+
})
208+
})
209+
defer outStream.Close()
210+
errStream := feedStreamTo(func(data []byte) {
211+
syncSend.Send(&rpc.CompileResponse{
212+
Message: &rpc.CompileResponse_ErrStream{ErrStream: data},
213+
})
214+
})
215+
defer errStream.Close()
216+
progressCB := func(p *rpc.TaskProgress) {
217+
syncSend.Send(&rpc.CompileResponse{
218+
Message: &rpc.CompileResponse_Progress{Progress: p},
219+
})
220+
}
173221
sketchBuilder, err := builder.NewBuilder(
222+
ctx,
174223
sk,
175224
boardBuildProperties,
176225
buildPath,
@@ -195,14 +244,14 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
195244
)
196245
if err != nil {
197246
if strings.Contains(err.Error(), "invalid build properties") {
198-
return nil, &cmderrors.InvalidArgumentError{Message: tr("Invalid build properties"), Cause: err}
247+
return &cmderrors.InvalidArgumentError{Message: tr("Invalid build properties"), Cause: err}
199248
}
200249
if errors.Is(err, builder.ErrSketchCannotBeLocatedInBuildPath) {
201-
return r, &cmderrors.CompileFailedError{
250+
return &cmderrors.CompileFailedError{
202251
Message: tr("Sketch cannot be located in build path. Please specify a different build path"),
203252
}
204253
}
205-
return r, &cmderrors.CompileFailedError{Message: err.Error()}
254+
return &cmderrors.CompileFailedError{Message: err.Error()}
206255
}
207256

208257
defer func() {
@@ -232,18 +281,18 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
232281

233282
// Just get build properties and exit
234283
if req.GetShowProperties() {
235-
return r, nil
284+
return nil
236285
}
237286

238287
if req.GetPreprocess() {
239288
// Just output preprocessed source code and exit
240289
preprocessedSketch, err := sketchBuilder.Preprocess()
241290
if err != nil {
242291
err = &cmderrors.CompileFailedError{Message: err.Error()}
243-
return r, err
292+
return err
244293
}
245294
_, err = outStream.Write(preprocessedSketch)
246-
return r, err
295+
return err
247296
}
248297

249298
defer func() {
@@ -285,7 +334,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
285334
}
286335

287336
if err := sketchBuilder.Build(); err != nil {
288-
return r, &cmderrors.CompileFailedError{Message: err.Error()}
337+
return &cmderrors.CompileFailedError{Message: err.Error()}
289338
}
290339

291340
// If the export directory is set we assume you want to export the binaries
@@ -297,9 +346,8 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
297346
exportBinaries = false
298347
}
299348
if exportBinaries {
300-
err := sketchBuilder.RunRecipe("recipe.hooks.savehex.presavehex", ".pattern", false)
301-
if err != nil {
302-
return r, err
349+
if err := sketchBuilder.RunRecipe("recipe.hooks.savehex.presavehex", ".pattern", false); err != nil {
350+
return err
303351
}
304352

305353
exportPath := paths.New(req.GetExportDir())
@@ -313,38 +361,36 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream
313361
if !buildPath.EqualsTo(exportPath) {
314362
logrus.WithField("path", exportPath).Trace("Saving sketch to export path.")
315363
if err := exportPath.MkdirAll(); err != nil {
316-
return r, &cmderrors.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err}
364+
return &cmderrors.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err}
317365
}
318366

319367
baseName, ok := sketchBuilder.GetBuildProperties().GetOk("build.project_name") // == "sketch.ino"
320368
if !ok {
321-
return r, &cmderrors.MissingPlatformPropertyError{Property: "build.project_name"}
369+
return &cmderrors.MissingPlatformPropertyError{Property: "build.project_name"}
322370
}
323371
buildFiles, err := sketchBuilder.GetBuildPath().ReadDir()
324372
if err != nil {
325-
return r, &cmderrors.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err}
373+
return &cmderrors.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err}
326374
}
327375
buildFiles.FilterPrefix(baseName)
328376
for _, buildFile := range buildFiles {
329377
exportedFile := exportPath.Join(buildFile.Base())
330378
logrus.WithField("src", buildFile).WithField("dest", exportedFile).Trace("Copying artifact.")
331379
if err = buildFile.CopyTo(exportedFile); err != nil {
332-
return r, &cmderrors.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err}
380+
return &cmderrors.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err}
333381
}
334382
}
335383
}
336384

337-
err = sketchBuilder.RunRecipe("recipe.hooks.savehex.postsavehex", ".pattern", false)
338-
if err != nil {
339-
return r, err
385+
if err = sketchBuilder.RunRecipe("recipe.hooks.savehex.postsavehex", ".pattern", false); err != nil {
386+
return err
340387
}
341388
}
342389

343390
r.ExecutableSectionsSize = sketchBuilder.ExecutableSectionsSize().ToRPCExecutableSectionSizeArray()
344391

345392
logrus.Tracef("Compile %s for %s successful", sk.Name, fqbnIn)
346-
347-
return r, nil
393+
return nil
348394
}
349395

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

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,

internal/cli/compile/compile.go

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

251253
var uploadRes *rpc.UploadResult
252254
if compileError == nil && uploadAfterCompile {

0 commit comments

Comments
 (0)