From 0e5d546bf029cb37f7437b2365a4535a543661bb Mon Sep 17 00:00:00 2001 From: Sven Greb Date: Tue, 24 Nov 2020 15:48:12 +0100 Subject: [PATCH] Spell incantation for "github.com/golangci/golangci-lint" Go module The "github.com/golangci/golangci-lint" [1] Go module provides the `golangci-lint` commands, a fast, parallel runner for dozens of Go linters Go that uses caching, supports YAML configurations and has integrations with all major IDEs. The source code for the `golangci-lint` command can be found in the "golangci/golangci-lint" [2] GitHub repository. To configure and run the `golangci-lint` command, a new `spell.Incantation` [3] has been implemented in the new "golangcilint" [4] package that can be casted using the "gobin" caster [5] or any other spell caster [6] that handles spell incantations [3] of kind `KindGoModule` [7]. The spell incantation is customizable through the following functions: - `WithArgs(args ...string) golangcilint.Option` - sets additional arguments to pass to the `golangci-lint` module command. - `WithEnv(env map[string]string) golangcilint.Option` - sets the spell incantation specific environment. - `WithModulePath(path string) golangcilint.Option` - sets the `golangci-lint` module command import path. Defaults to `golangcilint.DefaultGoModulePath`. - `WithModuleVersion(version *semver.Version) golangcilint.Option` - sets the `golangci-lint` module version. Defaults to `golangcilint.DefaultGoModuleVersion`. - `WithVerboseOutput(verbose bool) golangcilint.Option` - indicates whether the output should be verbose. [1]: https://pkg.go.dev/github.com/golangci/golangci-lint [2]: https://github.com/golangci/golangci-lint/tree/master/cmd/golangci-lint [3]: https://pkg.go.dev/github.com/svengreb/wand/pkg/spell#Incantation [4]: https://pkg.go.dev/github.com/svengreb/wand/pkg/spell/golangcilint [5]: https://pkg.go.dev/github.com/svengreb/wand/pkg/cast/gobin#Caster [6]: https://pkg.go.dev/github.com/svengreb/wand/pkg/cast#Caster [7]: https://pkg.go.dev/github.com/svengreb/wand/pkg/spell#KindGoModule GH-33 --- pkg/cast/gobin/gobin.go | 6 +- pkg/spell/goimports/goimports.go | 6 +- pkg/spell/goimports/options.go | 13 ++- pkg/spell/golangcilint/golangcilint.go | 57 +++++++++++++ pkg/spell/golangcilint/options.go | 113 +++++++++++++++++++++++++ 5 files changed, 181 insertions(+), 14 deletions(-) create mode 100644 pkg/spell/golangcilint/golangcilint.go create mode 100644 pkg/spell/golangcilint/options.go diff --git a/pkg/cast/gobin/gobin.go b/pkg/cast/gobin/gobin.go index 8eda65e..09c002d 100644 --- a/pkg/cast/gobin/gobin.go +++ b/pkg/cast/gobin/gobin.go @@ -1,8 +1,10 @@ // Copyright (c) 2019-present Sven Greb // This source code is licensed under the MIT license found in the LICENSE file. -// Package gobin provides a caster to install and run Go module executables using the "github.com/myitcv/gobin" module. -// See https://github.com/myitcv/gobin for more details about "gobin". +// Package gobin provides a caster to install and run Go module executables using the "github.com/myitcv/gobin" module +// command. +// See https://pkg.go.dev/github.com/myitcv/gobin for more details about "gobin". +// The source code of the "gobin" is available at https://github.com/myitcv/gobin. // // Go Executable Installation // diff --git a/pkg/spell/goimports/goimports.go b/pkg/spell/goimports/goimports.go index 4a2d876..587bfbe 100644 --- a/pkg/spell/goimports/goimports.go +++ b/pkg/spell/goimports/goimports.go @@ -1,7 +1,7 @@ // Copyright (c) 2019-present Sven Greb // This source code is licensed under the MIT license found in the LICENSE file. -// Package goimports provides a spell incantation for the "golang.org/x/tools/cmd/goimports" Go module. +// Package goimports provides a spell incantation for the "golang.org/x/tools/cmd/goimports" Go module command. // See https://pkg.go.dev/golang.org/x/tools/cmd/goimports for more details about "goimports". // The source code of "goimports" is available at https://github.com/golang/tools/tree/master/cmd/goimports. package goimports @@ -16,15 +16,13 @@ import ( "github.com/svengreb/wand/pkg/spell" ) -// Spell is a spell incantation for the "golang.org/x/tools/cmd/goimports" Go module. +// Spell is a spell incantation for the "golang.org/x/tools/cmd/goimports" Go module command. type Spell struct { ac app.Config opts *Options } // Formula returns the spell incantation formula. -// See `goimports help environment`, `go help env` and the `go` command documentations for more details: -// - https://golang.org/cmd/go/#hdr-Environment_variables func (s *Spell) Formula() []string { var args []string diff --git a/pkg/spell/goimports/options.go b/pkg/spell/goimports/options.go index ef4a665..912fddb 100644 --- a/pkg/spell/goimports/options.go +++ b/pkg/spell/goimports/options.go @@ -13,14 +13,14 @@ import ( ) const ( - // DefaultGoModulePath is the default "goimports" module import path. + // DefaultGoModulePath is the default "goimports" module command import path. DefaultGoModulePath = "golang.org/x/tools/cmd/goimports" // DefaultGoModuleVersion is the default "goimports" module version. DefaultGoModuleVersion = "latest" ) -// Options are spell incantation options for the "golang.org/x/tools/cmd/goimports" Go module. +// Options are spell incantation options for the "golang.org/x/tools/cmd/goimports" Go module command. type Options struct { // env are spell incantation specific environment variables. env map[string]string @@ -52,7 +52,7 @@ type Options struct { verbose bool } -// Option is a spell incantation option for the "golang.org/x/tools/cmd/goimports" Go module. +// Option is a spell incantation option for the "golang.org/x/tools/cmd/goimports" Go module command. type Option func(*Options) // WithEnv sets the spell incantation specific environment. @@ -62,7 +62,7 @@ func WithEnv(env map[string]string) Option { } } -// WithExtraArgs sets additional arguments to pass to the "goimports" command. +// WithExtraArgs sets additional arguments to pass to the "goimports" module command. func WithExtraArgs(extraArgs ...string) Option { return func(o *Options) { o.extraArgs = append(o.extraArgs, extraArgs...) @@ -132,7 +132,7 @@ func WithVerboseOutput(verbose bool) Option { } } -// newOptions creates new "golang.org/x/tools/cmd/goimports" Go module spell incantation options. +// newOptions creates new spell incantation options for the "golang.org/x/tools/cmd/goimports" Go module command. func newOptions(opts ...Option) (*Options, error) { version, versionErr := semver.NewVersion(DefaultGoModuleVersion) if versionErr != nil { @@ -148,9 +148,6 @@ func newOptions(opts ...Option) (*Options, error) { Version: version, IsLatest: true, }, - listNonCompliantFiles: true, - persistChanges: true, - reportAllErrors: true, } for _, o := range opts { o(opt) diff --git a/pkg/spell/golangcilint/golangcilint.go b/pkg/spell/golangcilint/golangcilint.go new file mode 100644 index 0000000..a0d4782 --- /dev/null +++ b/pkg/spell/golangcilint/golangcilint.go @@ -0,0 +1,57 @@ +// Copyright (c) 2019-present Sven Greb +// This source code is licensed under the MIT license found in the LICENSE file. + +// Package golangcilint provides a spell incantation for the "github.com/golangci/golangci-lint/cmd/golangci-lint" Go +// module command. +// See https://pkg.go.dev/github.com/golangci/golangci-lint for more details about "golangci-lint". +// The source code of the "golangci-lint" is available at https://github.com/golangci/golangci-lint. +package golangcilint + +import ( + "github.com/svengreb/wand" + "github.com/svengreb/wand/pkg/app" + "github.com/svengreb/wand/pkg/project" + "github.com/svengreb/wand/pkg/spell" +) + +// Spell is a spell incantation for the "github.com/golangci/golangci-lint/cmd/golangci-lint" Go module command. +// If not extra arguments are configured, DefaultArgs are passed to the executable. +type Spell struct { + ac app.Config + opts *Options +} + +// Formula returns the spell incantation formula. +func (s *Spell) Formula() []string { + return s.opts.args +} + +// Kind returns the spell incantation kind. +func (s *Spell) Kind() spell.Kind { + return spell.KindGoModule +} + +// Options returns the spell incantation options. +func (s *Spell) Options() interface{} { + return *s.opts +} + +// GoModuleID returns partial Go module identifier information. +func (s *Spell) GoModuleID() *project.GoModuleID { + return s.opts.goModule +} + +// Env returns spell incantation specific environment variables. +func (s *Spell) Env() map[string]string { + return s.opts.env +} + +// New creates a new spell incantation for the "build" command of the Go toolchain. +//nolint:gocritic // The app.Config struct is passed as value by design to ensure immutability. +func New(wand wand.Wand, ac app.Config, opts ...Option) (*Spell, error) { + opt, optErr := newOptions(opts...) + if optErr != nil { + return nil, optErr + } + return &Spell{ac: ac, opts: opt}, nil +} diff --git a/pkg/spell/golangcilint/options.go b/pkg/spell/golangcilint/options.go new file mode 100644 index 0000000..45d0230 --- /dev/null +++ b/pkg/spell/golangcilint/options.go @@ -0,0 +1,113 @@ +// Copyright (c) 2019-present Sven Greb +// This source code is licensed under the MIT license found in the LICENSE file. + +package golangcilint + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + + "github.com/svengreb/wand/pkg/cast" + "github.com/svengreb/wand/pkg/project" +) + +const ( + // DefaultGoModulePath is the default "goimports" module command import path. + DefaultGoModulePath = "github.com/golangci/golangci-lint/cmd/golangci-lint" + + // DefaultGoModuleVersion is the default "goimports" module version. + DefaultGoModuleVersion = "v1.32.0" +) + +// DefaultArgs are the default arguments to pass to the "golangci-lint" command. +var DefaultArgs = []string{"run"} + +// Options are spell incantation options for the "github.com/golangci/golangci-lint/cmd/golangci-lint" Go module +// command. +type Options struct { + // args are arguments to pass to the "golangci-lint" command. + args []string + + // env are spell incantation specific environment variables. + env map[string]string + + // goModule are partial Go module identifier information. + goModule *project.GoModuleID + + // verbose indicates whether the output should be verbose. + verbose bool +} + +// Option is a spell incantation option for the "github.com/golangci/golangci-lint/cmd/golangci-lint" Go module command. +type Option func(*Options) + +// WithArgs sets additional arguments to pass to the "golangci-lint" module command. +// By default DefaultArgs are passed. +func WithArgs(args ...string) Option { + return func(o *Options) { + o.args = append(o.args, args...) + } +} + +// WithEnv sets the spell incantation specific environment. +func WithEnv(env map[string]string) Option { + return func(o *Options) { + o.env = env + } +} + +// WithModulePath sets the "golangci-lint" module command import path. +// Defaults to DefaultGoModulePath. +func WithModulePath(path string) Option { + return func(o *Options) { + if path != "" { + o.goModule.Path = path + } + } +} + +// WithModuleVersion sets the "golangci-lint" module version. +// Defaults to DefaultGoModuleVersion. +func WithModuleVersion(version *semver.Version) Option { + return func(o *Options) { + if version != nil { + o.goModule.Version = version + } + } +} + +// WithVerboseOutput indicates whether the output should be verbose. +func WithVerboseOutput(verbose bool) Option { + return func(o *Options) { + o.verbose = verbose + } +} + +// newOptions creates new spell incantation options for the "github.com/golangci/golangci-lint/cmd/golangci-lint" Go +// module command. +func newOptions(opts ...Option) (*Options, error) { + version, versionErr := semver.NewVersion(DefaultGoModuleVersion) + if versionErr != nil { + return nil, &cast.ErrCast{ + Err: fmt.Errorf("parsing default module version %q: %w", DefaultGoModulePath, versionErr), + Kind: cast.ErrCasterInvalidOpts, + } + } + opt := &Options{ + env: make(map[string]string), + goModule: &project.GoModuleID{ + Path: DefaultGoModulePath, + Version: version, + }, + } + for _, o := range opts { + o(opt) + } + + if len(opt.args) == 0 { + opt.args = append(opt.args, DefaultArgs...) + } + + return opt, nil +}