Skip to content

Commit

Permalink
Add checkstyle format
Browse files Browse the repository at this point in the history
  • Loading branch information
wata727 committed Apr 2, 2017
1 parent db43f76 commit 9d6b745
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Please show `tflint --help`
```
-h, --help show usage of TFLint. This page.
-v, --version print version information.
-f, --format <format> choose output format from "default" or "json"
-f, --format <format> choose output format from "default", "json" or "checkstyle"
-c, --config <file> specify config file. default is ".tflint.hcl"
--ignore-module <source1,source2...> ignore module by specified source.
--ignore-rule <rule1,rule2...> ignore rules.
Expand Down
2 changes: 1 addition & 1 deletion cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (cli *CLI) Run(args []string) int {
flags.BoolVar(&help, "h", false, "alias for --help")
flags.BoolVar(&configArgs.Debug, "debug", false, "enable debug mode.")
flags.BoolVar(&configArgs.Debug, "d", false, "alias for --debug")
flags.StringVar(&format, "format", "default", "choose output format from \"default\" or \"json\"")
flags.StringVar(&format, "format", "default", "choose output format from \"default\", \"json\" or \"checkstyle\"")
flags.StringVar(&format, "f", "default", "alias for --format")
flags.StringVar(&configArgs.IgnoreModule, "ignore-module", "", "ignore module by specified source.")
flags.StringVar(&configArgs.IgnoreRule, "ignore-rule", "", "ignore rules.")
Expand Down
15 changes: 15 additions & 0 deletions cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,21 @@ func TestCLIRun(t *testing.T) {
CLIOptions: defaultCLIOptions,
},
},
{
Name: "specify checkstyle format",
Command: "./tflint --format checkstyle",
LoaderGenerator: loaderDefaultBehavior,
DetectorGenerator: detectorNoErrorNoIssuesBehavior,
PrinterGenerator: func(ctrl *gomock.Controller) printer.PrinterIF {
printer := mock.NewMockPrinterIF(ctrl)
printer.EXPECT().Print([]*issue.Issue{}, "checkstyle")
return printer
},
Result: Result{
Status: ExitCodeOK,
CLIOptions: defaultCLIOptions,
},
},
{
Name: "specify invalid format",
Command: "./tflint --format awesome",
Expand Down
2 changes: 1 addition & 1 deletion help.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Usage: tflint [<options>] <args>
Available Options:
-h, --help show usage of TFLint. This page.
-v, --version print version information.
-f, --format <format> choose output format from "default" or "json"
-f, --format <format> choose output format from "default", "json" or "checkstyle"
-c, --config <file> specify config file. default is ".tflint.hcl"
--ignore-module <source1,source2...> ignore module by specified source.
--ignore-rule <rule1,rule2...> ignore rules.
Expand Down
59 changes: 59 additions & 0 deletions printer/checkstyle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package printer

import (
"encoding/xml"
"fmt"

"sort"

"github.com/wata727/tflint/issue"
)

type Error struct {
Line int `xml:"line,attr"`
Severity string `xml:"severity,attr"`
Message string `xml:"message,attr"`
}

type File struct {
Name string `xml:"name,attr"`
Errors []Error `xml:"error"`
}

type Checkstyle struct {
XMLName xml.Name `xml:"checkstyle"`
Files []File `xml:"file"`
}

func (p *Printer) CheckstylePrint(issues []*issue.Issue) {
sort.Sort(issue.ByFile{Issues: issue.Issues(issues)})

v := &Checkstyle{}

for _, i := range issues {
if len(v.Files) == 0 || v.Files[len(v.Files)-1].Name != i.File {
v.Files = append(v.Files, File{Name: i.File})
}
v.Files[len(v.Files)-1].Errors = append(v.Files[len(v.Files)-1].Errors, Error{Line: i.Line, Severity: toSeverity(i.Type), Message: i.Message})
}

result, err := xml.MarshalIndent(v, "", " ")
if err != nil {
fmt.Fprint(p.stderr, err)
}
fmt.Fprint(p.stdout, xml.Header)
fmt.Fprint(p.stdout, string(result))
}

func toSeverity(lintType string) string {
switch lintType {
case issue.ERROR:
return "error"
case issue.WARNING:
return "warning"
case issue.NOTICE:
return "info"
default:
return "unknown"
}
}
69 changes: 69 additions & 0 deletions printer/checkstyle_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package printer

import (
"testing"

"bytes"

"github.com/wata727/tflint/issue"
)

func TestCheckstylePrint(t *testing.T) {
cases := []struct {
Name string
Input []*issue.Issue
Result string
}{
{
Name: "no issues",
Input: []*issue.Issue{},
Result: `<?xml version="1.0" encoding="UTF-8"?>
<checkstyle></checkstyle>`,
},
{
Name: "multi files",
Input: []*issue.Issue{
{
File: "template.tf",
Line: 1,
Type: "ERROR",
Message: "example error message",
},
{
File: "application.tf",
Line: 10,
Type: "NOTICE",
Message: "example notice message",
},
{
File: "template.tf",
Line: 3,
Type: "WARNING",
Message: "example warning message",
},
},
Result: `<?xml version="1.0" encoding="UTF-8"?>
<checkstyle>
<file name="application.tf">
<error line="10" severity="info" message="example notice message"></error>
</file>
<file name="template.tf">
<error line="1" severity="error" message="example error message"></error>
<error line="3" severity="warning" message="example warning message"></error>
</file>
</checkstyle>`,
},
}

for _, tc := range cases {
stdout := &bytes.Buffer{}
stderr := &bytes.Buffer{}
p := NewPrinter(stdout, stderr)
p.CheckstylePrint(tc.Input)
result := stdout.String()

if result != tc.Result {
t.Fatalf("\nBad: %t\nExpected: %t\n\ntestcase: %s", result, tc.Result, tc.Name)
}
}
}
7 changes: 5 additions & 2 deletions printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ type Printer struct {
}

var validFormat = map[string]bool{
"default": true,
"json": true,
"default": true,
"json": true,
"checkstyle": true,
}

func NewPrinter(stdout io.Writer, stderr io.Writer) *Printer {
Expand All @@ -37,6 +38,8 @@ func (p *Printer) Print(issues []*issue.Issue, format string) {
p.DefaultPrint(issues)
case "json":
p.JSONPrint(issues)
case "checkstyle":
p.CheckstylePrint(issues)
default:
p.DefaultPrint(issues)
}
Expand Down
5 changes: 5 additions & 0 deletions printer/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ func TestValidateFormat(t *testing.T) {
Input: "json",
Result: true,
},
{
Name: "checkstyle is valid format",
Input: "checkstyle",
Result: true,
},
{
Name: "yaml is invalid format",
Input: "yaml",
Expand Down

0 comments on commit 9d6b745

Please sign in to comment.