Merge pull request #169 from yxxhero/add_golang_ci

add Go lint
This commit is contained in:
yxxhero 2022-07-16 20:43:25 +08:00 committed by GitHub
commit f00a8194e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 576 additions and 194 deletions

28
.github/workflows/lint.yaml vendored Normal file
View File

@ -0,0 +1,28 @@
name: Lint
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
GO_VERSION: 1.18
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.18
- name: Checkout code
uses: actions/checkout@v3
- name: Golangci lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.46.2

352
.golangci.yaml Normal file
View File

@ -0,0 +1,352 @@
# This file contains all available configuration options
# with their default values.
# options for analysis running
run:
# default concurrency is a available CPU number
# concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 30m
# exit code when at least one issue was found, default is 1
issues-exit-code: 1
# include test files or not, default is true
tests: true
# list of build tags, all linters use it. Default is empty list.
# build-tags:
# - mytag
# which dirs to skip: issues from them won't be reported;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but default dirs are skipped independently
# from this option's value (see skip-dirs-use-default).
# skip-dirs:
# - src/external_libs
# - autogenerated_by_my_lib
# default is true. Enables skipping of directories:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs-use-default: true
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
# skip-files:
# - ".*\\.my\\.go$"
# - lib/bad.go
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit
# automatic updating of go.mod described above. Instead, it fails when any changes
# to go.mod are needed. This setting is most useful to check that go.mod does
# not need updates, such as in a continuous integration and testing system.
# If invoked with -mod=vendor, the go command assumes that the vendor
# directory holds the correct copies of dependencies and ignores
# the dependency descriptions in go.mod.
# modules-download-mode: readonly|release|vendor
# output configuration options
output:
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
format: line-number
# print lines of code with issue, default is true
print-issued-lines: true
# print linter name in the end of issue text, default is true
print-linter-name: true
# all available settings of specific linters
linters-settings:
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: false
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: false
# [deprecated] comma-separated list of pairs of the form pkg:regex
# the regex is used to ignore names within pkg. (default "fmt:.*").
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
# ignore: fmt:.*
# path to a file containing a list of functions to exclude from checking
# see https://github.com/kisielk/errcheck#excluding-functions for details
# exclude: /path/to/file.txt
# Disable error checking, as errorcheck detects more errors and is more configurable.
gosec:
exclude:
- "G104"
govet:
# report about shadowed variables
check-shadowing: false
# settings per analyzer
settings:
printf: # analyzer name, run `go tool vet help` to see all analyzers
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
# enable or disable analyzers by name
# enable:
# - atomicalign
# enable-all: false
# disable:
# - shadow
# disable-all: false
golint:
# minimal confidence for issues, default is 0.8
min-confidence: 0.8
gofmt:
# simplify code: gofmt with `-s` option, true by default
simplify: true
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
# local-prefixes: github.com/org/project
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30
gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 100
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
dupl:
# tokens count to trigger issue, 150 by default
threshold: 100
goconst:
# minimal length of string constant, 3 by default
min-len: 3
# minimal occurrences count to trigger, 3 by default
min-occurrences: 8
# depguard:
# list-type: blacklist
# include-go-root: false
# packages:
# - github.com/sirupsen/logrus
# packages-with-error-messages:
# # specify an error message to output when a blacklisted package is used
# github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
ignore-words:
- GitLab
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 120
# tab width in spaces. Default to 1.
tab-width: 1
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30
prealloc:
# XXX: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# True by default.
simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
gocritic:
# Which checks should be enabled; can't be combined with 'disabled-checks';
# See https://go-critic.github.io/overview#checks-overview
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
# By default list of stable checks is used.
# enabled-checks:
# - rangeValCopy
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
# disabled-checks:
# - regexpMust
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
# enabled-tags:
# - performance
settings: # settings passed to gocritic
captLocal: # must be valid enabled check name
paramsOnly: true
# rangeValCopy:
# sizeThreshold: 32
godox:
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
- TODO
- BUG
- FIXME
- NOTE
- OPTIMIZE # marks code that should be optimized before merging
- HACK # marks hack-arounds that should be removed before merging
dogsled:
# checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2
whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
wsl:
# If true append is only allowed to be cuddled if appending value is
# matching variables, fields or types on line above. Default is true.
strict-append: true
# Allow calls and assignments to be cuddled as long as the lines have any
# matching variables, fields or types. Default is true.
allow-assign-and-call: true
# Allow multiline assignments to be cuddled. Default is true.
allow-multiline-assign: true
# Allow declarations (var) to be cuddled.
allow-cuddle-declarations: false
# Allow trailing comments in ending of blocks
allow-trailing-comment: false
# Force newlines in end of case at this limit (0 = never).
force-case-trailing-whitespace: 0
revive:
ignore-generated-header: true
severity: warning
funlen:
# Checks the number of lines in a function.
# If lower than 0, disable the check.
# Default: 60
lines: 280
# Checks the number of statements in a function.
# If lower than 0, disable the check.
# Default: 40
statements: 140
linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
disable-all: true
enable:
- bodyclose
- depguard
# - dogsled
# - dupl
- errcheck
- funlen
- gocognit
- goconst
# - gocritic
# - godox
- gofmt
- goimports
- revive
# - gosec
- gosimple
- govet
- ineffassign
# - interfacer
- misspell
- nakedret
- exportloopref
- staticcheck
- structcheck
# - stylecheck
- typecheck
- unconvert
- unparam
- unused
- whitespace
# don't enable:
# - deadcode
# - gochecknoglobals
# - gochecknoinits
# - gocyclo
# - lll
# - maligned
# - prealloc
# - varcheck
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
# exclude:
# - abcdef
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- funlen
# Exclude known linters from partially hard-vendored code,
# which is impossible to exclude via "nolint" comments.
# - path: internal/hmac/
# text: "weak cryptographic primitive"
# linters:
# - gosec
# Exclude some staticcheck messages
# - linters:
# - staticcheck
# text: "SA9003:"
# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing
# large codebase. It's not practical to fix all existing issues at the moment
# of integration: much better don't allow issues in new code.
# Default is false.
new: false
# Show only new issues created after git revision `REV`
# This should be passed as flag during individual CI jobs.
# new-from-rev: REV
# Show only new issues created in git patch with set file path.
# new-from-patch: path/to/patch/file

View File

@ -26,7 +26,7 @@ func addApplySubcommand(cliApp *cli.App) {
},
cli.BoolFlag{
Name: "validate",
Usage: "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requiers access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions",
Usage: "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions",
},
cli.IntFlag{
Name: "context",

View File

@ -71,7 +71,7 @@ func addDiffSubcommand(cliApp *cli.App) {
},
cli.BoolFlag{
Name: "validate",
Usage: "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requiers access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions",
Usage: "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions",
},
cli.IntFlag{

View File

@ -119,7 +119,6 @@ func setRootCommandFlags(cliApp *cli.App) {
Usage: "Request confirmation before attempting to modify clusters",
},
}
}
func toCliError(c *cli.Context, err error) error {
@ -153,7 +152,7 @@ func configureLogging(c *cli.Context) error {
}
logger = helmexec.NewLogger(os.Stderr, logLevel)
if c.App.Metadata == nil {
// Auto-initialised in 1.19.0
// Auto-initialized in 1.19.0
// https://github.com/urfave/cli/blob/master/CHANGELOG.md#1190---2016-11-19
c.App.Metadata = make(map[string]interface{})
}

View File

@ -51,7 +51,7 @@ func addSyncSubcommand(cliApp *cli.App) {
},
cli.BoolFlag{
Name: "validate",
Usage: `ADVANCED CONFIGURATION: When sync is going to involve helm-template as a part of the "chartify" process, it might fail due to missing .Capabilities. This flag makes instructs helmfile to pass --validate to helm-template so it populates .Capabilities and validates your manifests against the Kubernetes cluster you are currently pointing at. Note that this requiers access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions`,
Usage: `ADVANCED CONFIGURATION: When sync is going to involve helm-template as a part of the "chartify" process, it might fail due to missing .Capabilities. This flag makes instructs helmfile to pass --validate to helm-template so it populates .Capabilities and validates your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions`,
},
cli.BoolFlag{
Name: "wait",

View File

@ -39,7 +39,7 @@ func addTemplateSubcommand(cliApp *cli.App) {
},
cli.BoolFlag{
Name: "validate",
Usage: "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requiers access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions",
Usage: "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the list of available API versions",
},
cli.BoolFlag{
Name: "include-crds",

4
go.mod
View File

@ -30,6 +30,7 @@ require (
go.uber.org/multierr v1.6.0
go.uber.org/zap v1.21.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
gopkg.in/yaml.v2 v2.4.0
k8s.io/apimachinery v0.23.4
)
@ -123,7 +124,6 @@ require (
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
@ -146,5 +146,5 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c // indirect
github.com/pierrec/lz4 v2.3.0+incompatible // indirect
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect
)

View File

@ -8,7 +8,6 @@ import (
)
func main() {
rootCmd := cmd.RootCommand()
err := rootCmd.Run(os.Args)
if err != nil {

View File

@ -22,6 +22,7 @@ import (
"go.uber.org/zap"
)
// App is the main application object.
type App struct {
OverrideKubeContext string
OverrideHelmBinary string
@ -552,8 +553,7 @@ func (a *App) ListReleases(c ListConfigProvider) error {
SkipRepos: true,
SkipDeps: true,
}, func() {
//var releases m
// var releases m
for _, r := range run.state.Releases {
labels := ""
if r.Labels == nil {
@ -805,7 +805,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
Reverse: defOpts.Reverse,
RetainValuesFiles: defOpts.RetainValuesFiles,
}
//assign parent selector to sub helm selector in legacy mode or do not inherit in experimental mode
// assign parent selector to sub helm selector in legacy mode or do not inherit in experimental mode
if (m.Selectors == nil && !isExplicitSelectorInheritanceEnabled()) || m.SelectorsInherited {
optsForNestedState.Selectors = opts.Selectors
} else {
@ -915,7 +915,7 @@ func printBatches(batches [][]state.Release) string {
fmt.Fprintf(w, "%d\t%s\n", i+1, strings.Join(ids, ", "))
}
w.Flush()
_ = w.Flush()
return buf.String()
}
@ -1092,11 +1092,12 @@ func (a *App) findDesiredStateFiles(specifiedPath string, opts LoadOpts) ([]stri
var helmfileDir string
if specifiedPath != "" {
if a.fileExistsAt(specifiedPath) {
switch {
case a.fileExistsAt(specifiedPath):
return []string{specifiedPath}, nil
} else if a.directoryExistsAt(specifiedPath) {
case a.directoryExistsAt(specifiedPath):
helmfileDir = specifiedPath
} else {
default:
return []string{}, fmt.Errorf("specified state file %s is not found", specifiedPath)
}
} else {
@ -1113,15 +1114,16 @@ func (a *App) findDesiredStateFiles(specifiedPath string, opts LoadOpts) ([]stri
defaultFile = DeprecatedHelmfile
}
if a.directoryExistsAt(DefaultHelmfileDirectory) {
switch {
case a.directoryExistsAt(DefaultHelmfileDirectory):
if defaultFile != "" {
return []string{}, fmt.Errorf("configuration conlict error: you can have either %s or %s, but not both", defaultFile, DefaultHelmfileDirectory)
}
helmfileDir = DefaultHelmfileDirectory
} else if defaultFile != "" {
case defaultFile != "":
return []string{defaultFile}, nil
} else {
default:
return []string{}, fmt.Errorf("no state file found. It must be named %s/*.{yaml,yml} or %s, otherwise specified with the --file flag", DefaultHelmfileDirectory, DefaultHelmfile)
}
}
@ -1944,6 +1946,7 @@ func directoryExistsAt(path string) bool {
return err == nil && fileInfo.Mode().IsDir()
}
// Error is a wrapper around an error that adds context to the error.
type Error struct {
msg string
@ -2084,7 +2087,10 @@ func (a *App) CleanCacheDir(c ListConfigProvider) error {
}
for _, e := range dirs {
fmt.Printf("- %s\n", e.Name())
os.RemoveAll(filepath.Join(remote.CacheDir(), e.Name()))
err := os.RemoveAll(filepath.Join(remote.CacheDir(), e.Name()))
if err != nil {
return err
}
}
return nil

View File

@ -1275,7 +1275,7 @@ foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED raw-3.1.0 3.1.0 default
})
})
t.Run("select non existant release with --allow-no-matching-release", func(t *testing.T) {
t.Run("select non existent release with --allow-no-matching-release", func(t *testing.T) {
check(t, testcase{
files: map[string]string{
"/path/to/helmfile.yaml": `

View File

@ -612,7 +612,7 @@ releases:
whatever: yes
`,
}
//Check with legacy behavior, that is when no explicit selector then sub-helmfiles inherits from command line selector
// Check with legacy behavior, that is when no explicit selector then sub-helmfiles inherits from command line selector
legacyTestcases := []struct {
label string
expectedReleases []string
@ -626,7 +626,7 @@ releases:
}
runFilterSubHelmFilesTests(legacyTestcases, files, t, "1st EmbeddedSelectors")
//Check with experimental behavior, that is when no explicit selector then sub-helmfiles do no inherit from any selector
// Check with experimental behavior, that is when no explicit selector then sub-helmfiles do no inherit from any selector
desiredTestcases := []struct {
label string
expectedReleases []string
@ -640,7 +640,6 @@ releases:
t.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
runFilterSubHelmFilesTests(desiredTestcases, files, t, "2nd EmbeddedSelectors")
}
func TestVisitDesiredStatesWithReleasesFiltered_InheritedSelectors_3leveldeep(t *testing.T) {
@ -665,7 +664,7 @@ releases:
chart: stable/grafana
`,
}
//Check with legacy behavior, that is when no explicit selector then sub-helmfiles inherits from command line selector
// Check with legacy behavior, that is when no explicit selector then sub-helmfiles inherits from command line selector
legacyTestcases := []struct {
label string
expectedReleases []string
@ -676,7 +675,7 @@ releases:
}
runFilterSubHelmFilesTests(legacyTestcases, files, t, "1st 3leveldeep")
//Check with experimental behavior, that is when no explicit selector then sub-helmfiles do no inherit from any selector
// Check with experimental behavior, that is when no explicit selector then sub-helmfiles do no inherit from any selector
desiredTestcases := []struct {
label string
expectedReleases []string
@ -689,7 +688,6 @@ releases:
t.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
runFilterSubHelmFilesTests(desiredTestcases, files, t, "2nd 3leveldeep")
}
func TestVisitDesiredStatesWithReleasesFiltered_InheritedSelectors_inherits(t *testing.T) {
@ -724,7 +722,7 @@ releases:
select: foo
`,
}
//Check with legacy behavior, that is when no explicit selector then sub-helmfiles inherits from command line selector
// Check with legacy behavior, that is when no explicit selector then sub-helmfiles inherits from command line selector
legacyTestcases := []struct {
label string
expectedReleases []string
@ -736,7 +734,7 @@ releases:
}
runFilterSubHelmFilesTests(legacyTestcases, files, t, "1st inherits")
//Check with experimental behavior, that is when no explicit selector then sub-helmfiles do no inherit from any selector
// Check with experimental behavior, that is when no explicit selector then sub-helmfiles do no inherit from any selector
desiredTestcases := []struct {
label string
expectedReleases []string
@ -750,7 +748,6 @@ releases:
t.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
runFilterSubHelmFilesTests(desiredTestcases, files, t, "2nd inherits")
}
func runFilterSubHelmFilesTests(testcases []struct {
@ -801,7 +798,6 @@ func runFilterSubHelmFilesTests(testcases []struct {
t.Errorf("[%s]unexpected releases for selector %s: expected=%v, actual=%v", testName, testcase.label, testcase.expectedReleases, actual)
}
}
}
func TestVisitDesiredStatesWithReleasesFiltered_EmbeddedNestedStateAdditionalEnvValues(t *testing.T) {
@ -2257,8 +2253,8 @@ type configImpl struct {
includeTransitiveNeeds bool
}
func (a configImpl) Selectors() []string {
return a.selectors
func (c configImpl) Selectors() []string {
return c.selectors
}
func (c configImpl) Set() []string {
@ -2399,16 +2395,16 @@ func (a applyConfig) SkipDeps() bool {
return a.skipDeps
}
func (c applyConfig) SkipNeeds() bool {
return c.skipNeeds
func (a applyConfig) SkipNeeds() bool {
return a.skipNeeds
}
func (c applyConfig) IncludeNeeds() bool {
return c.includeNeeds
func (a applyConfig) IncludeNeeds() bool {
return a.includeNeeds
}
func (c applyConfig) IncludeTransitiveNeeds() bool {
return c.includeTransitiveNeeds
func (a applyConfig) IncludeTransitiveNeeds() bool {
return a.includeTransitiveNeeds
}
func (a applyConfig) IncludeTests() bool {
@ -2765,7 +2761,6 @@ releases:
t.Errorf("HelmState.TemplateReleases() = [%v], want %v", helm.templated[i].flags[j], wantReleases[i].flags[j])
}
}
}
}
@ -4312,11 +4307,12 @@ changing working directory back to "/path/to"
skipDiffOnInstall: tc.skipDiffOnInstall,
skipNeeds: tc.fields.skipNeeds,
})
if tc.error == "" && applyErr != nil {
switch {
case tc.error == "" && applyErr != nil:
t.Fatalf("unexpected error for data defined at %s: %v", tc.loc, applyErr)
} else if tc.error != "" && applyErr == nil {
case tc.error != "" && applyErr == nil:
t.Fatalf("expected error did not occur for data defined at %s", tc.loc)
} else if tc.error != "" && applyErr != nil && tc.error != applyErr.Error() {
case tc.error != "" && applyErr != nil && tc.error != applyErr.Error():
t.Fatalf("invalid error: expected %q, got %q", tc.error, applyErr.Error())
}
@ -4433,7 +4429,6 @@ changing working directory back to "/path/to"
for i := range testcases {
tc := testcases[i]
t.Run(tc.name, func(t *testing.T) {
var helm = &exectest.Helm{
DiffMutex: &sync.Mutex{},
ChartsMutex: &sync.Mutex{},
@ -4483,12 +4478,12 @@ changing working directory back to "/path/to"
skipRepos: false,
includeTransitiveNeeds: false,
})
if tc.error == "" && depsErr != nil {
switch {
case tc.error == "" && depsErr != nil:
t.Fatalf("unexpected error for data defined at %s: %v", tc.loc, depsErr)
} else if tc.error != "" && depsErr == nil {
case tc.error != "" && depsErr == nil:
t.Fatalf("expected error did not occur for data defined at %s", tc.loc)
} else if tc.error != "" && depsErr != nil && tc.error != depsErr.Error() {
case tc.error != "" && depsErr != nil && tc.error != depsErr.Error():
t.Fatalf("invalid error: expected %q, got %q", tc.error, depsErr.Error())
}

View File

@ -11,19 +11,19 @@ import (
// TestIsExplicitSelectorInheritanceEnabled tests the isExplicitSelectorInheritanceEnabled function
func TestIsExplicitSelectorInheritanceEnabled(t *testing.T) {
//env var ExperimentalEnvVar is not set
// env var ExperimentalEnvVar is not set
require.Empty(t, os.Getenv(envvar.Experimental))
require.False(t, isExplicitSelectorInheritanceEnabled())
//check for env var ExperimentalEnvVar set to true
// check for env var ExperimentalEnvVar set to true
t.Setenv(envvar.Experimental, "true")
require.True(t, isExplicitSelectorInheritanceEnabled())
//check for env var ExperimentalEnvVar set to anything
// check for env var ExperimentalEnvVar set to anything
t.Setenv(envvar.Experimental, "anything")
require.False(t, isExplicitSelectorInheritanceEnabled())
//check for env var ExperimentalEnvVar set to ExperimentalSelectorExplicit
// check for env var ExperimentalEnvVar set to ExperimentalSelectorExplicit
t.Setenv(envvar.Experimental, ExperimentalSelectorExplicit)
require.True(t, isExplicitSelectorInheritanceEnabled())
@ -34,15 +34,15 @@ func TestIsExplicitSelectorInheritanceEnabled(t *testing.T) {
// TestExperimentalModeEnabled tests the experimentalModeEnabled function
func TestExperimentalModeEnabled(t *testing.T) {
//env var ExperimentalEnvVar is not set
// env var ExperimentalEnvVar is not set
require.Empty(t, os.Getenv(envvar.Experimental))
require.False(t, experimentalModeEnabled())
//check for env var ExperimentalEnvVar set to anything
// check for env var ExperimentalEnvVar set to anything
t.Setenv(envvar.Experimental, "anything")
require.False(t, experimentalModeEnabled())
//check for env var ExperimentalEnvVar set to true
// check for env var ExperimentalEnvVar set to true
t.Setenv(envvar.Experimental, "true")
require.True(t, experimentalModeEnabled())
}

View File

@ -77,7 +77,7 @@ func (ld *desiredStateLoader) Load(f string, opts LoadOpts) (*state.HelmState, e
return nil, errors.New("err: Cannot use option --kube-context and set attribute kubeContext.")
}
st.OverrideKubeContext = ld.overrideKubeContext
// HelmDefaults.KubeContext is also overriden in here
// HelmDefaults.KubeContext is also overridden in here
// to set default release value properly.
st.HelmDefaults.KubeContext = ld.overrideKubeContext
}

View File

@ -108,11 +108,12 @@ func TestDestroy_2(t *testing.T) {
includeTransitiveNeeds: false,
})
if tc.error == "" && destroyErr != nil {
switch {
case tc.error == "" && destroyErr != nil:
t.Fatalf("unexpected error: %v", destroyErr)
} else if tc.error != "" && destroyErr == nil {
case tc.error != "" && destroyErr == nil:
t.Fatal("expected error did not occur")
} else if tc.error != "" && destroyErr != nil && tc.error != destroyErr.Error() {
case tc.error != "" && destroyErr != nil && tc.error != destroyErr.Error():
t.Fatalf("invalid error: expected %q, got %q", tc.error, destroyErr.Error())
}

View File

@ -148,11 +148,12 @@ func TestDestroy(t *testing.T) {
logger: logger,
})
if tc.error == "" && destroyErr != nil {
switch {
case tc.error == "" && destroyErr != nil:
t.Fatalf("unexpected error: %v", destroyErr)
} else if tc.error != "" && destroyErr == nil {
case tc.error != "" && destroyErr == nil:
t.Fatal("expected error did not occur")
} else if tc.error != "" && destroyErr != nil && tc.error != destroyErr.Error() {
case tc.error != "" && destroyErr != nil && tc.error != destroyErr.Error():
t.Fatalf("invalid error: expected %q, got %q", tc.error, destroyErr.Error())
}

View File

@ -9,7 +9,6 @@ import (
// TestFormatAsTable tests the FormatAsTable function.
func TestFormatAsTable(t *testing.T) {
h := []*HelmRelease{
{
Name: "test",
@ -78,5 +77,4 @@ func TestFormatAsJson(t *testing.T) {
if result != string(expectd) {
t.Errorf("FormatAsJson() = %v, want %v", result, string(expectd))
}
}

View File

@ -19,5 +19,4 @@ func TestLoadOptsDeepCopy(t *testing.T) {
// Check that the new struct is not the same as the old one.
require.Equal(t, lOld, lNew, "DeepCopy should return a copy of the LoadOpts struct")
}

View File

@ -55,7 +55,9 @@ func (r *Run) withPreparedCharts(helmfileCommand string, opts state.ChartPrepare
if err != nil {
return err
}
defer os.RemoveAll(tempDir)
defer func() {
_ = os.RemoveAll(tempDir)
}()
dir = tempDir
} else {
dir = opts.OutputDir

View File

@ -51,8 +51,7 @@ func (r *desiredStateLoader) renderPrestate(firstPassEnv *environment.Environmen
// create preliminary state, as we may have an environment. Tolerate errors.
prestate, err := c.ParseAndLoad([]byte(sanitized), baseDir, filename, r.env, false, firstPassEnv)
if err != nil && r.logger != nil {
switch err.(type) {
case *state.StateLoadError:
if _, ok := err.(*state.StateLoadError); ok {
r.logger.Debugf("could not deduce `environment:` block, configuring only .Environment.Name. error: %v", err)
}
r.logger.Debugf("error in first-pass rendering: result of \"%s\":\n%s", filename, prependLineNumbers(yamlBuf.String()))

View File

@ -31,7 +31,6 @@ func makeLoader(files map[string]string, env string) (*desiredStateLoader, *test
}
func TestReadFromYaml_MakeEnvironmentHasNoSideEffects(t *testing.T) {
yamlContent := []byte(`
environments:
staging:
@ -71,7 +70,6 @@ releases:
}
func TestReadFromYaml_RenderTemplate(t *testing.T) {
defaultValuesYaml := `
releaseName: "hello"
conditionalReleaseTag: "yes"
@ -159,7 +157,6 @@ releases:
// even if the pre-render disables the readFile and exec functions.
// This does not apply to .gotmpl files, which is a nice side-effect.
func TestReadFromYaml_RenderTemplateWithGotmpl(t *testing.T) {
defaultValuesYamlGotmpl := `
releaseName: {{ readFile "nonIgnoredFile" }}
`

View File

@ -2,6 +2,7 @@ package app
import "errors"
// ValidateConfig validates the given Helmfile config.
func ValidateConfig(conf ApplyConfigProvider) error {
if conf.NoColor() && conf.Color() {
return errors.New("--color and --no-color cannot be specified at the same time")

View File

@ -1,3 +1,5 @@
// Package version is used to get the version of the Helmfile CLI.
package version
// Version is the version of Helmfile
var Version string

View File

@ -51,7 +51,7 @@ func GetArgs(args string, state *state.HelmState) []string {
value := argVal[1]
argsMap.SetArg(arg, value, false)
} else {
//check if next value is arg to flag
// check if next value is arg to flag
if index+1 < len(argsVals) {
nextVal := argsVals[index+1]
if strings.HasPrefix(nextVal, "--") {

View File

@ -10,7 +10,6 @@ import (
// TestGetArgs tests the GetArgs function
func TestGetArgs(t *testing.T) {
tests := []struct {
args string
expected string
@ -86,6 +85,5 @@ func TestSetArg(t *testing.T) {
require.NotContainsf(t, ap.flags, test.flag, "expected flag %s to be not set", test.flag)
require.NotContainsf(t, ap.m, test.flag, "expected m %s to be not set", test.flag)
}
}
}

View File

@ -9,9 +9,10 @@ import (
"github.com/helmfile/helmfile/pkg/state"
"github.com/urfave/cli"
"go.uber.org/zap"
"golang.org/x/crypto/ssh/terminal"
"golang.org/x/term"
)
// nolint: golint
type ConfigImpl struct {
c *cli.Context
@ -239,10 +240,10 @@ func (c ConfigImpl) Color() bool {
// we can't rely on helm-diff's ability to auto-detect term for color output.
// See https://github.com/roboll/helmfile/issues/2043
term := terminal.IsTerminal(int(os.Stdout.Fd()))
terminal := term.IsTerminal(int(os.Stdout.Fd()))
// https://github.com/databus23/helm-diff/issues/281
dumb := os.Getenv("TERM") == "dumb"
return term && !dumb
return terminal && !dumb
}
func (c ConfigImpl) NoColor() bool {

View File

@ -1,8 +1,9 @@
package environment
import (
"github.com/google/go-cmp/cmp"
"testing"
"github.com/google/go-cmp/cmp"
)
// See https://github.com/roboll/helmfile/issues/1150

View File

@ -18,12 +18,10 @@ func (context *HelmContext) GetTillerlessArgs(helm *execer) []string {
if context.Tillerless && !helm.IsHelm3() {
if context.TillerNamespace != "" {
return []string{"tiller", "run", context.TillerNamespace, "--", helm.helmBinary}
} else {
}
return []string{"tiller", "run", "--", helm.helmBinary}
}
} else {
return []string{}
}
}
func (context *HelmContext) getTillerlessEnv() map[string]string {
@ -41,7 +39,6 @@ func (context *HelmContext) getTillerlessEnv() map[string]string {
}
}
return result
} else {
return map[string]string{}
}
return map[string]string{}
}

View File

@ -52,7 +52,6 @@ func TestGetTillerlessArgs(t *testing.T) {
version: *sr,
}
require.Equalf(t, test.expected, hc.GetTillerlessArgs(he), "expected result %s, received result %s", test.expected, hc.GetTillerlessArgs(he))
}
}
@ -97,6 +96,5 @@ func TestGetTillerlessEnv(t *testing.T) {
t.Setenv(kubeconfigEnv, test.kubeconfig)
result := hc.getTillerlessEnv()
require.Equalf(t, test.expected, result, "expected result %s, received result %s", test.expected, result)
}
}

View File

@ -74,7 +74,6 @@ func parseHelmVersion(versionStr string) (semver.Version, error) {
}
func getHelmVersion(helmBinary string, runner Runner) (semver.Version, error) {
// Autodetect from `helm version`
outBytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil)
if err != nil {
@ -84,15 +83,16 @@ func getHelmVersion(helmBinary string, runner Runner) (semver.Version, error) {
return parseHelmVersion(string(outBytes))
}
func redactedUrl(chart string) string {
chartUrl, err := url.ParseRequestURI(chart)
func redactedURL(chart string) string {
chartURL, err := url.ParseRequestURI(chart)
if err != nil {
return chart
}
return chartUrl.Redacted()
return chartURL.Redacted()
}
// New for running helm commands
// nolint: golint
func New(helmBinary string, logger *zap.SugaredLogger, kubeContext string, runner Runner) *execer {
// TODO: proper error handling
version, err := getHelmVersion(helmBinary, runner)
@ -206,7 +206,7 @@ func (helm *execer) UpdateDeps(chart string) error {
}
func (helm *execer) SyncRelease(context HelmContext, name, chart string, flags ...string) error {
helm.logger.Infof("Upgrading release=%v, chart=%v", name, redactedUrl(chart))
helm.logger.Infof("Upgrading release=%v, chart=%v", name, redactedURL(chart))
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
@ -270,7 +270,6 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str
// Cache miss
if !ok {
secret = &decryptedSecret{}
helm.decryptedSecrets[absPath] = secret
@ -288,7 +287,6 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str
}
secret.bytes = secretBytes
} else {
// Cache hit
helm.logger.Debugf("Found secret in cache %v", absPath)
@ -312,7 +310,9 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str
if err != nil {
return "", err
}
defer tmpFile.Close()
defer func() {
_ = tmpFile.Close()
}()
_, err = tmpFile.Write(content)
if err != nil {
@ -334,7 +334,7 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str
}
func (helm *execer) TemplateRelease(name string, chart string, flags ...string) error {
helm.logger.Infof("Templating release=%v, chart=%v", name, redactedUrl(chart))
helm.logger.Infof("Templating release=%v, chart=%v", name, redactedURL(chart))
var args []string
if helm.IsHelm3() {
args = []string{"template", name, chart}
@ -373,9 +373,9 @@ func (helm *execer) TemplateRelease(name string, chart string, flags ...string)
func (helm *execer) DiffRelease(context HelmContext, name, chart string, suppressDiff bool, flags ...string) error {
if context.Writer != nil {
fmt.Fprintf(context.Writer, "Comparing release=%v, chart=%v\n", name, redactedUrl(chart))
fmt.Fprintf(context.Writer, "Comparing release=%v, chart=%v\n", name, redactedURL(chart))
} else {
helm.logger.Infof("Comparing release=%v, chart=%v", name, redactedUrl(chart))
helm.logger.Infof("Comparing release=%v, chart=%v", name, redactedURL(chart))
}
preArgs := context.GetTillerlessArgs(helm)
env := context.getTillerlessEnv()
@ -390,15 +390,13 @@ func (helm *execer) DiffRelease(context HelmContext, name, chart string, suppres
}
}
if detailedExitcodeEnabled {
switch e := err.(type) {
case ExitError:
if e.ExitStatus() == 2 {
e, ok := err.(ExitError)
if ok && e.ExitStatus() == 2 {
if !(suppressDiff) {
helm.write(context.Writer, out)
}
return err
}
}
} else if !(suppressDiff) {
helm.write(context.Writer, out)
}
@ -413,7 +411,7 @@ func (helm *execer) Lint(name, chart string, flags ...string) error {
}
func (helm *execer) Fetch(chart string, flags ...string) error {
helm.logger.Infof("Fetching %v", redactedUrl(chart))
helm.logger.Infof("Fetching %v", redactedURL(chart))
out, err := helm.exec(append([]string{"fetch", chart}, flags...), map[string]string{})
helm.info(out)
return err
@ -432,7 +430,9 @@ func (helm *execer) ChartPull(chart string, flags ...string) error {
if err != nil {
return err
}
defer os.RemoveAll(tempDir)
defer func() {
_ = os.RemoveAll(tempDir)
}()
helmArgs = []string{"fetch", ociChartURL, "--version", ociChartTag, "--destination", tempDir}
} else {
helmArgs = []string{"chart", "pull", chart}

View File

@ -32,6 +32,7 @@ func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string
return mock.output, mock.err
}
// nolint: golint
func MockExecer(logger *zap.SugaredLogger, kubeContext string) *execer {
execer := New("helm", logger, kubeContext, &mockRunner{})
return execer
@ -816,14 +817,14 @@ func Test_GetVersion(t *testing.T) {
helm := New("helm", NewLogger(os.Stdout, "info"), "dev", &helm2Runner)
ver := helm.GetVersion()
if ver.Major != 2 || ver.Minor != 16 || ver.Patch != 1 {
t.Error(fmt.Sprintf("helmexec.GetVersion - did not detect correct Helm2 version; it was: %+v", ver))
t.Errorf("helmexec.GetVersion - did not detect correct Helm2 version; it was: %+v", ver)
}
helm3Runner := mockRunner{output: []byte("v3.2.4+ge29ce2a\n")}
helm = New("helm", NewLogger(os.Stdout, "info"), "dev", &helm3Runner)
ver = helm.GetVersion()
if ver.Major != 3 || ver.Minor != 2 || ver.Patch != 4 {
t.Error(fmt.Sprintf("helmexec.GetVersion - did not detect correct Helm3 version; it was: %+v", ver))
t.Errorf("helmexec.GetVersion - did not detect correct Helm3 version; it was: %+v", ver)
}
}

View File

@ -1,8 +1,9 @@
package helmexec
import (
"go.uber.org/zap"
"strings"
"go.uber.org/zap"
)
type logWriterGenerator struct {

View File

@ -10,57 +10,57 @@ func CastKeysToStrings(s interface{}) (map[string]interface{}, error) {
switch src := s.(type) {
case map[interface{}]interface{}:
for k, v := range src {
var str_k string
switch typed_k := k.(type) {
var strK string
switch typedK := k.(type) {
case string:
str_k = typed_k
strK = typedK
default:
return nil, fmt.Errorf("unexpected type of key in map: expected string, got %T: value=%v, map=%v", typed_k, typed_k, src)
return nil, fmt.Errorf("unexpected type of key in map: expected string, got %T: value=%v, map=%v", typedK, typedK, src)
}
casted_v, err := recursivelyStringifyMapKey(v)
castedV, err := recursivelyStringifyMapKey(v)
if err != nil {
return nil, err
}
new[str_k] = casted_v
new[strK] = castedV
}
case map[string]interface{}:
for k, v := range src {
casted_v, err := recursivelyStringifyMapKey(v)
castedV, err := recursivelyStringifyMapKey(v)
if err != nil {
return nil, err
}
new[k] = casted_v
new[k] = castedV
}
}
return new, nil
}
func recursivelyStringifyMapKey(v interface{}) (interface{}, error) {
var casted_v interface{}
switch typed_v := v.(type) {
var castedV interface{}
switch typedV := v.(type) {
case map[interface{}]interface{}, map[string]interface{}:
tmp, err := CastKeysToStrings(typed_v)
tmp, err := CastKeysToStrings(typedV)
if err != nil {
return nil, err
}
casted_v = tmp
castedV = tmp
case []interface{}:
a := []interface{}{}
for i := range typed_v {
res, err := recursivelyStringifyMapKey(typed_v[i])
for i := range typedV {
res, err := recursivelyStringifyMapKey(typedV[i])
if err != nil {
return nil, err
}
a = append(a, res)
}
casted_v = a
castedV = a
default:
casted_v = typed_v
castedV = typedV
}
return casted_v, nil
return castedV, nil
}
type arg interface {
@ -169,7 +169,7 @@ func ParseKey(key string) []string {
r = append(r, part)
part = ""
} else {
part = part + string(rune)
part += string(rune)
}
}
if len(part) > 0 {

View File

@ -1,8 +1,9 @@
package plugins
import (
"github.com/variantdev/vals"
"sync"
"github.com/variantdev/vals"
)
const (

View File

@ -103,8 +103,7 @@ func (r *Remote) Locate(urlOrPath string) (string, error) {
}
fetched, err := r.Fetch(urlOrPath)
if err != nil {
switch err.(type) {
case InvalidURLError:
if _, ok := err.(InvalidURLError); ok {
return urlOrPath, nil
}
return "", err
@ -134,8 +133,7 @@ func IsRemote(goGetterSrc string) bool {
func Parse(goGetterSrc string) (*Source, error) {
items := strings.Split(goGetterSrc, "::")
var getter string
switch len(items) {
case 2:
if len(items) == 2 {
getter = items[0]
goGetterSrc = items[1]
}
@ -199,7 +197,7 @@ func (r *Remote) Fetch(goGetterSrc string, cacheDirOpt ...string) (string, error
if q.Has("sshkey") {
q.Set("sshkey", "redacted")
}
paramsKey := strings.Replace(q.Encode(), "&", "_", -1)
paramsKey := strings.ReplaceAll(q.Encode(), "&", "_")
cacheKey = fmt.Sprintf("%s.%s", dirKey, paramsKey)
} else {
cacheKey = dirKey

View File

@ -206,7 +206,9 @@ func (st *HelmState) updateDependenciesInTempDir(shell helmexec.DependencyUpdate
if err != nil {
return nil, fmt.Errorf("unable to create dir: %v", err)
}
defer os.RemoveAll(d)
defer func() {
_ = os.RemoveAll(d)
}()
return updateDependencies(st, shell, unresolved, filename, d)
}
@ -219,9 +221,9 @@ func getUnresolvedDependenciess(st *HelmState) (string, *UnresolvedDependencies,
}
unresolved := &UnresolvedDependencies{deps: map[string][]unresolvedChartDependency{}}
//if err := unresolved.Add("stable/envoy", "https://kubernetes-charts.storage.googleapis.com", ""); err != nil {
// if err := unresolved.Add("stable/envoy", "https://kubernetes-charts.storage.googleapis.com", ""); err != nil {
// panic(err)
//}
// }
for _, r := range st.Releases {
repo, chart, ok := resolveRemoteChart(r.Chart)
@ -269,6 +271,7 @@ type chartDependencyManager struct {
writeFile func(string, []byte, os.FileMode) error
}
// nolint: golint
func NewChartDependencyManager(name string, logger *zap.SugaredLogger) *chartDependencyManager {
return &chartDependencyManager{
Name: name,
@ -324,7 +327,6 @@ func (m *chartDependencyManager) updateHelm2(shell helmexec.DependencyUpdater, w
}
func (m *chartDependencyManager) doUpdate(chartLockFile string, unresolved *UnresolvedDependencies, shell helmexec.DependencyUpdater, wd string) (*ResolvedDependencies, error) {
// Generate `requirements.lock` of the temporary local chart by coping `<basename>.lock`
lockFile := m.lockFileName()

View File

@ -22,6 +22,7 @@ const (
DefaultHelmBinary = "helm"
)
// nolint: golint
type StateLoadError struct {
msg string
Cause error
@ -231,7 +232,6 @@ func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEn
}
if len(envSpec.Secrets) > 0 {
var envSecretFiles []string
for _, urlOrPath := range envSpec.Secrets {
resolved, skipped, err := st.storage().resolveFile(envSpec.MissingFileHandler, "environment values", urlOrPath)
@ -305,6 +305,7 @@ func (c *StateCreator) scatterGatherEnvSecretFiles(st *HelmState, envSecretFiles
results <- secretResult{secret.id, nil, err, secret.path}
continue
}
// nolint: staticcheck
defer func() {
if err := c.DeleteFile(decFile); err != nil {
c.logger.Warnf("removing decrypted file %s: %w", decFile, err)

View File

@ -102,7 +102,7 @@ func (r ReleaseSpec) ExecuteTemplateExpressions(renderer *tmpl.FileRenderer) (*R
return nil, fmt.Errorf("failed executing template expressions in release \"%s\".values[%d] = \"%v\": %v", r.Name, i, ts, err)
}
s, err := renderer.RenderTemplateContentToBuffer([]byte(serialized))
s, err := renderer.RenderTemplateContentToBuffer(serialized)
if err != nil {
return nil, fmt.Errorf("failed executing template expressions in release \"%s\".values[%d] = \"%v\": %v", r.Name, i, serialized, err)
}

View File

@ -873,7 +873,7 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme
affectedReleases.Upgraded = append(affectedReleases.Upgraded, release)
m.Unlock()
installedVersion, err := st.getDeployedVersion(context, helm, release)
if err != nil { //err is not really impacting so just log it
if err != nil { // err is not really impacting so just log it
st.logger.Debugf("getting deployed release version failed:%v", err)
} else {
release.installedVersion = installedVersion
@ -1121,6 +1121,7 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre
chartification, clean, err := st.PrepareChartify(helm, release, chartPath, workerIndex)
if !opts.SkipCleanup {
// nolint: staticcheck
defer clean()
}
if err != nil {
@ -1350,7 +1351,6 @@ func (o *TemplateOpts) Apply(opts *TemplateOpts) {
// TemplateReleases wrapper for executing helm template on the releases
func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string, additionalValues []string, args []string, workerLimit int,
validate bool, opt ...TemplateOpt) []error {
opts := &TemplateOpts{}
for _, o := range opt {
o.Apply(opts)
@ -2100,7 +2100,7 @@ func markExcludedReleases(releases []ReleaseSpec, selectors []string, commonLabe
// Strip off just the last portion for the name stable/newrelic would give newrelic
chartSplit := strings.Split(r.Chart, "/")
r.Labels["chart"] = chartSplit[len(chartSplit)-1]
//Merge CommonLabels into release labels
// Merge CommonLabels into release labels
for k, v := range commonLabels {
r.Labels[k] = v
}
@ -2579,7 +2579,6 @@ func (st *HelmState) chartVersionFlags(release *ReleaseSpec) []string {
}
func (st *HelmState) appendApiVersionsFlags(flags []string, r *ReleaseSpec) []string {
if len(r.ApiVersions) != 0 {
for _, a := range r.ApiVersions {
flags = append(flags, "--api-versions", a)
@ -2745,7 +2744,9 @@ func (st *HelmState) generateTemporaryReleaseValuesFiles(release *ReleaseSpec, v
if err != nil {
return generatedFiles, err
}
defer valfile.Close()
defer func() {
_ = valfile.Close()
}()
if _, err := valfile.Write(yamlBytes); err != nil {
return generatedFiles, fmt.Errorf("failed to write %s: %v", valfile.Name(), err)
@ -2759,10 +2760,14 @@ func (st *HelmState) generateTemporaryReleaseValuesFiles(release *ReleaseSpec, v
if err != nil {
return generatedFiles, err
}
defer valfile.Close()
defer func() {
_ = valfile.Close()
}()
encoder := yaml.NewEncoder(valfile)
defer encoder.Close()
defer func() {
_ = encoder.Close()
}()
if err := encoder.Encode(typedValue); err != nil {
return generatedFiles, err
@ -3031,13 +3036,13 @@ func (ar *AffectedReleases) DisplayAffectedReleases(logger *zap.SugaredLogger) {
}
func escape(value string) string {
intermediate := strings.Replace(value, "{", "\\{", -1)
intermediate = strings.Replace(intermediate, "}", "\\}", -1)
return strings.Replace(intermediate, ",", "\\,", -1)
intermediate := strings.ReplaceAll(value, "{", "\\{")
intermediate = strings.ReplaceAll(intermediate, "}", "\\}")
return strings.ReplaceAll(intermediate, ",", "\\,")
}
//MarshalYAML will ensure we correctly marshal SubHelmfileSpec structure correctly so it can be unmarshalled at some
//future time
// MarshalYAML will ensure we correctly marshal SubHelmfileSpec structure correctly so it can be unmarshalled at some
// future time
func (p SubHelmfileSpec) MarshalYAML() (interface{}, error) {
type SubHelmfileSpecTmp struct {
Path string `yaml:"path,omitempty"`
@ -3053,10 +3058,9 @@ func (p SubHelmfileSpec) MarshalYAML() (interface{}, error) {
}, nil
}
//UnmarshalYAML will unmarshal the helmfile yaml section and fill the SubHelmfileSpec structure
//this is required to keep allowing string scalar for defining helmfile
// UnmarshalYAML will unmarshal the helmfile yaml section and fill the SubHelmfileSpec structure
// this is required to keep allowing string scalar for defining helmfile
func (hf *SubHelmfileSpec) UnmarshalYAML(unmarshal func(interface{}) error) error {
var tmp interface{}
if err := unmarshal(&tmp); err != nil {
return err
@ -3081,12 +3085,12 @@ func (hf *SubHelmfileSpec) UnmarshalYAML(unmarshal func(interface{}) error) erro
hf.SelectorsInherited = subHelmfileSpecTmp.SelectorsInherited
hf.Environment = subHelmfileSpecTmp.Environment
}
//since we cannot make sur the "console" string can be red after the "path" we must check we don't have
//a SubHelmfileSpec with only selector and no path
// since we cannot make sur the "console" string can be red after the "path" we must check we don't have
// a SubHelmfileSpec with only selector and no path
if hf.Selectors != nil && hf.Path == "" {
return fmt.Errorf("found 'selectors' definition without path: %v", hf.Selectors)
}
//also exclude SelectorsInherited to true and explicit selectors
// also exclude SelectorsInherited to true and explicit selectors
if hf.SelectorsInherited && len(hf.Selectors) > 0 {
return fmt.Errorf("you cannot use 'SelectorsInherited: true' along with and explicit selector for path: %v", hf.Path)
}

View File

@ -44,7 +44,6 @@ func getBoolRefFromStringTemplate(templateRef string) (*bool, error) {
}
func updateBoolTemplatedValues(r *ReleaseSpec) error {
if r.InstalledTemplate != nil {
if installed, err := getBoolRefFromStringTemplate(*r.InstalledTemplate); err != nil {
return fmt.Errorf("installedTemplate: %v", err)

View File

@ -201,7 +201,6 @@ func TestHelmState_executeTemplates(t *testing.T) {
}
func TestHelmState_recursiveRefsTemplates(t *testing.T) {
tests := []struct {
name string
input ReleaseSpec

View File

@ -17,7 +17,6 @@ type result struct {
}
func (st *HelmState) scatterGather(concurrency int, items int, produceInputs func(), receiveInputsAndProduceIntermediates func(int), aggregateIntermediates func()) {
if concurrency < 1 || concurrency > items {
concurrency = items
}
@ -53,7 +52,6 @@ func (st *HelmState) scatterGather(concurrency int, items int, produceInputs fun
func (st *HelmState) scatterGatherReleases(helm helmexec.Interface, concurrency int,
do func(ReleaseSpec, int) error) []error {
return st.iterateOnReleases(helm, concurrency, st.Releases, do)
}
@ -144,7 +142,6 @@ func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Releas
d := dag.New()
for i, r := range releases {
id := ReleaseToID(&r.ReleaseSpec)
idToReleases[id] = append(idToReleases[id], r)

View File

@ -1244,7 +1244,6 @@ func TestHelmState_SyncReleases_MissingValuesFileForUndesiredRelease(t *testing.
t.Fatalf("unexpected error(s): expected=0, got=%d: %v", len(errs), errs)
}
}
})
}
}
@ -1392,7 +1391,6 @@ func TestHelmState_SyncReleasesAffectedRealeases(t *testing.T) {
}
func testEq(a []*ReleaseSpec, b []*exectest.Release) bool {
// If one is nil, the other must also be nil.
if (a == nil) != (b == nil) {
return false
@ -1473,7 +1471,7 @@ func TestGetDeployedVersion(t *testing.T) {
helm := &exectest.Helm{
Lists: map[exectest.ListKey]string{},
}
//simulate the helm.list call result
// simulate the helm.list call result
helm.Lists[exectest.ListKey{Filter: "^" + tt.release.Name + "$", Flags: "--deleting--deployed--failed--pending"}] = tt.listResult
affectedReleases := AffectedReleases{}
@ -1652,10 +1650,8 @@ func TestHelmState_DiffFlags(t *testing.T) {
t.Errorf("HelmState.flagsForDiff() for [%s][%s] = %v, want %v", tt.name, tt.releases[j].Name, flags, tt.wantDiffFlags)
}
}
})
}
}
func TestHelmState_SyncReleasesCleanup(t *testing.T) {

View File

@ -2,11 +2,13 @@ package state
import (
"fmt"
"github.com/helmfile/helmfile/pkg/remote"
"go.uber.org/zap"
"net/url"
"path/filepath"
"sort"
"go.uber.org/zap"
"github.com/helmfile/helmfile/pkg/remote"
)
type Storage struct {

View File

@ -83,7 +83,10 @@ func HashObject(obj interface{}) (string, error) {
DisableMethods: true,
SpewKeys: true,
}
printer.Fprintf(hash, "%#v", obj)
_, err := printer.Fprintf(hash, "%#v", obj)
if err != nil {
return "", err
}
sum := fmt.Sprint(hash.Sum32())

View File

@ -75,7 +75,7 @@ func TestGenerateID(t *testing.T) {
for id, n := range ids {
if n > 1 {
t.Fatalf("too many occurences of %s: %d", id, n)
t.Fatalf("too many occurrences of %s: %d", id, n)
}
}
}

View File

@ -7,7 +7,7 @@ import (
)
func isLocalChart(chart string) bool {
regex, _ := regexp.Compile("^[.]?./")
regex := regexp.MustCompile("^[.]?./")
matched := regex.MatchString(chart)
if matched {
return true

View File

@ -73,7 +73,7 @@ func (f *TestFs) ReadFile(filename string) ([]byte, error) {
return []byte(nil), os.ErrNotExist
}
f.fileReaderCalls += 1
f.fileReaderCalls++
f.successfulReads = append(f.successfulReads, filename)

View File

@ -35,6 +35,6 @@ func CaptureStdout(f func()) string {
}()
wg.Wait()
f()
writer.Close()
_ = writer.Close()
return <-out
}

View File

@ -130,7 +130,9 @@ func (c *Context) EnvExec(envs map[string]interface{}, command string, args []in
}
g.Go(func() error {
defer stdin.Close()
defer func() {
_ = stdin.Close()
}()
size := len(input)

View File

@ -104,6 +104,7 @@ func TestReadFile_PassAbsPath(t *testing.T) {
func TestToYaml_UnsupportedNestedMapKey(t *testing.T) {
expected := ``
// nolint: unconvert
vals := Values(map[string]interface{}{
"foo": map[interface{}]interface{}{
"bar": "BAR",
@ -125,6 +126,7 @@ func TestToYaml(t *testing.T) {
expected := `foo:
bar: BAR
`
// nolint: unconvert
vals := Values(map[string]interface{}{
"foo": map[string]interface{}{
"bar": "BAR",
@ -143,6 +145,7 @@ func TestFromYaml(t *testing.T) {
raw := `foo:
bar: BAR
`
// nolint: unconvert
expected := Values(map[string]interface{}{
"foo": map[string]interface{}{
"bar": "BAR",
@ -276,7 +279,6 @@ func TestRequired(t *testing.T) {
// TestRequiredEnv tests that RequiredEnv returns an error if the environment variable is not set.
func TestRequiredEnv(t *testing.T) {
// test that the environment variable is not set
envKey := "HelmFile"
envVal, err := RequiredEnv(envKey)
@ -298,7 +300,6 @@ func TestRequiredEnv(t *testing.T) {
envVal, err = RequiredEnv(envKey)
require.Nilf(t, err, "Expected no error to be returned when environment variable %s is set to a non-empty string", envKey)
require.Equalf(t, expected, envVal, "Expected %s to be returned when environment variable %s is set to a non-empty string", expected, envKey)
}
// TestExec tests that Exec returns the expected output.

View File

@ -2,8 +2,9 @@ package tmpl
import (
"bytes"
"github.com/Masterminds/sprig/v3"
"text/template"
"github.com/Masterminds/sprig/v3"
)
func (c *Context) CreateFuncMap() template.FuncMap {

View File

@ -8,7 +8,7 @@ import (
"github.com/variantdev/vals"
)
//to generate mock run mockgen -source=expand_secret_ref.go -destination=expand_secrets_mock.go -package=tmpl
// to generate mock run mockgen -source=expand_secret_ref.go -destination=expand_secrets_mock.go -package=tmpl
type valClient interface {
Eval(template map[string]interface{}) (map[string]interface{}, error)
}

View File

@ -2,9 +2,10 @@ package tmpl
import (
"fmt"
"github.com/helmfile/helmfile/pkg/environment"
"reflect"
"testing"
"github.com/helmfile/helmfile/pkg/environment"
)
var emptyEnvTmplData = map[string]interface{}{
@ -50,8 +51,7 @@ func TestRenderToBytes_Yaml(t *testing.T) {
`
valuesFile := "values.yaml"
r := NewFileRenderer(func(filename string) ([]byte, error) {
switch filename {
case valuesFile:
if filename == valuesFile {
return []byte(valuesYamlContent), nil
}
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", valuesFile, filename)

View File

@ -28,7 +28,7 @@ func get(path string, varArgs ...interface{}) (interface{}, error) {
def = varArgs[0]
obj = varArgs[1]
default:
return nil, fmt.Errorf("unexpected number of args pased to the template function get(path, [def, ]obj): expected 1 or 2, got %d, args was %v", len(varArgs), varArgs)
return nil, fmt.Errorf("unexpected number of args passed to the template function get(path, [def, ]obj): expected 1 or 2, got %d, args was %v", len(varArgs), varArgs)
}
if path == "" {

View File

@ -10,6 +10,7 @@ type TextRenderer interface {
RenderTemplateText(text string) (string, error)
}
// nolint: golint
func NewTextRenderer(readFile func(filename string) ([]byte, error), basePath string, data interface{}) *templateTextRenderer {
return &templateTextRenderer{
ReadText: readFile,

View File

@ -93,15 +93,15 @@ func run(cmd *cobra.Command, args []string) {
for _, p := range ps.list {
switch {
case p.left != nil && p.right == nil:
fmt.Fprintf(os.Stderr, "Only in %s: %s\n", leftPath, p.left.getId())
fmt.Fprintf(os.Stderr, "Only in %s: %s\n", leftPath, p.left.getID())
exitCode = 1
case p.left == nil && p.right != nil:
fmt.Fprintf(os.Stderr, "Only in %s: %s\n", rightPath, p.right.getId())
fmt.Fprintf(os.Stderr, "Only in %s: %s\n", rightPath, p.right.getID())
exitCode = 1
default:
diff := deep.Equal(p.left, p.right)
if diff != nil {
id := p.left.getId()
id := p.left.getID()
fmt.Fprintf(os.Stderr, "< %s %s\n", id, leftPath)
fmt.Fprintf(os.Stderr, "> %s %s\n", id, rightPath)
for _, d := range diff {
@ -160,7 +160,9 @@ func readManifest(path string) ([]resource, error) {
if err != nil {
return nil, err
}
defer f.Close()
defer func() {
_ = f.Close()
}()
decoder := yaml.NewYAMLToJSONDecoder(f)
resources := []resource{}
for {
@ -179,7 +181,7 @@ func readManifest(path string) ([]resource, error) {
return resources, nil
}
func (res resource) getId() string {
func (res resource) getID() string {
meta, err := res.getMeta()
if err != nil {
return fmt.Sprintf("%v", res)
@ -202,7 +204,6 @@ func (res resource) getId() string {
}
gvk := strings.Join([]string{gv, k}, "_")
return strings.Join([]string{gvk, ns, nm}, "|")
}
// lifted from kustomize/kyaml/kio/filters/merge3.go
@ -267,7 +268,6 @@ func (p *pair) add(node resource, source diffSource) error {
return fmt.Errorf("unknown diff source value: %s", source)
}
return nil
}
func main() {

View File

@ -242,5 +242,4 @@ func TestTmplStrings(t *testing.T) {
require.Equal(t, tc.output, tplResult.String())
})
}
}

View File

@ -113,10 +113,10 @@ func computeDiff(formatter aurora.Aurora, a interface{}, b interface{}) (string,
switch {
case strings.HasPrefix(s, "+"):
diffs = append(diffs, formatter.Bold(formatter.Green(s)).String())
ndiffs += 1
ndiffs++
case strings.HasPrefix(s, "-"):
diffs = append(diffs, formatter.Bold(formatter.Red(s)).String())
ndiffs += 1
ndiffs++
default:
diffs = append(diffs, s)
}