@@ -26,6 +26,8 @@ import (
2626 "github.com/golangci/golangci-lint/pkg/result/processors"
2727)
2828
29+ const defaultFileMode = 0644
30+
2931func getDefaultIssueExcludeHelp () string {
3032 parts := []string {"Use or not use default excludes:" }
3133 for _ , ep := range config .DefaultExcludePatterns {
@@ -400,44 +402,89 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
400402 return err // XXX: don't loose type
401403 }
402404
403- p , err := e .createPrinter ()
404- if err != nil {
405- return err
405+ formats := strings .Split (e .cfg .Output .Format , "," )
406+ for _ , format := range formats {
407+ out := strings .SplitN (format , ":" , 2 )
408+ if len (out ) < 2 {
409+ out = append (out , "" )
410+ }
411+
412+ err := e .printReports (ctx , issues , out [1 ], out [0 ])
413+ if err != nil {
414+ return err
415+ }
406416 }
407417
408418 e .setExitCodeIfIssuesFound (issues )
409419
420+ e .fileCache .PrintStats (e .log )
421+
422+ return nil
423+ }
424+
425+ func (e * Executor ) printReports (ctx context.Context , issues []result.Issue , path , format string ) error {
426+ w , shouldClose , err := e .createWriter (path )
427+ if err != nil {
428+ return fmt .Errorf ("can't create output for %s: %w" , path , err )
429+ }
430+
431+ p , err := e .createPrinter (format , w )
432+ if err != nil {
433+ if file , ok := w .(io.Closer ); shouldClose && ok {
434+ _ = file .Close ()
435+ }
436+ return err
437+ }
438+
410439 if err = p .Print (ctx , issues ); err != nil {
440+ if file , ok := w .(io.Closer ); shouldClose && ok {
441+ _ = file .Close ()
442+ }
411443 return fmt .Errorf ("can't print %d issues: %s" , len (issues ), err )
412444 }
413445
414- e .fileCache .PrintStats (e .log )
446+ if file , ok := w .(io.Closer ); shouldClose && ok {
447+ _ = file .Close ()
448+ }
415449
416450 return nil
417451}
418452
419- func (e * Executor ) createPrinter () (printers.Printer , error ) {
453+ func (e * Executor ) createWriter (path string ) (io.Writer , bool , error ) {
454+ if path == "" || path == "stdout" {
455+ return logutils .StdOut , false , nil
456+ }
457+ if path == "stderr" {
458+ return logutils .StdErr , false , nil
459+ }
460+ f , err := os .OpenFile (path , os .O_CREATE | os .O_TRUNC | os .O_WRONLY , defaultFileMode )
461+ if err != nil {
462+ return nil , false , err
463+ }
464+ return f , true , nil
465+ }
466+
467+ func (e * Executor ) createPrinter (format string , w io.Writer ) (printers.Printer , error ) {
420468 var p printers.Printer
421- format := e .cfg .Output .Format
422469 switch format {
423470 case config .OutFormatJSON :
424- p = printers .NewJSON (& e .reportData )
471+ p = printers .NewJSON (& e .reportData , w )
425472 case config .OutFormatColoredLineNumber , config .OutFormatLineNumber :
426473 p = printers .NewText (e .cfg .Output .PrintIssuedLine ,
427474 format == config .OutFormatColoredLineNumber , e .cfg .Output .PrintLinterName ,
428- e .log .Child ("text_printer" ))
475+ e .log .Child ("text_printer" ), w )
429476 case config .OutFormatTab :
430- p = printers .NewTab (e .cfg .Output .PrintLinterName , e .log .Child ("tab_printer" ))
477+ p = printers .NewTab (e .cfg .Output .PrintLinterName , e .log .Child ("tab_printer" ), w )
431478 case config .OutFormatCheckstyle :
432- p = printers .NewCheckstyle ()
479+ p = printers .NewCheckstyle (w )
433480 case config .OutFormatCodeClimate :
434- p = printers .NewCodeClimate ()
481+ p = printers .NewCodeClimate (w )
435482 case config .OutFormatHTML :
436- p = printers .NewHTML ()
483+ p = printers .NewHTML (w )
437484 case config .OutFormatJunitXML :
438- p = printers .NewJunitXML ()
485+ p = printers .NewJunitXML (w )
439486 case config .OutFormatGithubActions :
440- p = printers .NewGithub ()
487+ p = printers .NewGithub (w )
441488 default :
442489 return nil , fmt .Errorf ("unknown output format %s" , format )
443490 }
0 commit comments