parent
cc13492623
commit
ac23def893
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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{})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
4
go.mod
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
1
main.go
1
main.go
|
|
@ -8,7 +8,6 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
|
||||
rootCmd := cmd.RootCommand()
|
||||
err := rootCmd.Run(os.Args)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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": `
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
|
|
|
|||
|
|
@ -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" }}
|
||||
`
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, "--") {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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{}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package helmexec
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type logWriterGenerator struct {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package plugins
|
||||
|
||||
import (
|
||||
"github.com/variantdev/vals"
|
||||
"sync"
|
||||
|
||||
"github.com/variantdev/vals"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -201,7 +201,6 @@ func TestHelmState_executeTemplates(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHelmState_recursiveRefsTemplates(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input ReleaseSpec
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
func isLocalChart(chart string) bool {
|
||||
regex, _ := regexp.Compile("^[.]?./")
|
||||
regex := regexp.MustCompile("^[.]?./")
|
||||
matched := regex.MatchString(chart)
|
||||
if matched {
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,6 @@ func CaptureStdout(f func()) string {
|
|||
}()
|
||||
wg.Wait()
|
||||
f()
|
||||
writer.Close()
|
||||
_ = writer.Close()
|
||||
return <-out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 == "" {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -242,5 +242,4 @@ func TestTmplStrings(t *testing.T) {
|
|||
require.Equal(t, tc.output, tplResult.String())
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue