github.com/mistwind/reviewdog@v0.0.0-20230322024206-9cfa11856d58/reviewdog.go (about) 1 package reviewdog 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 "log" 9 "os" 10 11 "github.com/mistwind/reviewdog/diff" 12 "github.com/mistwind/reviewdog/filter" 13 "github.com/mistwind/reviewdog/parser" 14 "github.com/mistwind/reviewdog/proto/rdf" 15 ) 16 17 // Reviewdog represents review dog application which parses result of compiler 18 // or linter, get diff and filter the results by diff, and report filtered 19 // results. 20 type Reviewdog struct { 21 toolname string 22 p parser.Parser 23 c CommentService 24 d DiffService 25 filterMode filter.Mode 26 failOnError bool 27 } 28 29 // NewReviewdog returns a new Reviewdog. 30 func NewReviewdog(toolname string, p parser.Parser, c CommentService, d DiffService, filterMode filter.Mode, failOnError bool) *Reviewdog { 31 return &Reviewdog{p: p, c: c, d: d, toolname: toolname, filterMode: filterMode, failOnError: failOnError} 32 } 33 34 // RunFromResult creates a new Reviewdog and runs it with check results. 35 func RunFromResult(ctx context.Context, c CommentService, results []*rdf.Diagnostic, 36 filediffs []*diff.FileDiff, strip int, toolname string, filterMode filter.Mode, failOnError bool) error { 37 return (&Reviewdog{c: c, toolname: toolname, filterMode: filterMode, failOnError: failOnError}).runFromResult(ctx, results, filediffs, strip, failOnError) 38 } 39 40 // Comment represents a reported result as a comment. 41 type Comment struct { 42 Result *filter.FilteredDiagnostic 43 ToolName string 44 } 45 46 // CommentService is an interface which posts Comment. 47 type CommentService interface { 48 Post(context.Context, *Comment) error 49 } 50 51 // BulkCommentService posts comments all at once when Flush() is called. 52 // Flush() will be called at the end of reviewdog run. 53 type BulkCommentService interface { 54 CommentService 55 Flush(context.Context) error 56 } 57 58 // DiffService is an interface which get diff. 59 type DiffService interface { 60 Diff(context.Context) ([]byte, error) 61 Strip() int 62 } 63 64 func (w *Reviewdog) runFromResult(ctx context.Context, results []*rdf.Diagnostic, 65 filediffs []*diff.FileDiff, strip int, failOnError bool) error { 66 wd, err := os.Getwd() 67 if err != nil { 68 return err 69 } 70 fmt.Printf("getcwd ok: %s\n", wd) 71 72 checks := filter.FilterCheck(results, filediffs, strip, wd, w.filterMode) 73 hasViolations := false 74 fmt.Printf("checks length is %d\n", len(checks)) 75 76 for _, check := range checks { 77 if !check.ShouldReport { 78 fmt.Printf("comment for %s should not be reported\n", check.Diagnostic.Message) 79 continue 80 } 81 fmt.Printf("comment for %s should be reported\n", check.Diagnostic.Message) 82 comment := &Comment{ 83 Result: check, 84 ToolName: w.toolname, 85 } 86 87 fmt.Printf("posting comment for %s...\n", check.Diagnostic.Message) 88 89 if err := w.c.Post(ctx, comment); err != nil { 90 fmt.Printf("posting comment for %s error: %s\n", check.Diagnostic.Message, err) 91 return err 92 } 93 fmt.Printf("posting comment for %s ok\n", check.Diagnostic.Message) 94 hasViolations = true 95 } 96 97 if bulk, ok := w.c.(BulkCommentService); ok { 98 if err := bulk.Flush(ctx); err != nil { 99 return err 100 } 101 } 102 103 if failOnError && hasViolations { 104 return fmt.Errorf("input data has violations") 105 } 106 107 return nil 108 } 109 110 // Run runs Reviewdog application. 111 func (w *Reviewdog) Run(ctx context.Context, r io.Reader) error { 112 results, err := w.p.Parse(r) 113 if err != nil { 114 return fmt.Errorf("parse error: %w", err) 115 } 116 117 log.Printf("reviewdog: parse result: %#v\n", results) 118 119 d, err := w.d.Diff(ctx) 120 if err != nil { 121 return fmt.Errorf("fail to get diff: %w", err) 122 } 123 log.Printf("reviewdog: diff ok\n") 124 125 filediffs, err := diff.ParseMultiFile(bytes.NewReader(d)) 126 if err != nil { 127 return fmt.Errorf("fail to parse diff: %w", err) 128 } 129 log.Printf("reviewdog: parse multifile ok\n") 130 131 return w.runFromResult(ctx, results, filediffs, w.d.Strip(), w.failOnError) 132 }