github.com/bgpat/reviewdog@v0.0.0-20230909064023-077e44ca1f66/resultmap.go (about)

     1  package reviewdog
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"sync"
     7  
     8  	"github.com/bgpat/reviewdog/filter"
     9  	"github.com/bgpat/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  }