Compare commits
	
		
			5 Commits
		
	
	
		
			3145aca7c0
			...
			b008221434
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | b008221434 | |
|  | d4535e2cbc | |
|  | d21e87b639 | |
|  | d3908e6a3c | |
|  | daebbfb0ad | 
							
								
								
									
										12
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										12
									
								
								go.mod
								
								
								
								
							|  | @ -6,7 +6,7 @@ require ( | |||
| 	dario.cat/mergo v1.0.2 | ||||
| 	github.com/Masterminds/semver/v3 v3.4.0 | ||||
| 	github.com/Masterminds/sprig/v3 v3.3.0 | ||||
| 	github.com/aws/aws-sdk-go-v2/config v1.31.13 | ||||
| 	github.com/aws/aws-sdk-go-v2/config v1.31.15 | ||||
| 	github.com/aws/aws-sdk-go-v2/service/s3 v1.88.7 | ||||
| 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc | ||||
| 	github.com/go-test/deep v1.1.1 | ||||
|  | @ -145,8 +145,8 @@ require ( | |||
| 	github.com/atotto/clipboard v0.1.4 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2 v1.39.4 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.2 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/credentials v1.18.17 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/credentials v1.18.19 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.11 // indirect | ||||
|  | @ -159,9 +159,9 @@ require ( | |||
| 	github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.6 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/sso v1.29.8 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3 // indirect | ||||
| 	github.com/aws/aws-sdk-go-v2/service/sts v1.38.9 // indirect | ||||
| 	github.com/aws/smithy-go v1.23.1 // indirect | ||||
| 	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect | ||||
| 	github.com/blang/semver/v4 v4.0.0 // indirect | ||||
|  |  | |||
							
								
								
									
										24
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										24
									
								
								go.sum
								
								
								
								
							|  | @ -144,12 +144,12 @@ github.com/aws/aws-sdk-go-v2 v1.39.4 h1:qTsQKcdQPHnfGYBBs+Btl8QwxJeoWcOcPcixK90m | |||
| github.com/aws/aws-sdk-go-v2 v1.39.4/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM= | ||||
| github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.2 h1:t9yYsydLYNBk9cJ73rgPhPWqOh/52fcWDQB5b1JsKSY= | ||||
| github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.2/go.mod h1:IusfVNTmiSN3t4rhxWFaBAqn+mcNdwKtPcV16eYdgko= | ||||
| github.com/aws/aws-sdk-go-v2/config v1.31.13 h1:wcqQB3B0PgRPUF5ZE/QL1JVOyB0mbPevHFoAMpemR9k= | ||||
| github.com/aws/aws-sdk-go-v2/config v1.31.13/go.mod h1:ySB5D5ybwqGbT6c3GszZ+u+3KvrlYCUQNo62+hkKOFk= | ||||
| github.com/aws/aws-sdk-go-v2/credentials v1.18.17 h1:skpEwzN/+H8cdrrtT8y+rvWJGiWWv0DeNAe+4VTf+Vs= | ||||
| github.com/aws/aws-sdk-go-v2/credentials v1.18.17/go.mod h1:Ed+nXsaYa5uBINovJhcAWkALvXw2ZLk36opcuiSZfJM= | ||||
| github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10 h1:UuGVOX48oP4vgQ36oiKmW9RuSeT8jlgQgBFQD+HUiHY= | ||||
| github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.10/go.mod h1:vM/Ini41PzvudT4YkQyE/+WiQJiQ6jzeDyU8pQKwCac= | ||||
| github.com/aws/aws-sdk-go-v2/config v1.31.15 h1:gE3M4xuNXfC/9bG4hyowGm/35uQTi7bUKeYs5e/6uvU= | ||||
| github.com/aws/aws-sdk-go-v2/config v1.31.15/go.mod h1:HvnvGJoE2I95KAIW8kkWVPJ4XhdrlvwJpV6pEzFQa8o= | ||||
| github.com/aws/aws-sdk-go-v2/credentials v1.18.19 h1:Jc1zzwkSY1QbkEcLujwqRTXOdvW8ppND3jRBb/VhBQc= | ||||
| github.com/aws/aws-sdk-go-v2/credentials v1.18.19/go.mod h1:DIfQ9fAk5H0pGtnqfqkbSIzky82qYnGvh06ASQXXg6A= | ||||
| github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11 h1:X7X4YKb+c0rkI6d4uJ5tEMxXgCZ+jZ/D6mvkno8c8Uw= | ||||
| github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.11/go.mod h1:EqM6vPZQsZHYvC4Cai35UDg/f5NCEU+vp0WfbVqVcZc= | ||||
| github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9 h1:Z1897HnnfLLgbs3pcUv8xLvtbai9TEfPUZfA0BFw968= | ||||
| github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.9/go.mod h1:8oVESJIPBYGWdZhaHcIvTm7BnI6hbsR3ggKn0uyRMhk= | ||||
| github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.11 h1:7AANQZkF3ihM8fbdftpjhken0TP9sBzFbV/Ze/Y4HXA= | ||||
|  | @ -176,12 +176,12 @@ github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.6 h1:9PWl450XOG+m5lKv+ | |||
| github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.6/go.mod h1:hwt7auGsDcaNQ8pzLgE2kCNyIWouYlAKSjuUu5Dqr7I= | ||||
| github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1 h1:TFg6XiS7EsHN0/jpV3eVNczZi/sPIVP5jxIs+euIESQ= | ||||
| github.com/aws/aws-sdk-go-v2/service/ssm v1.65.1/go.mod h1:OIezd9K0sM/64DDP4kXx/i0NdgXu6R5KE6SCsIPJsjc= | ||||
| github.com/aws/aws-sdk-go-v2/service/sso v1.29.7 h1:fspVFg6qMx0svs40YgRmE7LZXh9VRZvTT35PfdQR6FM= | ||||
| github.com/aws/aws-sdk-go-v2/service/sso v1.29.7/go.mod h1:BQTKL3uMECaLaUV3Zc2L4Qybv8C6BIXjuu1dOPyxTQs= | ||||
| github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2 h1:scVnW+NLXasGOhy7HhkdT9AGb6kjgW7fJ5xYkUaqHs0= | ||||
| github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.2/go.mod h1:FRNCY3zTEWZXBKm2h5UBUPvCVDOecTad9KhynDyGBc0= | ||||
| github.com/aws/aws-sdk-go-v2/service/sts v1.38.7 h1:VEO5dqFkMsl8QZ2yHsFDJAIZLAkEbaYDB+xdKi0Feic= | ||||
| github.com/aws/aws-sdk-go-v2/service/sts v1.38.7/go.mod h1:L1xxV3zAdB+qVrVW/pBIrIAnHFWHo6FBbFe4xOGsG/o= | ||||
| github.com/aws/aws-sdk-go-v2/service/sso v1.29.8 h1:M5nimZmugcZUO9wG7iVtROxPhiqyZX6ejS1lxlDPbTU= | ||||
| github.com/aws/aws-sdk-go-v2/service/sso v1.29.8/go.mod h1:mbef/pgKhtKRwrigPPs7SSSKZgytzP8PQ6P6JAAdqyM= | ||||
| github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3 h1:S5GuJZpYxE0lKeMHKn+BRTz6PTFpgThyJ+5mYfux7BM= | ||||
| github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.3/go.mod h1:X4OF+BTd7HIb3L+tc4UlWHVrpgwZZIVENU15pRDVTI0= | ||||
| github.com/aws/aws-sdk-go-v2/service/sts v1.38.9 h1:Ekml5vGg6sHSZLZJQJagefnVe6PmqC2oiRkBq4F7fU0= | ||||
| github.com/aws/aws-sdk-go-v2/service/sts v1.38.9/go.mod h1:/e15V+o1zFHWdH3u7lpI3rVBcxszktIKuHKCY2/py+k= | ||||
| github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= | ||||
| github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= | ||||
| github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= | ||||
|  |  | |||
|  | @ -521,52 +521,7 @@ func (a *App) PrintDAGState(c DAGConfigProvider) error { | |||
| 
 | ||||
| func (a *App) PrintState(c StateConfigProvider) error { | ||||
| 	return a.ForEachState(func(run *Run) (_ bool, errs []error) { | ||||
| 		var err error | ||||
| 
 | ||||
| 		if !c.SkipCharts() { | ||||
| 			err = run.withPreparedCharts("build", state.ChartPrepareOptions{ | ||||
| 				SkipRepos:   true, | ||||
| 				SkipDeps:    true, | ||||
| 				Concurrency: 2, | ||||
| 			}, func() { | ||||
| 				if c.EmbedValues() { | ||||
| 					for i := range run.state.Releases { | ||||
| 						r := run.state.Releases[i] | ||||
| 
 | ||||
| 						values, err := run.state.LoadYAMLForEmbedding(&r, r.Values, r.MissingFileHandler, r.ValuesPathPrefix) | ||||
| 						if err != nil { | ||||
| 							errs = []error{err} | ||||
| 							return | ||||
| 						} | ||||
| 
 | ||||
| 						run.state.Releases[i].Values = values | ||||
| 
 | ||||
| 						secrets, err := run.state.LoadYAMLForEmbedding(&r, r.Secrets, r.MissingFileHandler, r.ValuesPathPrefix) | ||||
| 						if err != nil { | ||||
| 							errs = []error{err} | ||||
| 							return | ||||
| 						} | ||||
| 
 | ||||
| 						run.state.Releases[i].Secrets = secrets | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				stateYaml, err := run.state.ToYaml() | ||||
| 				if err != nil { | ||||
| 					errs = []error{err} | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				sourceFile, err := run.state.FullFilePath() | ||||
| 				if err != nil { | ||||
| 					errs = []error{err} | ||||
| 					return | ||||
| 				} | ||||
| 				fmt.Printf("---\n#  Source: %s\n\n%+v", sourceFile, stateYaml) | ||||
| 
 | ||||
| 				errs = []error{} | ||||
| 			}) | ||||
| 		} else { | ||||
| 		printState := func() { | ||||
| 			if c.EmbedValues() { | ||||
| 				for i := range run.state.Releases { | ||||
| 					r := run.state.Releases[i] | ||||
|  | @ -574,7 +529,7 @@ func (a *App) PrintState(c StateConfigProvider) error { | |||
| 					values, err := run.state.LoadYAMLForEmbedding(&r, r.Values, r.MissingFileHandler, r.ValuesPathPrefix) | ||||
| 					if err != nil { | ||||
| 						errs = []error{err} | ||||
| 						return false, errs | ||||
| 						return | ||||
| 					} | ||||
| 
 | ||||
| 					run.state.Releases[i].Values = values | ||||
|  | @ -582,7 +537,7 @@ func (a *App) PrintState(c StateConfigProvider) error { | |||
| 					secrets, err := run.state.LoadYAMLForEmbedding(&r, r.Secrets, r.MissingFileHandler, r.ValuesPathPrefix) | ||||
| 					if err != nil { | ||||
| 						errs = []error{err} | ||||
| 						return false, errs | ||||
| 						return | ||||
| 					} | ||||
| 
 | ||||
| 					run.state.Releases[i].Secrets = secrets | ||||
|  | @ -592,21 +547,30 @@ func (a *App) PrintState(c StateConfigProvider) error { | |||
| 			stateYaml, err := run.state.ToYaml() | ||||
| 			if err != nil { | ||||
| 				errs = []error{err} | ||||
| 				return false, errs | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
| 			sourceFile, err := run.state.FullFilePath() | ||||
| 			if err != nil { | ||||
| 				errs = []error{err} | ||||
| 				return false, errs | ||||
| 				return | ||||
| 			} | ||||
| 			fmt.Printf("---\n#  Source: %s\n\n%+v", sourceFile, stateYaml) | ||||
| 
 | ||||
| 			errs = []error{} | ||||
| 		} | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 		if !c.SkipCharts() { | ||||
| 			err := run.withPreparedCharts("build", state.ChartPrepareOptions{ | ||||
| 				SkipRepos:   true, | ||||
| 				SkipDeps:    true, | ||||
| 				Concurrency: 2, | ||||
| 			}, printState) | ||||
| 			if err != nil { | ||||
| 				errs = append(errs, err) | ||||
| 			} | ||||
| 		} else { | ||||
| 			printState() | ||||
| 		} | ||||
| 
 | ||||
| 		return false, errs | ||||
|  | @ -633,20 +597,22 @@ func (a *App) ListReleases(c ListConfigProvider) error { | |||
| 		var stateReleases []*HelmRelease | ||||
| 		var err error | ||||
| 
 | ||||
| 		listReleases := func() { | ||||
| 			rel, err := a.list(run) | ||||
| 			if err != nil { | ||||
| 				panic(err) | ||||
| 			} | ||||
| 			stateReleases = rel | ||||
| 		} | ||||
| 
 | ||||
| 		if !c.SkipCharts() { | ||||
| 			err = run.withPreparedCharts("list", state.ChartPrepareOptions{ | ||||
| 				SkipRepos:   true, | ||||
| 				SkipDeps:    true, | ||||
| 				Concurrency: 2, | ||||
| 			}, func() { | ||||
| 				rel, err := a.list(run) | ||||
| 				if err != nil { | ||||
| 					panic(err) | ||||
| 				} | ||||
| 				stateReleases = rel | ||||
| 			}) | ||||
| 			}, listReleases) | ||||
| 		} else { | ||||
| 			stateReleases, err = a.list(run) | ||||
| 			listReleases() | ||||
| 		} | ||||
| 
 | ||||
| 		if err != nil { | ||||
|  |  | |||
|  | @ -116,11 +116,19 @@ func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState, | |||
| 			return nil, &StateLoadError{fmt.Sprintf("failed to read %s: reading document at index %d", file, i), err} | ||||
| 		} | ||||
| 
 | ||||
| 		if err := mergo.Merge(&state, &intermediate, mergo.WithAppendSlice); err != nil { | ||||
| 		if err := mergo.Merge(&state, &intermediate, mergo.WithAppendSlice, mergo.WithOverride); err != nil { | ||||
| 			return nil, &StateLoadError{fmt.Sprintf("failed to read %s: merging document at index %d", file, i), err} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	state.logger = c.logger | ||||
| 	state.valsRuntime = c.valsRuntime | ||||
| 
 | ||||
| 	return &state, nil | ||||
| } | ||||
| 
 | ||||
| // applyDefaultsAndOverrides applies default binary paths and command-line overrides
 | ||||
| func (c *StateCreator) applyDefaultsAndOverrides(state *HelmState) { | ||||
| 	if c.overrideHelmBinary != "" && c.overrideHelmBinary != DefaultHelmBinary { | ||||
| 		state.DefaultHelmBinary = c.overrideHelmBinary | ||||
| 	} else if state.DefaultHelmBinary == "" { | ||||
|  | @ -134,11 +142,6 @@ func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState, | |||
| 		// Let `helmfile --kustomize-binary ""` not break this helmfile run
 | ||||
| 		state.DefaultKustomizeBinary = DefaultKustomizeBinary | ||||
| 	} | ||||
| 
 | ||||
| 	state.logger = c.logger | ||||
| 	state.valsRuntime = c.valsRuntime | ||||
| 
 | ||||
| 	return &state, nil | ||||
| } | ||||
| 
 | ||||
| // LoadEnvValues loads environment values files relative to the `baseDir`
 | ||||
|  | @ -181,6 +184,11 @@ func (c *StateCreator) ParseAndLoad(content []byte, baseDir, file string, envNam | |||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		// Apply default binaries and command-line overrides only for the main helmfile
 | ||||
| 		// after loading and merging all bases. This ensures that values from bases are
 | ||||
| 		// properly respected and that later bases/documents can override earlier ones.
 | ||||
| 		c.applyDefaultsAndOverrides(state) | ||||
| 	} | ||||
| 
 | ||||
| 	state, err = c.LoadEnvValues(state, envName, failOnMissingEnv, envValues, overrode) | ||||
|  | @ -216,7 +224,7 @@ func (c *StateCreator) loadBases(envValues, overrodeEnv *environment.Environment | |||
| 	layers = append(layers, st) | ||||
| 
 | ||||
| 	for i := 1; i < len(layers); i++ { | ||||
| 		if err := mergo.Merge(layers[0], layers[i], mergo.WithAppendSlice); err != nil { | ||||
| 		if err := mergo.Merge(layers[0], layers[i], mergo.WithAppendSlice, mergo.WithOverride); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| package state | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"path/filepath" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
|  | @ -525,3 +526,205 @@ releaseContext: | |||
| 		t.Errorf("unexpected values: expected=%v, actual=%v", expectedValues, actualValues) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // TestHelmBinaryInBases tests that helmBinary and kustomizeBinary settings
 | ||||
| // from bases are properly merged with later values overriding earlier ones
 | ||||
| func TestHelmBinaryInBases(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name                    string | ||||
| 		files                   map[string]string | ||||
| 		mainFile                string | ||||
| 		expectedHelmBinary      string | ||||
| 		expectedKustomizeBinary string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "helmBinary in second base should be used", | ||||
| 			files: map[string]string{ | ||||
| 				"/path/to/helmfile.yaml": `bases: | ||||
|   - ./bases/env.yaml | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/repos.yaml | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/releases.yaml | ||||
| `, | ||||
| 				"/path/to/bases/env.yaml": `environments: | ||||
|   default: | ||||
|     values: | ||||
|     - key: value1 | ||||
| `, | ||||
| 				"/path/to/bases/repos.yaml": `repositories: | ||||
|   - name: stable | ||||
|     url: https://charts.helm.sh/stable
 | ||||
| helmBinary: /path/to/custom/helm | ||||
| `, | ||||
| 				"/path/to/bases/releases.yaml": `releases: | ||||
|   - name: myapp | ||||
|     chart: stable/nginx | ||||
| `, | ||||
| 			}, | ||||
| 			mainFile:                "/path/to/helmfile.yaml", | ||||
| 			expectedHelmBinary:      "/path/to/custom/helm", | ||||
| 			expectedKustomizeBinary: DefaultKustomizeBinary, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "helmBinary in main file after bases should override", | ||||
| 			files: map[string]string{ | ||||
| 				"/path/to/helmfile.yaml": `bases: | ||||
|   - ./bases/env.yaml | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/repos.yaml | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/releases.yaml | ||||
| helmBinary: /path/to/main/helm | ||||
| `, | ||||
| 				"/path/to/bases/env.yaml": `environments: | ||||
|   default: | ||||
|     values: | ||||
|     - key: value1 | ||||
| `, | ||||
| 				"/path/to/bases/repos.yaml": `repositories: | ||||
|   - name: stable | ||||
|     url: https://charts.helm.sh/stable
 | ||||
| helmBinary: /path/to/base/helm | ||||
| `, | ||||
| 				"/path/to/bases/releases.yaml": `releases: | ||||
|   - name: myapp | ||||
|     chart: stable/nginx | ||||
| `, | ||||
| 			}, | ||||
| 			mainFile:                "/path/to/helmfile.yaml", | ||||
| 			expectedHelmBinary:      "/path/to/main/helm", | ||||
| 			expectedKustomizeBinary: DefaultKustomizeBinary, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "helmBinary in main file between bases should override earlier bases", | ||||
| 			files: map[string]string{ | ||||
| 				"/path/to/helmfile.yaml": `bases: | ||||
|   - ./bases/env.yaml | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/repos.yaml | ||||
| helmBinary: /path/to/middle/helm | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/releases.yaml | ||||
| `, | ||||
| 				"/path/to/bases/env.yaml": `environments: | ||||
|   default: | ||||
|     values: | ||||
|     - key: value1 | ||||
| `, | ||||
| 				"/path/to/bases/repos.yaml": `repositories: | ||||
|   - name: stable | ||||
|     url: https://charts.helm.sh/stable
 | ||||
| helmBinary: /path/to/base/helm | ||||
| `, | ||||
| 				"/path/to/bases/releases.yaml": `releases: | ||||
|   - name: myapp | ||||
|     chart: stable/nginx | ||||
| `, | ||||
| 			}, | ||||
| 			mainFile:                "/path/to/helmfile.yaml", | ||||
| 			expectedHelmBinary:      "/path/to/middle/helm", | ||||
| 			expectedKustomizeBinary: DefaultKustomizeBinary, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "kustomizeBinary in base should be used", | ||||
| 			files: map[string]string{ | ||||
| 				"/path/to/helmfile.yaml": `bases: | ||||
|   - ./bases/base.yaml | ||||
| `, | ||||
| 				"/path/to/bases/base.yaml": `kustomizeBinary: /path/to/custom/kustomize | ||||
| releases: | ||||
|   - name: myapp | ||||
|     chart: mychart | ||||
| `, | ||||
| 			}, | ||||
| 			mainFile:                "/path/to/helmfile.yaml", | ||||
| 			expectedHelmBinary:      DefaultHelmBinary, | ||||
| 			expectedKustomizeBinary: "/path/to/custom/kustomize", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "both helmBinary and kustomizeBinary in different bases", | ||||
| 			files: map[string]string{ | ||||
| 				"/path/to/helmfile.yaml": `bases: | ||||
|   - ./bases/helm.yaml | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/kustomize.yaml | ||||
| `, | ||||
| 				"/path/to/bases/helm.yaml": `helmBinary: /path/to/custom/helm | ||||
| `, | ||||
| 				"/path/to/bases/kustomize.yaml": `kustomizeBinary: /path/to/custom/kustomize | ||||
| `, | ||||
| 			}, | ||||
| 			mainFile:                "/path/to/helmfile.yaml", | ||||
| 			expectedHelmBinary:      "/path/to/custom/helm", | ||||
| 			expectedKustomizeBinary: "/path/to/custom/kustomize", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "later base overrides earlier base for helmBinary", | ||||
| 			files: map[string]string{ | ||||
| 				"/path/to/helmfile.yaml": `bases: | ||||
|   - ./bases/first.yaml | ||||
| --- | ||||
| bases: | ||||
|   - ./bases/second.yaml | ||||
| `, | ||||
| 				"/path/to/bases/first.yaml": `helmBinary: /path/to/first/helm | ||||
| `, | ||||
| 				"/path/to/bases/second.yaml": `helmBinary: /path/to/second/helm | ||||
| `, | ||||
| 			}, | ||||
| 			mainFile:                "/path/to/helmfile.yaml", | ||||
| 			expectedHelmBinary:      "/path/to/second/helm", | ||||
| 			expectedKustomizeBinary: DefaultKustomizeBinary, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			testFs := testhelper.NewTestFs(tt.files) | ||||
| 			if testFs.Cwd == "" { | ||||
| 				testFs.Cwd = "/" | ||||
| 			} | ||||
| 
 | ||||
| 			r := remote.NewRemote(logger, testFs.Cwd, testFs.ToFileSystem()) | ||||
| 			creator := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", "", r, false, "") | ||||
| 
 | ||||
| 			// Set up LoadFile for recursive base loading
 | ||||
| 			creator.LoadFile = func(inheritedEnv, overrodeEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*HelmState, error) { | ||||
| 				path := filepath.Join(baseDir, file) | ||||
| 				content, ok := tt.files[path] | ||||
| 				if !ok { | ||||
| 					return nil, fmt.Errorf("file not found: %s", path) | ||||
| 				} | ||||
| 				return creator.ParseAndLoad([]byte(content), filepath.Dir(path), path, DefaultEnv, true, evaluateBases, inheritedEnv, overrodeEnv) | ||||
| 			} | ||||
| 
 | ||||
| 			yamlContent, ok := tt.files[tt.mainFile] | ||||
| 			if !ok { | ||||
| 				t.Fatalf("no file named %q registered", tt.mainFile) | ||||
| 			} | ||||
| 
 | ||||
| 			state, err := creator.ParseAndLoad([]byte(yamlContent), filepath.Dir(tt.mainFile), tt.mainFile, DefaultEnv, true, true, nil, nil) | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("unexpected error: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			if state.DefaultHelmBinary != tt.expectedHelmBinary { | ||||
| 				t.Errorf("helmBinary mismatch: expected=%s, actual=%s", | ||||
| 					tt.expectedHelmBinary, state.DefaultHelmBinary) | ||||
| 			} | ||||
| 
 | ||||
| 			if state.DefaultKustomizeBinary != tt.expectedKustomizeBinary { | ||||
| 				t.Errorf("kustomizeBinary mismatch: expected=%s, actual=%s", | ||||
| 					tt.expectedKustomizeBinary, state.DefaultKustomizeBinary) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue