diff --git a/Makefile b/Makefile index 591f5c8d3..a9638e16f 100644 --- a/Makefile +++ b/Makefile @@ -117,39 +117,66 @@ gomplate.png: gomplate.svg cloudconvert -f png -c density=288 $^ lint: - gometalinter --vendor --disable-all \ - --enable=gosec \ - --enable=goconst \ - --enable=gocyclo \ - --enable=golint \ - --enable=gotypex \ - --enable=ineffassign \ - --enable=vet \ - --enable=vetshadow \ - --enable=misspell \ - --enable=goimports \ - --enable=gofmt \ - ./... - gometalinter --vendor --skip tests --disable-all \ - --enable=deadcode \ - ./... - -slow-lint: - gometalinter -j $(LINT_PROCS) --vendor --skip tests --deadline 120s \ - --disable gotype \ + golangci-lint run --disable-all \ + --enable depguard \ + --enable dupl \ + --enable goconst \ + --enable gocritic \ + --enable gocyclo \ --enable gofmt \ --enable goimports \ + --enable golint \ + --enable gosec \ + --enable gosimple \ + --enable govet \ + --enable ineffassign \ + --enable maligned \ --enable misspell \ - ./... - gometalinter -j $(LINT_PROCS) --vendor --deadline 120s \ - --disable gotype \ - --disable megacheck \ - --disable deadcode \ + --enable nakedret \ + --enable prealloc \ + --enable staticcheck \ + --enable structcheck \ + --enable stylecheck \ + --enable typecheck \ + --enable unconvert \ + --enable varcheck + + golangci-lint run --tests false --disable-all \ + --enable deadcode \ + --enable errcheck \ + --enable interfacer \ + --enable scopelint \ + --enable unused + + golangci-lint run --build-tags integration \ + --disable-all \ + --enable deadcode \ + --enable depguard \ + --enable dupl \ + --enable gochecknoinits \ + --enable gocritic \ + --enable gocyclo \ --enable gofmt \ --enable goimports \ + --enable golint \ + --enable gosec \ + --enable gosimple \ + --enable govet \ + --enable ineffassign \ + --enable maligned \ --enable misspell \ + --enable nakedret \ + --enable prealloc \ + --enable scopelint \ + --enable staticcheck \ + --enable structcheck \ + --enable stylecheck \ + --enable typecheck \ + --enable unconvert \ + --enable unparam \ + --enable unused \ + --enable varcheck \ ./tests/integration - megacheck -tags integration ./tests/integration .PHONY: gen-changelog clean test build-x compress-all build-release build test-integration-docker gen-docs lint clean-images clean-containers docker-images .DELETE_ON_ERROR: diff --git a/aws/kms.go b/aws/kms.go index cd3484812..ed616c42f 100644 --- a/aws/kms.go +++ b/aws/kms.go @@ -50,7 +50,7 @@ func (k *KMS) Decrypt(ciphertext string) (string, error) { return "", err } input := &kms.DecryptInput{ - CiphertextBlob: []byte(ciphertextBlob), + CiphertextBlob: ciphertextBlob, } output, err := k.Client.Decrypt(input) if err != nil { diff --git a/cmd/gomplate/main.go b/cmd/gomplate/main.go index 3c125c7dd..aa6692a39 100644 --- a/cmd/gomplate/main.go +++ b/cmd/gomplate/main.go @@ -30,7 +30,7 @@ func validateOpts(cmd *cobra.Command, args []string) error { } if len(opts.InputFiles) != len(opts.OutputFiles) { - return fmt.Errorf("Must provide same number of --out (%d) as --file (%d) options", len(opts.OutputFiles), len(opts.InputFiles)) + return fmt.Errorf("must provide same number of --out (%d) as --file (%d) options", len(opts.OutputFiles), len(opts.InputFiles)) } if cmd.Flag("input-dir").Changed && (cmd.Flag("in").Changed || cmd.Flag("file").Changed) { @@ -77,12 +77,10 @@ func postRunExec(cmd *cobra.Command, args []string) error { signal.Notify(sigs) go func() { // Pass signals to the sub-process - select { - case sig := <-sigs: - if c.Process != nil { - // nolint: gosec - c.Process.Signal(sig) - } + sig := <-sigs + if c.Process != nil { + // nolint: gosec + _ = c.Process.Signal(sig) } }() diff --git a/config.go b/config.go index def7dabba..b5da42c44 100644 --- a/config.go +++ b/config.go @@ -67,11 +67,12 @@ func (o *Config) String() string { o.defaults() c := "input: " - if o.Input != "" { + switch { + case o.Input != "": c += "" - } else if o.InputDir != "" { + case o.InputDir != "": c += o.InputDir - } else { + default: c += strings.Join(o.InputFiles, ", ") } @@ -80,11 +81,12 @@ func (o *Config) String() string { } c += "\noutput: " - if o.InputDir != "" && o.OutputDir != "." { + switch { + case o.InputDir != "" && o.OutputDir != ".": c += o.OutputDir - } else if o.OutputMap != "" { + case o.OutputMap != "": c += o.OutputMap - } else { + default: c += strings.Join(o.OutputFiles, ", ") } diff --git a/data/data.go b/data/data.go index 63596936b..1a0c6218d 100644 --- a/data/data.go +++ b/data/data.go @@ -139,20 +139,20 @@ func parseCSV(args ...string) ([][]string, []string, error) { func csvParseArgs(args ...string) (in, delim string, hdr []string) { delim = "," - if len(args) == 1 { + switch len(args) { + case 1: in = args[0] - } - if len(args) == 2 { + case 2: in = args[1] - if len(args[0]) == 1 { + switch len(args[0]) { + case 1: delim = args[0] - } else if len(args[0]) == 0 { + case 0: hdr = []string{} - } else { + default: hdr = strings.Split(args[0], delim) } - } - if len(args) == 3 { + case 3: delim = args[0] hdr = strings.Split(args[1], delim) in = args[2] diff --git a/data/datasource_file_test.go b/data/datasource_file_test.go index 1284113e5..ebdc4c4a0 100644 --- a/data/datasource_file_test.go +++ b/data/datasource_file_test.go @@ -59,7 +59,7 @@ func TestReadFile(t *testing.T) { source.fs = fs actual, err = readFile(source, "foo.txt") assert.NoError(t, err) - assert.Equal(t, []byte(content), actual) + assert.Equal(t, content, actual) mime, err = source.mimeType() assert.NoError(t, err) assert.Equal(t, "application/json", mime) diff --git a/data/datasource_http_test.go b/data/datasource_http_test.go index 62531241d..f35733db1 100644 --- a/data/datasource_http_test.go +++ b/data/datasource_http_test.go @@ -162,37 +162,6 @@ func TestParseHeaderArgs(t *testing.T) { assert.Equal(t, expected, parsed) } -func TestHTTPFileWithSubPath(t *testing.T) { - server, client := setupHTTP(200, "application/json; charset=utf-8", `{"hello": "world"}`) - defer server.Close() - - sources := make(map[string]*Source) - sources["foo"] = &Source{ - Alias: "foo", - URL: &url.URL{ - Scheme: "http", - Host: "example.com", - Path: "/foo", - }, - hc: client, - } - data := &Data{ - Sources: sources, - } - - expected := map[string]interface{}{ - "hello": "world", - } - - actual, err := data.Datasource("foo") - assert.NoError(t, err) - assert.Equal(t, must(marshalObj(expected, json.Marshal)), must(marshalObj(actual, json.Marshal))) - - actual, err = data.Datasource(server.URL) - assert.NoError(t, err) - assert.Equal(t, must(marshalObj(expected, json.Marshal)), must(marshalObj(actual, json.Marshal))) -} - func TestBuildURL(t *testing.T) { expected := "https://example.com/index.html" base := mustParseURL(expected) diff --git a/data/datasource_test.go b/data/datasource_test.go index 32c1219d7..ea542b100 100644 --- a/data/datasource_test.go +++ b/data/datasource_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/assert" ) +const osWindows = "windows" + func TestNewData(t *testing.T) { d, err := NewData(nil, nil) assert.NoError(t, err) @@ -63,7 +65,7 @@ func TestParseSourceWithAlias(t *testing.T) { assert.True(t, s.URL.IsAbs()) assert.Equal(t, "/otherdir/foo.json", s.URL.Path) - if runtime.GOOS == "windows" { + if runtime.GOOS == osWindows { s, err = parseSource("data=foo.json") assert.NoError(t, err) assert.Equalf(t, byte(':'), s.URL.Path[1], "Path was %s", s.URL.Path) @@ -111,7 +113,7 @@ func TestDatasource(t *testing.T) { fs := afero.NewMemMapFs() var uPath string var f afero.File - if runtime.GOOS == "windows" { + if runtime.GOOS == osWindows { _ = fs.Mkdir("C:\\tmp", 0777) f, _ = fs.Create("C:\\tmp\\" + fname) _, _ = f.Write(contents) @@ -158,7 +160,7 @@ func TestDatasourceReachable(t *testing.T) { fs := afero.NewMemMapFs() var uPath string var f afero.File - if runtime.GOOS == "windows" { + if runtime.GOOS == osWindows { _ = fs.Mkdir("C:\\tmp", 0777) f, _ = fs.Create("C:\\tmp\\" + fname) uPath = "C:/tmp/" + fname @@ -205,7 +207,7 @@ func TestInclude(t *testing.T) { var uPath string var f afero.File - if runtime.GOOS == "windows" { + if runtime.GOOS == osWindows { _ = fs.Mkdir("C:\\tmp", 0777) f, _ = fs.Create("C:\\tmp\\" + fname) uPath = "C:/tmp/" + fname diff --git a/data/datasource_vault.go b/data/datasource_vault.go index 143a71e94..18b478be6 100644 --- a/data/datasource_vault.go +++ b/data/datasource_vault.go @@ -51,17 +51,19 @@ func readVault(source *Source, args ...string) (data []byte, err error) { } source.mediaType = jsonMimetype - if len(params) > 0 { + switch { + case len(params) > 0: data, err = source.vc.Write(p, params) - } else if strings.HasSuffix(p, "/") { + case strings.HasSuffix(p, "/"): source.mediaType = jsonArrayMimetype data, err = source.vc.List(p) - } else { + default: data, err = source.vc.Read(p) } if err != nil { return nil, err } + if len(data) == 0 { return nil, errors.Errorf("no value found for path %s", p) } diff --git a/env/env_test.go b/env/env_test.go index 0ed5f5933..122c23803 100644 --- a/env/env_test.go +++ b/env/env_test.go @@ -118,4 +118,4 @@ func (f woFile) Read([]byte) (n int, err error) { return 0, ErrWriteOnly } -var ErrWriteOnly = errors.New("Filesystem is write-only") +var ErrWriteOnly = errors.New("filesystem is write-only") diff --git a/funcs/math.go b/funcs/math.go index 0507de631..4c9df1632 100644 --- a/funcs/math.go +++ b/funcs/math.go @@ -141,7 +141,7 @@ func (f *MathFuncs) Div(a, b interface{}) (interface{}, error) { divisor := conv.ToFloat64(a) dividend := conv.ToFloat64(b) if dividend == 0 { - return 0, fmt.Errorf("Error: division by 0") + return 0, fmt.Errorf("error: division by 0") } return divisor / dividend, nil } diff --git a/funcs/uuid_test.go b/funcs/uuid_test.go index 7df826a55..ef6cb4e8e 100644 --- a/funcs/uuid_test.go +++ b/funcs/uuid_test.go @@ -8,7 +8,6 @@ import ( ) const ( - uuidPattern = "^[[:xdigit:]]{8}-(?:[[:xdigit:]]{4}-){3}[[:xdigit:]]{12}$" uuidV1Pattern = "^[[:xdigit:]]{8}-[[:xdigit:]]{4}-1[[:xdigit:]]{3}-[89ab][[:xdigit:]]{3}-[[:xdigit:]]{12}$" uuidV4Pattern = "^[[:xdigit:]]{8}-[[:xdigit:]]{4}-4[[:xdigit:]]{3}-[89ab][[:xdigit:]]{3}-[[:xdigit:]]{12}$" ) @@ -36,8 +35,7 @@ func TestNil(t *testing.T) { func TestIsValid(t *testing.T) { u := UUIDNS() - var in interface{} - in = false + in := interface{}(false) i, err := u.IsValid(in) assert.NoError(t, err) assert.False(t, i) @@ -63,8 +61,7 @@ func TestIsValid(t *testing.T) { func TestParse(t *testing.T) { u := UUIDNS() - var in interface{} - in = false + in := interface{}(false) _, err := u.Parse(in) assert.Error(t, err) diff --git a/gomplate.go b/gomplate.go index 4f7ef146e..6d9a30e8f 100644 --- a/gomplate.go +++ b/gomplate.go @@ -32,6 +32,7 @@ func (g *gomplate) runTemplate(t *tplate) error { return err } + // nolint: gocritic switch t.target.(type) { case io.Closer: if t.target != os.Stdout { @@ -179,6 +180,7 @@ func mappingNamer(outMap string, g *gomplate) func(string) (string, error) { return "", err } ctx := &context{} + // nolint: gocritic switch c := g.context.(type) { case *context: for k, v := range *c { diff --git a/math/math.go b/math/math.go index 08feb1fcf..08a8eee3a 100644 --- a/math/math.go +++ b/math/math.go @@ -34,7 +34,7 @@ func Seq(start, end, step int64) []int64 { } // adjust the end so it aligns exactly (avoids infinite loop!) - end = end - (end-start)%step + end -= (end - start) % step seq := []int64{start} last := start diff --git a/random/random.go b/random/random.go index 58a44d7d4..7dcb41791 100644 --- a/random/random.go +++ b/random/random.go @@ -19,8 +19,7 @@ const defaultSet = "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstu // StringRE - Generate a random string that matches a given regular // expression. Defaults to "[a-zA-Z0-9_.-]" func StringRE(count int, match string) (r string, err error) { - var chars []rune - chars = []rune(defaultSet) + var chars = []rune(defaultSet) if match != "" { chars, err = matchChars(match) if err != nil { diff --git a/template.go b/template.go index 7022664b8..f2a021c7f 100644 --- a/template.go +++ b/template.go @@ -103,8 +103,9 @@ func gatherTemplates(o *Config, outFileNamer func(string) (string, error)) (temp return nil, err } + switch { // the arg-provided input string gets a special name - if o.Input != "" { + case o.Input != "": templates = []*tplate{{ name: "", contents: o.Input, @@ -112,13 +113,13 @@ func gatherTemplates(o *Config, outFileNamer func(string) (string, error)) (temp modeOverride: modeOverride, targetPath: o.OutputFiles[0], }} - } else if o.InputDir != "" { + case o.InputDir != "": // input dirs presume output dirs are set too templates, err = walkDir(o.InputDir, outFileNamer, o.ExcludeGlob, mode, modeOverride) if err != nil { return nil, err } - } else if o.Input == "" { + case o.Input == "": templates = make([]*tplate, len(o.InputFiles)) for i := range o.InputFiles { templates[i], err = fileToTemplates(o.InputFiles[i], o.OutputFiles[i], mode, modeOverride) diff --git a/template_test.go b/template_test.go index 14fe6ed33..12726ab88 100644 --- a/template_test.go +++ b/template_test.go @@ -233,7 +233,7 @@ func TestProcessTemplates(t *testing.T) { if in.templates[i].targetPath != "-" { info, err := fs.Stat(in.templates[i].targetPath) assert.NoError(t, err) - assert.Equal(t, os.FileMode(in.modes[i]), info.Mode()) + assert.Equal(t, in.modes[i], info.Mode()) } } fs.Remove("out") diff --git a/tests/integration/basic_test.go b/tests/integration/basic_test.go index 310188061..87baf957f 100644 --- a/tests/integration/basic_test.go +++ b/tests/integration/basic_test.go @@ -74,7 +74,7 @@ func (s *BasicSuite) TestErrorsWithInputOutputImbalance(c *C) { }) result.Assert(c, icmd.Expected{ ExitCode: 1, - Err: "Must provide same number of --out (1) as --file (2) options", + Err: "must provide same number of --out (1) as --file (2) options", }) } diff --git a/tests/integration/datasources_consul_test.go b/tests/integration/datasources_consul_test.go index f0c58f68d..3f73e5099 100644 --- a/tests/integration/datasources_consul_test.go +++ b/tests/integration/datasources_consul_test.go @@ -124,7 +124,7 @@ func (s *ConsulDatasourcesSuite) TearDownSuite(c *C) { } } -func (s *ConsulDatasourcesSuite) consulPut(c *C, k string, v string) { +func (s *ConsulDatasourcesSuite) consulPut(c *C, k, v string) { result := icmd.RunCmd(icmd.Command("consul", "kv", "put", k, v), func(c *icmd.Cmd) { c.Env = []string{"CONSUL_HTTP_ADDR=http://" + s.consulAddr} @@ -141,36 +141,39 @@ func (s *ConsulDatasourcesSuite) consulDelete(c *C, k string) { } func (s *ConsulDatasourcesSuite) TestConsulDatasource(c *C) { - s.consulPut(c, "foo", "bar") - defer s.consulDelete(c, "foo") + s.consulPut(c, "foo1", "bar") + defer s.consulDelete(c, "foo1") result := icmd.RunCmd(icmd.Command(GomplateBin, "-d", "consul=consul://", - "-i", `{{(ds "consul" "foo")}}`, + "-i", `{{(ds "consul" "foo1")}}`, ), func(c *icmd.Cmd) { c.Env = []string{"CONSUL_HTTP_ADDR=http://" + s.consulAddr} }) result.Assert(c, icmd.Expected{ExitCode: 0, Out: "bar"}) - s.consulPut(c, "foo", `{"bar": "baz"}`) + s.consulPut(c, "foo2", `{"bar": "baz"}`) + defer s.consulDelete(c, "foo2") result = icmd.RunCmd(icmd.Command(GomplateBin, "-d", "consul=consul://?type=application/json", - "-i", `{{(ds "consul" "foo").bar}}`, + "-i", `{{(ds "consul" "foo2").bar}}`, ), func(c *icmd.Cmd) { c.Env = []string{"CONSUL_HTTP_ADDR=http://" + s.consulAddr} }) result.Assert(c, icmd.Expected{ExitCode: 0, Out: "baz"}) - s.consulPut(c, "foo", `bar`) + s.consulPut(c, "foo2", `bar`) + defer s.consulDelete(c, "foo2") result = icmd.RunCmd(icmd.Command(GomplateBin, "-d", "consul=consul://"+s.consulAddr, - "-i", `{{(ds "consul" "foo")}}`, + "-i", `{{(ds "consul" "foo2")}}`, )) result.Assert(c, icmd.Expected{ExitCode: 0, Out: "bar"}) - s.consulPut(c, "foo", `bar`) + s.consulPut(c, "foo3", `bar`) + defer s.consulDelete(c, "foo3") result = icmd.RunCmd(icmd.Command(GomplateBin, "-d", "consul=consul+http://"+s.consulAddr, - "-i", `{{(ds "consul" "foo")}}`, + "-i", `{{(ds "consul" "foo3")}}`, )) result.Assert(c, icmd.Expected{ExitCode: 0, Out: "bar"}) }