use cobra for CLI
This commit is contained in:
parent
0e4998bb4f
commit
c17b41c59a
135
Gopkg.lock
generated
135
Gopkg.lock
generated
@ -25,6 +25,18 @@
|
||||
packages = ["."]
|
||||
revision = "88b7bfd34643dce0c28a6b797652d6b5026091af"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fatih/color"
|
||||
packages = ["."]
|
||||
revision = "507f6050b8568533fb3f5504de8e5205fa62a114"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fsnotify/fsnotify"
|
||||
packages = ["."]
|
||||
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
|
||||
version = "v1.4.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-ole/go-ole"
|
||||
packages = [
|
||||
@ -57,6 +69,65 @@
|
||||
]
|
||||
revision = "044f3332f2e8c38cfbb56bab29f65b4245bbe76b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/hcl"
|
||||
packages = [
|
||||
".",
|
||||
"hcl/ast",
|
||||
"hcl/parser",
|
||||
"hcl/printer",
|
||||
"hcl/scanner",
|
||||
"hcl/strconv",
|
||||
"hcl/token",
|
||||
"json/parser",
|
||||
"json/scanner",
|
||||
"json/token"
|
||||
]
|
||||
revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/inconshreveable/mousetrap"
|
||||
packages = ["."]
|
||||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/magiconair/properties"
|
||||
packages = ["."]
|
||||
revision = "c3beff4c2358b44d0493c7dda585e7db7ff28ae6"
|
||||
version = "v1.7.6"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/go-homedir"
|
||||
packages = ["."]
|
||||
revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
packages = ["."]
|
||||
revision = "00c29f56e2386353d58c599509e8dc3801b0d716"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pelletier/go-toml"
|
||||
packages = ["."]
|
||||
revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
@ -94,6 +165,49 @@
|
||||
revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc"
|
||||
version = "v1.0.5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/afero"
|
||||
packages = [
|
||||
".",
|
||||
"mem"
|
||||
]
|
||||
revision = "63644898a8da0bc22138abf860edaf5277b6102e"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/cast"
|
||||
packages = ["."]
|
||||
revision = "8965335b8c7107321228e3e3702cab9832751bac"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = [
|
||||
".",
|
||||
"cobra",
|
||||
"cobra/cmd"
|
||||
]
|
||||
revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4"
|
||||
version = "v0.0.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/jwalterweatherman"
|
||||
packages = ["."]
|
||||
revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/viper"
|
||||
packages = ["."]
|
||||
revision = "b5e8006cbee93ec955a89ab31e0e3ce3204f3736"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = ["assert"]
|
||||
@ -130,6 +244,25 @@
|
||||
]
|
||||
revision = "6f686a352de66814cdd080d970febae7767857a3"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"internal/gen",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"transform",
|
||||
"unicode/cldr",
|
||||
"unicode/norm"
|
||||
]
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "sourcegraph.com/sourcegraph/go-diff"
|
||||
@ -145,6 +278,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "fc3abded9121a32e3fc9de887b9f1dd7a4d64ee58e169053e9120881d6c54658"
|
||||
inputs-digest = "e734f3b5571fe0e9119d20d9e9a7f8ee2b2f316686cf194307a3e5fb3327c85b"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
@ -1,43 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
"github.com/golangci/golangci-lint/pkg/golinters"
|
||||
"github.com/golangci/golangci-shared/pkg/executors"
|
||||
"github.com/golangci/golangci-lint/internal/commands"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.SetFlags(0) // don't print time
|
||||
|
||||
e := commands.NewExecutor()
|
||||
if err := e.Execute(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
var cfg config.Config
|
||||
config.ReadFromCommandLine(&cfg)
|
||||
|
||||
linters := golinters.GetSupportedLinters()
|
||||
ctx := context.Background()
|
||||
|
||||
ex, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exPath := filepath.Dir(ex)
|
||||
exec := executors.NewShell(exPath)
|
||||
|
||||
for _, linter := range linters {
|
||||
res, err := linter.Run(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Print(res)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
27
internal/commands/executor.go
Normal file
27
internal/commands/executor.go
Normal file
@ -0,0 +1,27 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type Executor struct {
|
||||
rootCmd *cobra.Command
|
||||
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
func NewExecutor() *Executor {
|
||||
e := &Executor{
|
||||
cfg: config.NewDefault(),
|
||||
}
|
||||
|
||||
e.initRoot()
|
||||
e.initRun()
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func (e Executor) Execute() error {
|
||||
return e.rootCmd.Execute()
|
||||
}
|
18
internal/commands/root.go
Normal file
18
internal/commands/root.go
Normal file
@ -0,0 +1,18 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func (e *Executor) initRoot() {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "golangci-lint",
|
||||
Short: "golangci-lint is a smart linters runner.",
|
||||
Long: `Smart, fast linters runner. Run it in cloud for every GitHub pull request on https://golangci.com`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_ = cmd.Help()
|
||||
},
|
||||
}
|
||||
rootCmd.PersistentFlags().BoolVarP(&e.cfg.Common.IsVerbose, "verbose", "v", false, "verbose output")
|
||||
e.rootCmd = rootCmd
|
||||
}
|
92
internal/commands/run.go
Normal file
92
internal/commands/run.go
Normal file
@ -0,0 +1,92 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
"github.com/golangci/golangci-lint/pkg/golinters"
|
||||
"github.com/golangci/golangci-lint/pkg/result"
|
||||
"github.com/golangci/golangci-shared/pkg/executors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func (e *Executor) initRun() {
|
||||
var runCmd = &cobra.Command{
|
||||
Use: "run",
|
||||
Short: "Run linters",
|
||||
Run: e.executeRun,
|
||||
}
|
||||
e.rootCmd.AddCommand(runCmd)
|
||||
|
||||
runCmd.Flags().StringVarP(&e.cfg.Run.OutFormat, "out-format", "",
|
||||
config.OutFormatColoredLineNumber,
|
||||
fmt.Sprintf("Format of output: %s", strings.Join(config.OutFormats, "|")))
|
||||
}
|
||||
|
||||
func (e Executor) executeRun(cmd *cobra.Command, args []string) {
|
||||
f := func() error {
|
||||
linters := golinters.GetSupportedLinters()
|
||||
ctx := context.Background()
|
||||
|
||||
ex, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exPath := filepath.Dir(ex)
|
||||
exec := executors.NewShell(exPath)
|
||||
|
||||
issues := []result.Issue{}
|
||||
for _, linter := range linters {
|
||||
res, err := linter.Run(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
issues = append(issues, res.Issues...)
|
||||
}
|
||||
|
||||
if err = outputIssues(e.cfg.Run.OutFormat, issues); err != nil {
|
||||
return fmt.Errorf("can't output %d issues: %s", len(issues), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := f(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func outputIssues(format string, issues []result.Issue) error {
|
||||
if format == config.OutFormatLineNumber || format == config.OutFormatColoredLineNumber {
|
||||
if len(issues) == 0 {
|
||||
outStr := "Congrats! No issues were found."
|
||||
if format == config.OutFormatColoredLineNumber {
|
||||
outStr = color.GreenString(outStr)
|
||||
}
|
||||
log.Print(outStr)
|
||||
}
|
||||
|
||||
for _, i := range issues {
|
||||
log.Printf("%s:%d: %s", i.File, i.LineNumber, i.Text)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if format == config.OutFormatJSON {
|
||||
outputJSON, err := json.Marshal(issues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Print(string(outputJSON))
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("unknown output format %q", format)
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package config
|
||||
|
||||
import "flag"
|
||||
|
||||
func ReadFromCommandLine(cfg *Config) {
|
||||
flag.Parse()
|
||||
paths := flag.Args()
|
||||
if len(paths) != 0 {
|
||||
cfg.Paths = paths
|
||||
}
|
||||
}
|
@ -1,5 +1,34 @@
|
||||
package config
|
||||
|
||||
type Config struct {
|
||||
Paths []string
|
||||
type OutFormat string
|
||||
|
||||
const (
|
||||
OutFormatJSON = "json"
|
||||
OutFormatLineNumber = "line-number"
|
||||
OutFormatColoredLineNumber = "colored-line-number"
|
||||
)
|
||||
|
||||
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON}
|
||||
|
||||
type Common struct {
|
||||
IsVerbose bool
|
||||
}
|
||||
|
||||
type Run struct {
|
||||
Paths []string
|
||||
OutFormat string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Common Common
|
||||
Run Run
|
||||
}
|
||||
|
||||
func NewDefault() *Config {
|
||||
return &Config{
|
||||
Run: Run{
|
||||
Paths: []string{"./..."},
|
||||
OutFormat: OutFormatColoredLineNumber,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package golinters
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
@ -38,7 +37,6 @@ func processPaths(root string, paths []string, maxPaths int) ([]string, error) {
|
||||
func getPathsForGoProject(root string) (*ProjectPaths, error) {
|
||||
excludeDirs := []string{"vendor", "testdata", "examples", "Godeps"}
|
||||
pr := fsutils.NewPathResolver(excludeDirs, []string{".go"})
|
||||
log.Printf("root is %q, paths are %q", root, path.Join(root, "..."))
|
||||
paths, err := pr.Resolve(path.Join(root, "..."))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't resolve paths: %s", err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user