diff --git a/core/analyzer.go b/core/analyzer.go index fc983b7..1cf3730 100644 --- a/core/analyzer.go +++ b/core/analyzer.go @@ -40,10 +40,10 @@ type Rule interface { type RuleSet map[reflect.Type][]Rule type Metrics struct { - NumFiles int - NumLines int - NumNosec int - NumFound int + NumFiles int `json:"files"` + NumLines int `json:"lines"` + NumNosec int `json:"nosec"` + NumFound int `json:"found"` } type Analyzer struct { @@ -51,8 +51,8 @@ type Analyzer struct { ruleset RuleSet context Context logger *log.Logger - Issues []Issue - Stats Metrics + Issues []Issue `json:"issues"` + Stats Metrics `json:"metrics"` } func NewAnalyzer(annotations bool, logger *log.Logger) Analyzer { diff --git a/core/issue.go b/core/issue.go index ad8ec30..261e840 100644 --- a/core/issue.go +++ b/core/issue.go @@ -14,6 +14,7 @@ package core import ( + "encoding/json" "fmt" "go/ast" "os" @@ -28,12 +29,12 @@ const ( ) type Issue struct { - Severity Score - Confidence Score - What string - File string - Code string - Line int + Severity Score `json:"severity"` + Confidence Score `json:"confidence"` + What string `json:"details"` + File string `json:"file"` + Code string `json:"code"` + Line int `json:"line"` } type MetaData struct { @@ -42,6 +43,10 @@ type MetaData struct { What string } +func (c Score) MarshalJSON() ([]byte, error) { + return json.Marshal(c.String()) +} + func (c Score) String() string { switch c { case High: diff --git a/output/formatter.go b/output/formatter.go index 8211f5e..2bbda13 100644 --- a/output/formatter.go +++ b/output/formatter.go @@ -15,8 +15,9 @@ package output import ( + "encoding/json" + "html/template" "io" - "text/template" gas "github.com/HewlettPackard/gas/core" ) @@ -44,25 +45,6 @@ Summary: ` -var json = `{ - "metrics": { - "files": {{.Stats.NumFiles}}, - "lines": {{.Stats.NumLines}}, - "nosec": {{.Stats.NumNosec}}, - "issues": {{.Stats.NumFound}} - }, - "issues": [ - {{ range $index, $issue := .Issues }}{{ if $index }}, {{ end }}{ - "file": "{{ $issue.File }}", - "line": "{{ $issue.Line }}", - "details": "{{ $issue.What }}", - "confidence": "{{ $issue.Confidence }}", - "severity": "{{ $issue.Severity }}", - "code": "{{ js $issue.Code }}" - }{{ end }} - ] -}` - var csv = `{{ range $index, $issue := .Issues -}} {{- $issue.File -}}, {{- $issue.Line -}}, @@ -73,20 +55,35 @@ var csv = `{{ range $index, $issue := .Issues -}} {{ end }}` func CreateReport(w io.Writer, format string, data *gas.Analyzer) error { - reportType := text - + var err error switch format { - case "csv": - reportType = csv case "json": - reportType = json + err = reportJSON(w, data) + case "csv": + err = reportFromTemplate(w, csv, data) case "text": - reportType = text + err = reportFromTemplate(w, text, data) default: - reportType = text + err = reportFromTemplate(w, text, data) + } + return err +} + +func reportJSON(w io.Writer, data *gas.Analyzer) error { + raw, err := json.MarshalIndent(data, "", "\t") + if err != nil { + panic(err) } - t, e := template.New("gas").Parse(reportType) + _, err = w.Write(raw) + if err != nil { + panic(err) + } + return err +} + +func reportFromTemplate(w io.Writer, reportTemplate string, data *gas.Analyzer) error { + t, e := template.New("gas").Parse(reportTemplate) if e != nil { return e }