@@ -20,15 +20,13 @@ package feedback
2020import (
2121 "bytes"
2222 "encoding/json"
23- "errors"
2423 "fmt"
2524 "io"
2625 "os"
2726
2827 "github.com/arduino/arduino-cli/cli/errorcodes"
2928 "github.com/arduino/arduino-cli/i18n"
3029 "github.com/sirupsen/logrus"
31- "google.golang.org/grpc/status"
3230 "gopkg.in/yaml.v2"
3331)
3432
7674 feedbackErr io.Writer
7775 bufferOut * bytes.Buffer
7876 bufferErr * bytes.Buffer
77+ bufferWarnings []string
7978 format OutputFormat
8079 formatSelected bool
8180)
@@ -92,6 +91,7 @@ func reset() {
9291 feedbackErr = os .Stderr
9392 bufferOut = & bytes.Buffer {}
9493 bufferErr = & bytes.Buffer {}
94+ bufferWarnings = nil
9595 format = Text
9696 formatSelected = false
9797}
@@ -135,6 +135,7 @@ func SetFormat(f OutputFormat) {
135135 } else {
136136 feedbackOut = bufferOut
137137 feedbackErr = bufferErr
138+ bufferWarnings = nil
138139 }
139140}
140141
@@ -153,27 +154,14 @@ func Print(v string) {
153154 fmt .Fprintln (feedbackOut , v )
154155}
155156
156- // Errorf behaves like fmt.Printf but writes on the error writer and adds a
157- // newline. It also logs the error.
158- func Errorf (format string , v ... interface {}) {
159- // Unbox grpc status errors
160- for i := range v {
161- if s , isStatus := v [i ].(* status.Status ); isStatus {
162- v [i ] = errors .New (s .Message ())
163- } else if err , isErr := v [i ].(error ); isErr {
164- if s , isStatus := status .FromError (err ); isStatus {
165- v [i ] = errors .New (s .Message ())
166- }
167- }
157+ // Warning outputs a warning message.
158+ func Warning (msg string ) {
159+ if format == Text {
160+ fmt .Fprintln (feedbackErr , msg )
161+ } else {
162+ bufferWarnings = append (bufferWarnings , msg )
168163 }
169- Error (fmt .Sprintf (format , v ... ))
170- }
171-
172- // Error behaves like fmt.Print but writes on the error writer and adds a
173- // newline. It also logs the error.
174- func Error (v ... interface {}) {
175- fmt .Fprintln (stdErr , v ... )
176- logrus .Error (fmt .Sprint (v ... ))
164+ logrus .Warning (msg )
177165}
178166
179167// FatalError outputs the error and exits with status exitCode.
@@ -213,26 +201,44 @@ func Fatal(errorMsg string, exitCode int) {
213201 os .Exit (exitCode )
214202}
215203
204+ func augment (data interface {}) interface {} {
205+ if len (bufferWarnings ) == 0 {
206+ return data
207+ }
208+ d , err := json .Marshal (data )
209+ if err != nil {
210+ return data
211+ }
212+ var res interface {}
213+ if err := json .Unmarshal (d , & res ); err != nil {
214+ return data
215+ }
216+ if m , ok := res .(map [string ]interface {}); ok {
217+ m ["warnings" ] = bufferWarnings
218+ }
219+ return res
220+ }
221+
216222// PrintResult is a convenient wrapper to provide feedback for complex data,
217223// where the contents can't be just serialized to JSON but requires more
218224// structure.
219225func PrintResult (res Result ) {
220226 var data string
221227 switch format {
222228 case JSON :
223- d , err := json .MarshalIndent (res .Data (), "" , " " )
229+ d , err := json .MarshalIndent (augment ( res .Data () ), "" , " " )
224230 if err != nil {
225231 Fatal (fmt .Sprintf ("Error during JSON encoding of the output: %v" , err ), errorcodes .ErrGeneric )
226232 }
227233 data = string (d )
228234 case MinifiedJSON :
229- d , err := json .Marshal (res .Data ())
235+ d , err := json .Marshal (augment ( res .Data () ))
230236 if err != nil {
231237 Fatal (fmt .Sprintf ("Error during JSON encoding of the output: %v" , err ), errorcodes .ErrGeneric )
232238 }
233239 data = string (d )
234240 case YAML :
235- d , err := yaml .Marshal (res .Data ())
241+ d , err := yaml .Marshal (augment ( res .Data () ))
236242 if err != nil {
237243 Fatal (fmt .Sprintf ("Error during YAML encoding of the output: %v" , err ), errorcodes .ErrGeneric )
238244 }
0 commit comments