github.com/Mistwind/reviewdog@v0.0.0-20230317041057-48e69b6d9e86/resultmap.go (about) 1 package reviewdog 2 3 import ( 4 "errors" 5 "fmt" 6 "sync" 7 8 "github.com/reviewdog/reviewdog/filter" 9 "github.com/reviewdog/reviewdog/proto/rdf" 10 ) 11 12 // ResultMap represents a concurrent-safe map to store Diagnostics generated by concurrent jobs. 13 type ResultMap struct { 14 sm sync.Map 15 } 16 17 type Result struct { 18 Name string 19 Level string 20 Diagnostics []*rdf.Diagnostic 21 22 // Optional. Report an error of the command execution. 23 // Non-nil CmdErr doesn't mean failure and Diagnostics still may have 24 // results. 25 // It is common that a linter fails with non-zero exit code when it finds 26 // lint errors. 27 CmdErr error 28 } 29 30 // CheckUnexpectedFailure returns error on unexpected failure, if any. 31 func (r *Result) CheckUnexpectedFailure() error { 32 if r.CmdErr != nil && len(r.Diagnostics) == 0 { 33 return fmt.Errorf("%s failed with zero findings: The command itself "+ 34 "failed (%v) or reviewdog cannot parse the results", r.Name, r.CmdErr) 35 } 36 return nil 37 } 38 39 // Store saves a new *Result into ResultMap. 40 func (rm *ResultMap) Store(key string, r *Result) { 41 rm.sm.Store(key, r) 42 } 43 44 // Load fetches *Result from ResultMap 45 func (rm *ResultMap) Load(key string) (*Result, error) { 46 v, ok := rm.sm.Load(key) 47 if !ok { 48 return nil, fmt.Errorf("fail to get the value of key %q from results", key) 49 } 50 51 t, ok := v.(*Result) 52 if !ok { 53 return nil, errors.New("stored type in ResultMap is invalid") 54 } 55 56 return t, nil 57 } 58 59 // Range retrieves `key` and `values` from ResultMap iteratively. 60 func (rm *ResultMap) Range(f func(key string, val *Result)) { 61 rm.sm.Range(func(k, v interface{}) bool { 62 f(k.(string), v.(*Result)) 63 return true 64 }) 65 } 66 67 // Len returns the length of ResultMap count. Len() is not yet officially not supported by Go. (ref: https://github.com/golang/go/issues/20680) 68 func (rm *ResultMap) Len() int { 69 l := 0 70 rm.sm.Range(func(_, _ interface{}) bool { 71 l++ 72 return true 73 }) 74 return l 75 } 76 77 type FilteredResult struct { 78 Level string 79 FilteredDiagnostic []*filter.FilteredDiagnostic 80 } 81 82 // FilteredResultMap represents a concurrent-safe map to store Diagnostics generated by concurrent jobs. 83 type FilteredResultMap struct { 84 sm sync.Map 85 } 86 87 // Store saves a new []*FilteredCheckFilteredResult into FilteredResultMap. 88 func (rm *FilteredResultMap) Store(key string, r *FilteredResult) { 89 rm.sm.Store(key, r) 90 } 91 92 // Load fetches FilteredResult from FilteredResultMap 93 func (rm *FilteredResultMap) Load(key string) (*FilteredResult, error) { 94 v, ok := rm.sm.Load(key) 95 if !ok { 96 return nil, fmt.Errorf("fail to get the value of key %q from results", key) 97 } 98 99 t, ok := v.(*FilteredResult) 100 if !ok { 101 return nil, errors.New("stored type in FilteredResultMap is invalid") 102 } 103 104 return t, nil 105 } 106 107 // Range retrieves `key` and `values` from FilteredResultMap iteratively. 108 func (rm *FilteredResultMap) Range(f func(key string, val *FilteredResult)) { 109 rm.sm.Range(func(k, v interface{}) bool { 110 f(k.(string), v.(*FilteredResult)) 111 return true 112 }) 113 } 114 115 // Len returns the length of FilteredResultMap count. Len() is not yet officially not supported by Go. (ref: https://github.com/golang/go/issues/20680) 116 func (rm *FilteredResultMap) Len() int { 117 l := 0 118 rm.sm.Range(func(_, _ interface{}) bool { 119 l++ 120 return true 121 }) 122 return l 123 }