diff --git a/.golangci.yml b/.golangci.yml index ddd5e95e1..72ba71e37 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,13 +2,10 @@ run: timeout: 2m issues-exit-code: 1 tests: true - skip-dirs: - - docs - - _ci - - .github - - .circleci + go: "1.21" output: - format: colored-line-number + formats: + - format: colored-line-number print-issued-lines: true print-linter-name: true @@ -28,21 +25,11 @@ linters-settings: comparison: true gofmt: simplify: true - gofumpt: - lang-version: "1.21" - extra-rules: false - gosimple: - go: "1.21" - checks: [ "all" ] dupl: threshold: 120 goconst: min-len: 3 min-occurrences: 5 - gomnd: - settings: - mnd: - ignored-functions: strconv.Format*,os.*,strconv.Parse*,strings.SplitN,bytes.SplitN revive: min-confidence: 0.8 unused: @@ -69,11 +56,11 @@ linters: - goconst - gocritic - goimports - - gomnd + - mnd - gosimple - govet - ineffassign - - megacheck + - staticcheck - misspell - unconvert - unused @@ -82,11 +69,17 @@ linters: disable: - depguard - gosec - - interfacer - gocyclo fast: false + mnd: + ignored-functions: strconv.Format*,os.*,strconv.Parse*,strings.SplitN,bytes.SplitN issues: + exclude-dirs: + - docs + - _ci + - .github + - .circleci exclude-rules: - path: _test\.go linters: @@ -95,7 +88,7 @@ issues: - lll - errcheck - wsl - - gomnd + - mnd - unparam exclude-use-default: false diff --git a/Makefile b/Makefile index 34045b134..18f43541f 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ clean: rm -f terragrunt install-lint: - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2 + go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1 run-lint: golangci-lint run -v --timeout=5m ./... diff --git a/cli/commands/catalog/tui/view.go b/cli/commands/catalog/tui/view.go index 4eed72ecf..4837ed46e 100644 --- a/cli/commands/catalog/tui/view.go +++ b/cli/commands/catalog/tui/view.go @@ -8,10 +8,10 @@ import ( ) var ( - appStyle = lipgloss.NewStyle().Padding(1, 2) //nolint:gomnd + appStyle = lipgloss.NewStyle().Padding(1, 2) //nolint:mnd infoPositionStyle = lipgloss.NewStyle().Padding(0, 1).BorderStyle(lipgloss.HiddenBorder()) infoLineStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#1D252")) - infoHelp = lipgloss.NewStyle().Padding(2, 0, 0, 2) //nolint:gomnd + infoHelp = lipgloss.NewStyle().Padding(2, 0, 0, 2) //nolint:mnd ) // View is the main view, which just calls the appropriate sub-view and returns a string representation of the TUI diff --git a/cli/commands/render-json/action.go b/cli/commands/render-json/action.go index 9bbc4f34b..1775a8721 100644 --- a/cli/commands/render-json/action.go +++ b/cli/commands/render-json/action.go @@ -77,7 +77,8 @@ func runRenderJSON(ctx context.Context, opts *options.TerragruntOptions, cfg *co } opts.Logger.Debugf("Rendering config %s to JSON %s", opts.TerragruntConfigPath, jsonOutPath) - if err := os.WriteFile(jsonOutPath, jsonBytes, 0644); err != nil { + const ownerWriteGlobalReadPerms = 0644 + if err := os.WriteFile(jsonOutPath, jsonBytes, ownerWriteGlobalReadPerms); err != nil { return errors.WithStackTrace(err) } return nil diff --git a/cli/commands/scaffold/action.go b/cli/commands/scaffold/action.go index 45929cd00..1a53529f3 100644 --- a/cli/commands/scaffold/action.go +++ b/cli/commands/scaffold/action.go @@ -233,10 +233,11 @@ func prepareBoilerplateFiles(ctx context.Context, opts *options.TerragruntOption return "", errors.WithStackTrace(err) } boilerplateDir = defaultTempDir - if err := os.WriteFile(util.JoinPath(boilerplateDir, "terragrunt.hcl"), []byte(defaultTerragruntTemplate), 0644); err != nil { + const ownerWriteGlobalReadPerms = 0644 + if err := os.WriteFile(util.JoinPath(boilerplateDir, "terragrunt.hcl"), []byte(defaultTerragruntTemplate), ownerWriteGlobalReadPerms); err != nil { return "", errors.WithStackTrace(err) } - if err := os.WriteFile(util.JoinPath(boilerplateDir, "boilerplate.yml"), []byte(defaultBoilerplateConfig), 0644); err != nil { + if err := os.WriteFile(util.JoinPath(boilerplateDir, "boilerplate.yml"), []byte(defaultBoilerplateConfig), ownerWriteGlobalReadPerms); err != nil { return "", errors.WithStackTrace(err) } } diff --git a/cli/commands/terraform/action.go b/cli/commands/terraform/action.go index 651e013f6..1318780f9 100644 --- a/cli/commands/terraform/action.go +++ b/cli/commands/terraform/action.go @@ -774,7 +774,8 @@ func setTerragruntNullValues(terragruntOptions *options.TerragruntOptions, terra return "", errors.WithStackTrace(err) } varFile := filepath.Join(terragruntOptions.WorkingDir, NullTFVarsFile) - if err := os.WriteFile(varFile, jsonContents, os.FileMode(0600)); err != nil { + const ownerReadWritePermissions = 0600 + if err := os.WriteFile(varFile, jsonContents, os.FileMode(ownerReadWritePermissions)); err != nil { return "", errors.WithStackTrace(err) } diff --git a/codegen/generate.go b/codegen/generate.go index 07ea7d7a1..96b7713e0 100644 --- a/codegen/generate.go +++ b/codegen/generate.go @@ -121,7 +121,8 @@ func WriteToFile(terragruntOptions *options.TerragruntOptions, basePath string, } contentsToWrite := fmt.Sprintf("%s%s", prefix, config.Contents) - if err := os.WriteFile(targetPath, []byte(contentsToWrite), 0644); err != nil { + const ownerWriteGlobalReadPerms = 0644 + if err := os.WriteFile(targetPath, []byte(contentsToWrite), ownerWriteGlobalReadPerms); err != nil { return errors.WithStackTrace(err) } terragruntOptions.Logger.Debugf("Generated file %s.", targetPath) diff --git a/pkg/cli/autocomplete.go b/pkg/cli/autocomplete.go index 128126bca..b239a4c7c 100644 --- a/pkg/cli/autocomplete.go +++ b/pkg/cli/autocomplete.go @@ -1,6 +1,7 @@ package cli import ( + goErrors "errors" "fmt" "io" "os" @@ -78,6 +79,8 @@ func defaultComplete(ctx *Context) error { } func printCommandSuggestions(arg string, commands []*Command, writer io.Writer) error { + errs := []error{} + for _, command := range commands { if command.Hidden { continue @@ -85,17 +88,23 @@ func printCommandSuggestions(arg string, commands []*Command, writer io.Writer) for _, name := range command.Names() { if name != "" && (arg == "" || strings.HasPrefix(name, arg)) { - fmt.Fprintln(writer, name) + _, err := fmt.Fprintln(writer, name) + errs = append(errs, err) } } } + if len(errs) > 0 { + return goErrors.Join(errs...) + } + return nil } func printFlagSuggestions(arg string, flags []Flag, writer io.Writer) error { cur := strings.TrimPrefix(arg, "-") + errs := []error{} for _, flag := range flags { for _, name := range flag.Names() { name = strings.TrimSpace(name) @@ -112,11 +121,16 @@ func printFlagSuggestions(arg string, flags []Flag, writer io.Writer) error { // match if last argument matches this flag and it is not repeated if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(name) { flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name) - fmt.Fprintln(writer, flagCompletion) + _, err := fmt.Fprintln(writer, flagCompletion) + errs = append(errs, err) } } } + if len(errs) > 0 { + return goErrors.Join(errs...) + } + return nil } diff --git a/pkg/cli/command.go b/pkg/cli/command.go index 48ee58ef0..f0c3301c4 100644 --- a/pkg/cli/command.go +++ b/pkg/cli/command.go @@ -218,7 +218,7 @@ func (cmd *Command) flagSetParse(flagSet *libflag.FlagSet, args []string) ([]str var notFoundMatch bool for i, arg := range args { // `--var=input=from_env` trims to `var` - trimmed := strings.SplitN(strings.Trim(arg, "-"), "=", 2)[0] + trimmed := strings.SplitN(strings.Trim(arg, "-"), "=", 2)[0] //nolint:mnd if trimmed == undefArg { undefArgs = append(undefArgs, arg) notFoundMatch = true diff --git a/terraform/cliconfig/config.go b/terraform/cliconfig/config.go index 74b5d923e..36c754e34 100644 --- a/terraform/cliconfig/config.go +++ b/terraform/cliconfig/config.go @@ -105,7 +105,8 @@ func (cfg *Config) Save(configPath string) error { file := hclwrite.NewEmptyFile() gohcl.EncodeIntoBody(cfg, file.Body()) - if err := os.WriteFile(configPath, file.Bytes(), os.FileMode(0644)); err != nil { + const ownerWriteGlobalReadPerms = 0644 + if err := os.WriteFile(configPath, file.Bytes(), os.FileMode(ownerWriteGlobalReadPerms)); err != nil { return errors.WithStackTrace(err) } diff --git a/terraform/getproviders/lock.go b/terraform/getproviders/lock.go index 6ab3ad78f..805ec8760 100644 --- a/terraform/getproviders/lock.go +++ b/terraform/getproviders/lock.go @@ -47,7 +47,8 @@ func UpdateLockfile(ctx context.Context, workingDir string, providers []Provider return err } - if err := os.WriteFile(filename, file.Bytes(), 0644); err != nil { + const ownerWriteGlobalReadPerms = 0644 + if err := os.WriteFile(filename, file.Bytes(), ownerWriteGlobalReadPerms); err != nil { return errors.WithStackTrace(err) } return nil diff --git a/terraform/getter.go b/terraform/getter.go index 35953f19a..941ecb800 100644 --- a/terraform/getter.go +++ b/terraform/getter.go @@ -216,7 +216,8 @@ func (tfrGetter *RegistryGetter) getSubdir(ctx context.Context, dstPath, sourceU } // Make the final destination - if err := os.MkdirAll(dstPath, 0755); err != nil { + const ownerWriteGlobalReadExecutePerms = 0755 + if err := os.MkdirAll(dstPath, ownerWriteGlobalReadExecutePerms); err != nil { return errors.WithStackTrace(err) } diff --git a/terraform/source.go b/terraform/source.go index 65f121bb1..f2b7fd947 100644 --- a/terraform/source.go +++ b/terraform/source.go @@ -111,7 +111,8 @@ func (terraformSource Source) WriteVersionFile() error { } } - return errors.WithStackTrace(os.WriteFile(terraformSource.VersionFile, []byte(version), 0640)) + const ownerReadWriteGroupReadPerms = 0640 + return errors.WithStackTrace(os.WriteFile(terraformSource.VersionFile, []byte(version), ownerReadWriteGroupReadPerms)) } // Take the given source path and create a Source struct from it, including the folder where the source should @@ -270,7 +271,7 @@ func IsLocalSource(sourceUrl *url.URL) bool { // path is everything after the double slash. If there is no double-slash in the URL, the root repo is the entire // sourceUrl and the path is an empty string. func SplitSourceUrl(sourceUrl *url.URL, logger *logrus.Entry) (*url.URL, string, error) { - pathSplitOnDoubleSlash := strings.SplitN(sourceUrl.Path, "//", 2) + pathSplitOnDoubleSlash := strings.SplitN(sourceUrl.Path, "//", 2) //nolint:mnd if len(pathSplitOnDoubleSlash) > 1 { sourceUrlModifiedPath, err := parseSourceUrl(sourceUrl.String()) diff --git a/util/file.go b/util/file.go index fb3cd29af..634ea40a5 100644 --- a/util/file.go +++ b/util/file.go @@ -67,7 +67,8 @@ func EnsureDirectory(path string) error { if FileExists(path) && IsFile(path) { return errors.WithStackTrace(PathIsNotDirectory{path}) } else if !FileExists(path) { - return errors.WithStackTrace(os.MkdirAll(path, 0700)) + const ownerReadWriteExecutePerms = 0700 + return errors.WithStackTrace(os.MkdirAll(path, ownerReadWriteExecutePerms)) } return nil } @@ -285,7 +286,8 @@ func CopyFolderContents(source, destination, manifestFile string, includeInCopy // the given filter function and only copy it if the filter returns true. Will create a specified manifest file // that contains paths of all copied files. func CopyFolderContentsWithFilter(source, destination, manifestFile string, filter func(absolutePath string) bool) error { - if err := os.MkdirAll(destination, 0700); err != nil { + const ownerReadWriteExecutePerms = 0700 + if err := os.MkdirAll(destination, ownerReadWriteExecutePerms); err != nil { return errors.WithStackTrace(err) } manifest := newFileManifest(destination, manifestFile) @@ -340,7 +342,8 @@ func CopyFolderContentsWithFilter(source, destination, manifestFile string, filt } } else { parentDir := filepath.Dir(dest) - if err := os.MkdirAll(parentDir, 0700); err != nil { + const ownerReadWriteExecutePerms = 0700 + if err := os.MkdirAll(parentDir, ownerReadWriteExecutePerms); err != nil { return errors.WithStackTrace(err) } if err := CopyFile(file, dest); err != nil { @@ -535,7 +538,8 @@ func (manifest *fileManifest) clean(manifestPath string) error { // Create will create the manifest file func (manifest *fileManifest) Create() error { - fileHandle, err := os.OpenFile(filepath.Join(manifest.ManifestFolder, manifest.ManifestFile), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) + const ownerWriteGlobalReadPerms = 0644 + fileHandle, err := os.OpenFile(filepath.Join(manifest.ManifestFolder, manifest.ManifestFile), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, ownerWriteGlobalReadPerms) if err != nil { return err }