github.com/mistwind/reviewdog@v0.0.0-20230322024206-9cfa11856d58/parser/parser.go (about)

     1  package parser
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  
     9  	"github.com/reviewdog/errorformat/fmts"
    10  
    11  	"github.com/mistwind/reviewdog/proto/rdf"
    12  )
    13  
    14  // Parser is an interface which parses compilers, linters, or any tools
    15  // results.
    16  type Parser interface {
    17  	Parse(r io.Reader) ([]*rdf.Diagnostic, error)
    18  }
    19  
    20  // Option represents option to create Parser. Either FormatName or
    21  // Errorformat should be specified.
    22  type Option struct {
    23  	FormatName  string
    24  	Errorformat []string
    25  	DiffStrip   int
    26  }
    27  
    28  // New returns Parser based on Option.
    29  func New(opt *Option) (Parser, error) {
    30  	name := opt.FormatName
    31  
    32  	log.Printf("parser name = %s\n", name)
    33  
    34  	if name != "" && len(opt.Errorformat) > 0 {
    35  		return nil, errors.New("you cannot specify both format name and errorformat at the same time")
    36  	}
    37  
    38  	switch name {
    39  	case "checkstyle":
    40  		return NewCheckStyleParser(), nil
    41  	case "rdjsonl":
    42  		return NewRDJSONLParser(), nil
    43  	case "rdjson":
    44  		return NewRDJSONParser(), nil
    45  	case "diff":
    46  		return NewDiffParser(opt.DiffStrip), nil
    47  	}
    48  
    49  	// use defined errorformat
    50  	if name != "" {
    51  		efm, ok := fmts.DefinedFmts()[name]
    52  		if !ok {
    53  			return nil, fmt.Errorf("%q is not supported. consider to add new errorformat to https://github.com/reviewdog/errorformat", name)
    54  		}
    55  		opt.Errorformat = efm.Errorformat
    56  	}
    57  	if len(opt.Errorformat) == 0 {
    58  		return nil, errors.New("errorformat is empty")
    59  	}
    60  	return NewErrorformatParserString(opt.Errorformat)
    61  }
    62  
    63  func severity(s string) rdf.Severity {
    64  	switch s {
    65  	case "error", "ERROR", "Error", "e", "E":
    66  		return rdf.Severity_ERROR
    67  	case "warning", "WARNING", "Warning", "w", "W":
    68  		return rdf.Severity_WARNING
    69  	case "info", "INFO", "Info", "i", "I",
    70  		"note", "NOTE", "Note", "n", "N": // Treat note as info.
    71  		return rdf.Severity_INFO
    72  	default:
    73  		return rdf.Severity_UNKNOWN_SEVERITY
    74  	}
    75  }