aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mgechev/revive/formatter/friendly.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mgechev/revive/formatter/friendly.go')
-rw-r--r--vendor/github.com/mgechev/revive/formatter/friendly.go146
1 files changed, 146 insertions, 0 deletions
diff --git a/vendor/github.com/mgechev/revive/formatter/friendly.go b/vendor/github.com/mgechev/revive/formatter/friendly.go
new file mode 100644
index 0000000000..a543eebe00
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/formatter/friendly.go
@@ -0,0 +1,146 @@
+package formatter
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+
+ "github.com/fatih/color"
+ "github.com/mgechev/revive/lint"
+ "github.com/olekukonko/tablewriter"
+)
+
+var (
+ errorEmoji = color.RedString("✘")
+ warningEmoji = color.YellowString("⚠")
+)
+
+var newLines = map[rune]bool{
+ 0x000A: true,
+ 0x000B: true,
+ 0x000C: true,
+ 0x000D: true,
+ 0x0085: true,
+ 0x2028: true,
+ 0x2029: true,
+}
+
+// Friendly is an implementation of the Formatter interface
+// which formats the errors to JSON.
+type Friendly struct {
+ Metadata lint.FormatterMetadata
+}
+
+// Name returns the name of the formatter
+func (f *Friendly) Name() string {
+ return "friendly"
+}
+
+// Format formats the failures gotten from the lint.
+func (f *Friendly) Format(failures <-chan lint.Failure, config lint.Config) (string, error) {
+ errorMap := map[string]int{}
+ warningMap := map[string]int{}
+ totalErrors := 0
+ totalWarnings := 0
+ for failure := range failures {
+ sev := severity(config, failure)
+ f.printFriendlyFailure(failure, sev)
+ if sev == lint.SeverityWarning {
+ warningMap[failure.RuleName] = warningMap[failure.RuleName] + 1
+ totalWarnings++
+ }
+ if sev == lint.SeverityError {
+ errorMap[failure.RuleName] = errorMap[failure.RuleName] + 1
+ totalErrors++
+ }
+ }
+ f.printSummary(totalErrors, totalWarnings)
+ f.printStatistics(color.RedString("Errors:"), errorMap)
+ f.printStatistics(color.YellowString("Warnings:"), warningMap)
+ return "", nil
+}
+
+func (f *Friendly) printFriendlyFailure(failure lint.Failure, severity lint.Severity) {
+ f.printHeaderRow(failure, severity)
+ f.printFilePosition(failure)
+ fmt.Println()
+ fmt.Println()
+}
+
+func (f *Friendly) printHeaderRow(failure lint.Failure, severity lint.Severity) {
+ emoji := warningEmoji
+ if severity == lint.SeverityError {
+ emoji = errorEmoji
+ }
+ fmt.Print(f.table([][]string{{emoji, "https://revive.run/r#" + failure.RuleName, color.GreenString(failure.Failure)}}))
+}
+
+func (f *Friendly) printFilePosition(failure lint.Failure) {
+ fmt.Printf(" %s:%d:%d", failure.GetFilename(), failure.Position.Start.Line, failure.Position.Start.Column)
+}
+
+type statEntry struct {
+ name string
+ failures int
+}
+
+func (f *Friendly) printSummary(errors, warnings int) {
+ emoji := warningEmoji
+ if errors > 0 {
+ emoji = errorEmoji
+ }
+ problemsLabel := "problems"
+ if errors+warnings == 1 {
+ problemsLabel = "problem"
+ }
+ warningsLabel := "warnings"
+ if warnings == 1 {
+ warningsLabel = "warning"
+ }
+ errorsLabel := "errors"
+ if errors == 1 {
+ errorsLabel = "error"
+ }
+ str := fmt.Sprintf("%d %s (%d %s, %d %s)", errors+warnings, problemsLabel, errors, errorsLabel, warnings, warningsLabel)
+ if errors > 0 {
+ fmt.Printf("%s %s\n", emoji, color.RedString(str))
+ fmt.Println()
+ return
+ }
+ if warnings > 0 {
+ fmt.Printf("%s %s\n", emoji, color.YellowString(str))
+ fmt.Println()
+ return
+ }
+}
+
+func (f *Friendly) printStatistics(header string, stats map[string]int) {
+ if len(stats) == 0 {
+ return
+ }
+ var data []statEntry
+ for name, total := range stats {
+ data = append(data, statEntry{name, total})
+ }
+ sort.Slice(data, func(i, j int) bool {
+ return data[i].failures > data[j].failures
+ })
+ formatted := [][]string{}
+ for _, entry := range data {
+ formatted = append(formatted, []string{color.GreenString(fmt.Sprintf("%d", entry.failures)), entry.name})
+ }
+ fmt.Println(header)
+ fmt.Println(f.table(formatted))
+}
+
+func (f *Friendly) table(rows [][]string) string {
+ buf := new(bytes.Buffer)
+ table := tablewriter.NewWriter(buf)
+ table.SetBorder(false)
+ table.SetColumnSeparator("")
+ table.SetRowSeparator("")
+ table.SetAutoWrapText(false)
+ table.AppendBulk(rows)
+ table.Render()
+ return buf.String()
+}