diff --git a/README.md b/README.md index 04fc9b0..8dd093b 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Flags: -min minimum value, only works with -numbers -max maximum value, only works with -numbers -output output formatting (text or json) + -set-exit-status Set exit status to 2 if any issues are found Examples: diff --git a/cmd/goconst/main.go b/cmd/goconst/main.go index a06515d..d55e38b 100644 --- a/cmd/goconst/main.go +++ b/cmd/goconst/main.go @@ -30,6 +30,7 @@ Flags: -min minimum value, only works with -numbers -max maximum value, only works with -numbers -output output formatting (text or json) + -set-exit-status Set exit status to 2 if any issues are found Examples: @@ -49,6 +50,7 @@ var ( flagMin = flag.Int("min", 0, "minimum value, only works with -numbers") flagMax = flag.Int("max", 0, "maximum value, only works with -numbers") flagOutput = flag.String("output", "text", "output formatting") + flagSetExitStatus = flag.Bool("set-exit-status", false, "Set exit status to 2 if any issues are found") ) func main() { @@ -63,15 +65,26 @@ func main() { usage(os.Stderr) os.Exit(1) } + + lintFailed := false for _, path := range args { - if err := run(path); err != nil { + anyIssues, err := run(path) + if err != nil { log.Println(err) os.Exit(1) } + + if anyIssues { + lintFailed = true + } + } + + if lintFailed && *flagSetExitStatus { + os.Exit(2) } } -func run(path string) error { +func run(path string) (bool, error) { gco := goconst.New( path, *flagIgnore, @@ -82,7 +95,7 @@ func run(path string) error { ) strs, consts, err := gco.ParseTree() if err != nil { - return err + return false, err } return printOutput(strs, consts, *flagOutput, *flagMinOccurrences, *flagMin, *flagMax) @@ -92,7 +105,7 @@ func usage(out io.Writer) { fmt.Fprintf(out, usageDoc) } -func printOutput(strs goconst.Strings, consts goconst.Constants, output string, minOccurrences, min, max int) error { +func printOutput(strs goconst.Strings, consts goconst.Constants, output string, minOccurrences, min, max int) (bool, error) { for str, item := range strs { // Filter out items whose occurrences don't match the min value if len(item) < minOccurrences { @@ -120,7 +133,7 @@ func printOutput(strs goconst.Strings, consts goconst.Constants, output string, strs, consts, }) if err != nil { - return err + return false, err } case "text": for str, item := range strs { @@ -147,9 +160,9 @@ func printOutput(strs goconst.Strings, consts goconst.Constants, output string, } } default: - return fmt.Errorf(`Unsupported output format: %s`, output) + return false, fmt.Errorf(`Unsupported output format: %s`, output) } - return nil + return len(strs) + len(consts) > 0, nil } func occurrences(item []goconst.ExtendedPos, current goconst.ExtendedPos) string { diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..53dbfbb --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/jgautheron/goconst + +go 1.13 diff --git a/tests/foo_test.go b/tests/foo_test.go new file mode 100644 index 0000000..96395f1 --- /dev/null +++ b/tests/foo_test.go @@ -0,0 +1,9 @@ +package main + +import "fmt" + +func foo() { + foo := "test" + boo := "test" + fmt.Println(foo, boo) +} diff --git a/tests/main.go b/tests/main.go new file mode 100644 index 0000000..227ab61 --- /dev/null +++ b/tests/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "strings" +) + +const Foo = "bar" + +var url string + +func main() { + if strings.HasPrefix(url, "http://") { + url = strings.TrimPrefix(url, "http://") + } + url = strings.TrimPrefix(url, "/") + fmt.Println(url) +} + +func testCase() string { + test := `test` + if url == "test" { + return test + } + switch url { + case "moo": + return "" + } + return "foo" +} diff --git a/visitor.go b/visitor.go index a86421f..27cd5d8 100644 --- a/visitor.go +++ b/visitor.go @@ -95,6 +95,15 @@ func (v *treeVisitor) Visit(node ast.Node) ast.Visitor { v.addString(lit.Value, lit.Pos()) } } + + // fn("http://") + case *ast.CallExpr: + for _, item := range t.Args { + lit, ok := item.(*ast.BasicLit) + if ok && v.isSupported(lit.Kind) { + v.addString(lit.Value, lit.Pos()) + } + } } return v @@ -102,7 +111,8 @@ func (v *treeVisitor) Visit(node ast.Node) ast.Visitor { // addString adds a string in the map along with its position in the tree. func (v *treeVisitor) addString(str string, pos token.Pos) { - str = strings.Replace(str, `"`, "", 2) + // Drop first and last character, quote, backquote... + str = str[1 : len(str)-1] // Ignore empty strings if len(str) == 0 {