gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/securego/gosec/output/formatter.go (about)

     1  // (c) Copyright 2016 Hewlett Packard Enterprise Development LP
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package output
    16  
    17  import (
    18  	"encoding/csv"
    19  	"encoding/json"
    20  	"encoding/xml"
    21  	htmlTemplate "html/template"
    22  	"io"
    23  	plainTemplate "text/template"
    24  
    25  	"github.com/securego/gosec"
    26  	"gopkg.in/yaml.v2"
    27  )
    28  
    29  // ReportFormat enumrates the output format for reported issues
    30  type ReportFormat int
    31  
    32  const (
    33  	// ReportText is the default format that writes to stdout
    34  	ReportText ReportFormat = iota // Plain text format
    35  
    36  	// ReportJSON set the output format to json
    37  	ReportJSON // Json format
    38  
    39  	// ReportCSV set the output format to csv
    40  	ReportCSV // CSV format
    41  
    42  	// ReportJUnitXML set the output format to junit xml
    43  	ReportJUnitXML // JUnit XML format
    44  )
    45  
    46  var text = `Results:
    47  {{ range $index, $issue := .Issues }}
    48  [{{ $issue.File }}:{{ $issue.Line }}] - {{ $issue.RuleID }}: {{ $issue.What }} (Confidence: {{ $issue.Confidence}}, Severity: {{ $issue.Severity }})
    49    > {{ $issue.Code }}
    50  
    51  {{ end }}
    52  Summary:
    53     Files: {{.Stats.NumFiles}}
    54     Lines: {{.Stats.NumLines}}
    55     Nosec: {{.Stats.NumNosec}}
    56    Issues: {{.Stats.NumFound}}
    57  
    58  `
    59  
    60  type reportInfo struct {
    61  	Issues []*gosec.Issue
    62  	Stats  *gosec.Metrics
    63  }
    64  
    65  // CreateReport generates a report based for the supplied issues and metrics given
    66  // the specified format. The formats currently accepted are: json, csv, html and text.
    67  func CreateReport(w io.Writer, format string, issues []*gosec.Issue, metrics *gosec.Metrics) error {
    68  	data := &reportInfo{
    69  		Issues: issues,
    70  		Stats:  metrics,
    71  	}
    72  	var err error
    73  	switch format {
    74  	case "json":
    75  		err = reportJSON(w, data)
    76  	case "yaml":
    77  		err = reportYAML(w, data)
    78  	case "csv":
    79  		err = reportCSV(w, data)
    80  	case "junit-xml":
    81  		err = reportJUnitXML(w, data)
    82  	case "html":
    83  		err = reportFromHTMLTemplate(w, html, data)
    84  	case "text":
    85  		err = reportFromPlaintextTemplate(w, text, data)
    86  	default:
    87  		err = reportFromPlaintextTemplate(w, text, data)
    88  	}
    89  	return err
    90  }
    91  
    92  func reportJSON(w io.Writer, data *reportInfo) error {
    93  	raw, err := json.MarshalIndent(data, "", "\t")
    94  	if err != nil {
    95  		panic(err)
    96  	}
    97  
    98  	_, err = w.Write(raw)
    99  	if err != nil {
   100  		panic(err)
   101  	}
   102  	return err
   103  }
   104  
   105  func reportYAML(w io.Writer, data *reportInfo) error {
   106  	raw, err := yaml.Marshal(data)
   107  	if err != nil {
   108  		return err
   109  	}
   110  	_, err = w.Write(raw)
   111  	return err
   112  }
   113  
   114  func reportCSV(w io.Writer, data *reportInfo) error {
   115  	out := csv.NewWriter(w)
   116  	defer out.Flush()
   117  	for _, issue := range data.Issues {
   118  		err := out.Write([]string{
   119  			issue.File,
   120  			issue.Line,
   121  			issue.What,
   122  			issue.Severity.String(),
   123  			issue.Confidence.String(),
   124  			issue.Code,
   125  		})
   126  		if err != nil {
   127  			return err
   128  		}
   129  	}
   130  	return nil
   131  }
   132  
   133  func reportJUnitXML(w io.Writer, data *reportInfo) error {
   134  	groupedData := groupDataByRules(data)
   135  	junitXMLStruct := createJUnitXMLStruct(groupedData)
   136  
   137  	raw, err := xml.MarshalIndent(junitXMLStruct, "", "\t")
   138  	if err != nil {
   139  		return err
   140  	}
   141  
   142  	xmlHeader := []byte("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
   143  	raw = append(xmlHeader, raw...)
   144  	_, err = w.Write(raw)
   145  	if err != nil {
   146  		return err
   147  	}
   148  
   149  	return nil
   150  }
   151  
   152  func reportFromPlaintextTemplate(w io.Writer, reportTemplate string, data *reportInfo) error {
   153  	t, e := plainTemplate.New("gosec").Parse(reportTemplate)
   154  	if e != nil {
   155  		return e
   156  	}
   157  
   158  	return t.Execute(w, data)
   159  }
   160  
   161  func reportFromHTMLTemplate(w io.Writer, reportTemplate string, data *reportInfo) error {
   162  	t, e := htmlTemplate.New("gosec").Parse(reportTemplate)
   163  	if e != nil {
   164  		return e
   165  	}
   166  
   167  	return t.Execute(w, data)
   168  }