Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit eece582

Browse files
authored
Fixed compiler output capture in JSON mode (#2078)
* Added integration test for #1698 * Added helper functions to handle concurrent writes to ctx.Stdout/Stderr * Do not alter ctx.Stderr/Stdout in ExecCommand Some instances of ctx.Stdout may now contains nil since it's no more altered during ExecCommand. * Handle multi-threaded compile streams
1 parent 6992de7 commit eece582

File tree

9 files changed

+65
-15
lines changed

9 files changed

+65
-15
lines changed

‎internal/integrationtest/compile_3/compile_test.go‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/arduino/go-paths-helper"
2323
"github.com/arduino/go-properties-orderedmap"
2424
"github.com/stretchr/testify/require"
25+
"go.bug.st/testifyjson/requirejson"
2526
)
2627

2728
func TestRuntimeToolPropertiesGeneration(t *testing.T) {
@@ -96,3 +97,22 @@ func TestCompileBuildPathInsideSketch(t *testing.T) {
9697
_, _, err = cli.Run("compile", "-b", "arduino:avr:mega", "--build-path", "build-mega")
9798
require.NoError(t, err)
9899
}
100+
101+
func TestCompilerErrOutput(t *testing.T) {
102+
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
103+
defer env.CleanUp()
104+
105+
// Run update-index with our test index
106+
_, _, err := cli.Run("core", "install", "arduino:avr@1.8.5")
107+
require.NoError(t, err)
108+
109+
// prepare sketch
110+
sketch, err := paths.New("testdata", "blink_with_wrong_cpp").Abs()
111+
require.NoError(t, err)
112+
113+
// Run compile and catch err stream
114+
out, _, err := cli.Run("compile", "-b", "arduino:avr:uno", "--format", "json", sketch.String())
115+
require.Error(t, err)
116+
compilerErr := requirejson.Parse(t, out).Query(".compiler_err")
117+
compilerErr.MustContain(`"error"`)
118+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
void setup() {}
2+
void loop() {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
void wrong() {

‎legacy/builder/builder.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ func (s *Preprocess) Run(ctx *types.Context) error {
152152
}
153153

154154
// Output arduino-preprocessed source
155-
ctx.Stdout.Write([]byte(ctx.Source))
155+
ctx.WriteStdout([]byte(ctx.Source))
156156
return nil
157157
}
158158

‎legacy/builder/builder_utils/utils.go‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,15 @@ func compileFileWithRecipe(ctx *types.Context, sourcePath *paths.Path, source *p
190190
ctx.CompilationDatabase.Add(source, command)
191191
}
192192
if !objIsUpToDate && !ctx.OnlyUpdateCompilationDatabase {
193-
_, _, err = utils.ExecCommand(ctx, command, utils.ShowIfVerbose /* stdout */, utils.Show /* stderr */)
193+
// Since this compile could be multithreaded, we first capture the command output
194+
stdout, stderr, err := utils.ExecCommand(ctx, command, utils.Capture, utils.Capture)
195+
// and transfer all at once at the end...
196+
if ctx.Verbose {
197+
ctx.WriteStdout(stdout)
198+
}
199+
ctx.WriteStderr(stderr)
200+
201+
// ...and then return the error
194202
if err != nil {
195203
return nil, errors.WithStack(err)
196204
}

‎legacy/builder/container_find_includes.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ func findIncludesUntilDone(ctx *types.Context, cache *includeCache, sourceFile t
408408
return errors.New(tr("Internal error in cache"))
409409
}
410410
}
411-
ctx.Stderr.Write(preproc_stderr)
411+
ctx.WriteStderr(preproc_stderr)
412412
return errors.WithStack(preproc_err)
413413
}
414414

‎legacy/builder/preprocess_sketch.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,6 @@ func (s *OutputCodeCompletions) Run(ctx *types.Context) error {
146146
// we assume it is a json, let's make it compliant at least
147147
ctx.CodeCompletions = "[]"
148148
}
149-
fmt.Fprintln(ctx.Stdout, ctx.CodeCompletions)
149+
ctx.WriteStdout([]byte(ctx.CodeCompletions))
150150
return nil
151151
}

‎legacy/builder/types/context.go‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,21 @@ func (ctx *Context) Warn(msg string) {
249249
}
250250
ctx.stdLock.Unlock()
251251
}
252+
253+
func (ctx *Context) WriteStdout(data []byte) (int, error) {
254+
ctx.stdLock.Lock()
255+
defer ctx.stdLock.Unlock()
256+
if ctx.Stdout == nil {
257+
return os.Stdout.Write(data)
258+
}
259+
return ctx.Stdout.Write(data)
260+
}
261+
262+
func (ctx *Context) WriteStderr(data []byte) (int, error) {
263+
ctx.stdLock.Lock()
264+
defer ctx.stdLock.Unlock()
265+
if ctx.Stderr == nil {
266+
return os.Stderr.Write(data)
267+
}
268+
return ctx.Stderr.Write(data)
269+
}

‎legacy/builder/utils/utils.go‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -184,29 +184,30 @@ const (
184184
)
185185

186186
func ExecCommand(ctx *types.Context, command *exec.Cmd, stdout int, stderr int) ([]byte, []byte, error) {
187-
if ctx.Stdout == nil {
188-
ctx.Stdout = os.Stdout
189-
}
190-
if ctx.Stderr == nil {
191-
ctx.Stderr = os.Stderr
192-
}
193-
194187
if ctx.Verbose {
195188
ctx.Info(PrintableCommand(command.Args))
196189
}
197190

198191
if stdout == Capture {
199192
buffer := &bytes.Buffer{}
200193
command.Stdout = buffer
201-
} else if stdout == Show || stdout == ShowIfVerbose && ctx.Verbose {
202-
command.Stdout = ctx.Stdout
194+
} else if stdout == Show || (stdout == ShowIfVerbose && ctx.Verbose) {
195+
if ctx.Stdout != nil {
196+
command.Stdout = ctx.Stdout
197+
} else {
198+
command.Stdout = os.Stdout
199+
}
203200
}
204201

205202
if stderr == Capture {
206203
buffer := &bytes.Buffer{}
207204
command.Stderr = buffer
208-
} else if stderr == Show || stderr == ShowIfVerbose && ctx.Verbose {
209-
command.Stderr = ctx.Stderr
205+
} else if stderr == Show || (stderr == ShowIfVerbose && ctx.Verbose) {
206+
if ctx.Stderr != nil {
207+
command.Stderr = ctx.Stderr
208+
} else {
209+
command.Stderr = os.Stderr
210+
}
210211
}
211212

212213
err := command.Start()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /