fix: Relative path in helmfile not relative to file in multi file setup (#448)
Fixes #431
This commit is contained in:
		
							parent
							
								
									99ce8570c7
								
							
						
					
					
						commit
						bf42d2519d
					
				
							
								
								
									
										313
									
								
								app_test.go
								
								
								
								
							
							
						
						
									
										313
									
								
								app_test.go
								
								
								
								
							|  | @ -8,20 +8,122 @@ import ( | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"reflect" | 	"reflect" | ||||||
|  | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | type testFs struct { | ||||||
|  | 	wd    string | ||||||
|  | 	dirs  map[string]bool | ||||||
|  | 	files map[string]string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func appWithFs(app *app, files map[string]string) *app { | ||||||
|  | 	fs := newTestFs(files) | ||||||
|  | 	return injectFs(app, fs) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func injectFs(app *app, fs *testFs) *app { | ||||||
|  | 	app.readFile = fs.readFile | ||||||
|  | 	app.glob = fs.glob | ||||||
|  | 	app.abs = fs.abs | ||||||
|  | 	app.getwd = fs.getwd | ||||||
|  | 	app.chdir = fs.chdir | ||||||
|  | 	app.fileExistsAt = fs.fileExistsAt | ||||||
|  | 	app.directoryExistsAt = fs.directoryExistsAt | ||||||
|  | 	return app | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func newTestFs(files map[string]string) *testFs { | ||||||
|  | 	dirs := map[string]bool{} | ||||||
|  | 	for abs, _ := range files { | ||||||
|  | 		d := filepath.Dir(abs) | ||||||
|  | 		dirs[d] = true | ||||||
|  | 	} | ||||||
|  | 	return &testFs{ | ||||||
|  | 		wd:    "/path/to", | ||||||
|  | 		dirs:  dirs, | ||||||
|  | 		files: files, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *testFs) fileExistsAt(path string) bool { | ||||||
|  | 	var ok bool | ||||||
|  | 	if strings.Contains(path, "/") { | ||||||
|  | 		_, ok = f.files[path] | ||||||
|  | 	} else { | ||||||
|  | 		_, ok = f.files[filepath.Join(f.wd, path)] | ||||||
|  | 	} | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *testFs) directoryExistsAt(path string) bool { | ||||||
|  | 	var ok bool | ||||||
|  | 	if strings.Contains(path, "/") { | ||||||
|  | 		_, ok = f.dirs[path] | ||||||
|  | 	} else { | ||||||
|  | 		_, ok = f.dirs[filepath.Join(f.wd, path)] | ||||||
|  | 	} | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *testFs) readFile(filename string) ([]byte, error) { | ||||||
|  | 	var str string | ||||||
|  | 	var ok bool | ||||||
|  | 	if strings.Contains(filename, "/") { | ||||||
|  | 		str, ok = f.files[filename] | ||||||
|  | 	} else { | ||||||
|  | 		str, ok = f.files[filepath.Join(f.wd, filename)] | ||||||
|  | 	} | ||||||
|  | 	if !ok { | ||||||
|  | 		return []byte(nil), fmt.Errorf("no file found: %s", filename) | ||||||
|  | 	} | ||||||
|  | 	return []byte(str), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *testFs) glob(pattern string) ([]string, error) { | ||||||
|  | 	matches := []string{} | ||||||
|  | 	for name, _ := range f.files { | ||||||
|  | 		matched, err := filepath.Match(pattern, name) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		if matched { | ||||||
|  | 			matches = append(matches, name) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if len(matches) == 0 { | ||||||
|  | 		return []string(nil), fmt.Errorf("no file matched: %s", pattern) | ||||||
|  | 	} | ||||||
|  | 	return matches, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *testFs) abs(path string) (string, error) { | ||||||
|  | 	var p string | ||||||
|  | 	if path[0] == '/' { | ||||||
|  | 		p = path | ||||||
|  | 	} else { | ||||||
|  | 		p = filepath.Join(f.wd, path) | ||||||
|  | 	} | ||||||
|  | 	return filepath.Clean(p), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *testFs) getwd() (string, error) { | ||||||
|  | 	return f.wd, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *testFs) chdir(dir string) error { | ||||||
|  | 	if dir == "/path/to" || dir == "/path/to/helmfile.d" { | ||||||
|  | 		f.wd = dir | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return fmt.Errorf("unexpected chdir \"%s\"", dir) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // See https://github.com/roboll/helmfile/issues/193
 | // See https://github.com/roboll/helmfile/issues/193
 | ||||||
| func TestVisitDesiredStatesWithReleasesFiltered(t *testing.T) { | func TestVisitDesiredStatesWithReleasesFiltered(t *testing.T) { | ||||||
| 	absPaths := map[string]string{ |  | ||||||
| 		".":                   "/path/to", |  | ||||||
| 		"/path/to/helmfile.d": "/path/to/helmfile.d", |  | ||||||
| 	} |  | ||||||
| 	dirs := map[string]bool{ |  | ||||||
| 		"helmfile.d": true, |  | ||||||
| 	} |  | ||||||
| 	files := map[string]string{ | 	files := map[string]string{ | ||||||
| 		"helmfile.yaml": ` | 		"/path/to/helmfile.yaml": ` | ||||||
| helmfiles: | helmfiles: | ||||||
| - helmfile.d/a*.yaml | - helmfile.d/a*.yaml | ||||||
| - helmfile.d/b*.yaml | - helmfile.d/b*.yaml | ||||||
|  | @ -42,39 +144,6 @@ releases: | ||||||
|   chart: stable/grafana |   chart: stable/grafana | ||||||
| `, | `, | ||||||
| 	} | 	} | ||||||
| 	globMatches := map[string][]string{ |  | ||||||
| 		"/path/to/helmfile.d/a*.yaml": []string{"/path/to/helmfile.d/a1.yaml", "/path/to/helmfile.d/a2.yaml"}, |  | ||||||
| 		"/path/to/helmfile.d/b*.yaml": []string{"/path/to/helmfile.d/b.yaml"}, |  | ||||||
| 	} |  | ||||||
| 	fileExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := files[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	directoryExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := dirs[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	readFile := func(filename string) ([]byte, error) { |  | ||||||
| 		str, ok := files[filename] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []byte(nil), fmt.Errorf("no file found: %s", filename) |  | ||||||
| 		} |  | ||||||
| 		return []byte(str), nil |  | ||||||
| 	} |  | ||||||
| 	glob := func(pattern string) ([]string, error) { |  | ||||||
| 		matches, ok := globMatches[pattern] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []string(nil), fmt.Errorf("no file matched: %s", pattern) |  | ||||||
| 		} |  | ||||||
| 		return matches, nil |  | ||||||
| 	} |  | ||||||
| 	abs := func(path string) (string, error) { |  | ||||||
| 		a, ok := absPaths[path] |  | ||||||
| 		if !ok { |  | ||||||
| 			return "", fmt.Errorf("abs: unexpected path: %s", path) |  | ||||||
| 		} |  | ||||||
| 		return a, nil |  | ||||||
| 	} |  | ||||||
| 	noop := func(st *state.HelmState, helm helmexec.Interface) []error { | 	noop := func(st *state.HelmState, helm helmexec.Interface) []error { | ||||||
| 		return []error{} | 		return []error{} | ||||||
| 	} | 	} | ||||||
|  | @ -90,18 +159,13 @@ releases: | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, testcase := range testcases { | 	for _, testcase := range testcases { | ||||||
| 		app := &app{ | 		app := appWithFs(&app{ | ||||||
| 			readFile:          readFile, |  | ||||||
| 			glob:              glob, |  | ||||||
| 			abs:               abs, |  | ||||||
| 			fileExistsAt:      fileExistsAt, |  | ||||||
| 			directoryExistsAt: directoryExistsAt, |  | ||||||
| 			kubeContext: "default", | 			kubeContext: "default", | ||||||
| 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | ||||||
| 			selectors:   []string{fmt.Sprintf("name=%s", testcase.name)}, | 			selectors:   []string{fmt.Sprintf("name=%s", testcase.name)}, | ||||||
| 			namespace:   "", | 			namespace:   "", | ||||||
| 			env:         "default", | 			env:         "default", | ||||||
| 		} | 		}, files) | ||||||
| 		err := app.VisitDesiredStatesWithReleasesFiltered( | 		err := app.VisitDesiredStatesWithReleasesFiltered( | ||||||
| 			"helmfile.yaml", noop, | 			"helmfile.yaml", noop, | ||||||
| 		) | 		) | ||||||
|  | @ -115,15 +179,8 @@ releases: | ||||||
| 
 | 
 | ||||||
| // See https://github.com/roboll/helmfile/issues/320
 | // See https://github.com/roboll/helmfile/issues/320
 | ||||||
| func TestVisitDesiredStatesWithReleasesFiltered_UndefinedEnv(t *testing.T) { | func TestVisitDesiredStatesWithReleasesFiltered_UndefinedEnv(t *testing.T) { | ||||||
| 	absPaths := map[string]string{ |  | ||||||
| 		".":                   "/path/to", |  | ||||||
| 		"/path/to/helmfile.d": "/path/to/helmfile.d", |  | ||||||
| 	} |  | ||||||
| 	dirs := map[string]bool{ |  | ||||||
| 		"helmfile.d": true, |  | ||||||
| 	} |  | ||||||
| 	files := map[string]string{ | 	files := map[string]string{ | ||||||
| 		"helmfile.yaml": ` | 		"/path/to/helmfile.yaml": ` | ||||||
| environments: | environments: | ||||||
|   prod: |   prod: | ||||||
| 
 | 
 | ||||||
|  | @ -139,38 +196,6 @@ releases: | ||||||
|   chart: stable/zipkin |   chart: stable/zipkin | ||||||
| `, | `, | ||||||
| 	} | 	} | ||||||
| 	globMatches := map[string][]string{ |  | ||||||
| 		"/path/to/helmfile.d/a*.yaml": []string{"/path/to/helmfile.d/a1.yaml"}, |  | ||||||
| 	} |  | ||||||
| 	fileExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := files[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	directoryExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := dirs[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	readFile := func(filename string) ([]byte, error) { |  | ||||||
| 		str, ok := files[filename] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []byte(nil), fmt.Errorf("no file found: %s", filename) |  | ||||||
| 		} |  | ||||||
| 		return []byte(str), nil |  | ||||||
| 	} |  | ||||||
| 	glob := func(pattern string) ([]string, error) { |  | ||||||
| 		matches, ok := globMatches[pattern] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []string(nil), fmt.Errorf("no file matched: %s", pattern) |  | ||||||
| 		} |  | ||||||
| 		return matches, nil |  | ||||||
| 	} |  | ||||||
| 	abs := func(path string) (string, error) { |  | ||||||
| 		a, ok := absPaths[path] |  | ||||||
| 		if !ok { |  | ||||||
| 			return "", fmt.Errorf("abs: unexpected path: %s", path) |  | ||||||
| 		} |  | ||||||
| 		return a, nil |  | ||||||
| 	} |  | ||||||
| 	noop := func(st *state.HelmState, helm helmexec.Interface) []error { | 	noop := func(st *state.HelmState, helm helmexec.Interface) []error { | ||||||
| 		return []error{} | 		return []error{} | ||||||
| 	} | 	} | ||||||
|  | @ -185,18 +210,13 @@ releases: | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, testcase := range testcases { | 	for _, testcase := range testcases { | ||||||
| 		app := &app{ | 		app := appWithFs(&app{ | ||||||
| 			readFile:          readFile, |  | ||||||
| 			glob:              glob, |  | ||||||
| 			abs:               abs, |  | ||||||
| 			fileExistsAt:      fileExistsAt, |  | ||||||
| 			directoryExistsAt: directoryExistsAt, |  | ||||||
| 			kubeContext: "default", | 			kubeContext: "default", | ||||||
| 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | ||||||
| 			namespace:   "", | 			namespace:   "", | ||||||
| 			selectors:   []string{}, | 			selectors:   []string{}, | ||||||
| 			env:         testcase.name, | 			env:         testcase.name, | ||||||
| 		} | 		}, files) | ||||||
| 		err := app.VisitDesiredStatesWithReleasesFiltered( | 		err := app.VisitDesiredStatesWithReleasesFiltered( | ||||||
| 			"helmfile.yaml", noop, | 			"helmfile.yaml", noop, | ||||||
| 		) | 		) | ||||||
|  | @ -210,15 +230,8 @@ releases: | ||||||
| 
 | 
 | ||||||
| // See https://github.com/roboll/helmfile/issues/322
 | // See https://github.com/roboll/helmfile/issues/322
 | ||||||
| func TestVisitDesiredStatesWithReleasesFiltered_Selectors(t *testing.T) { | func TestVisitDesiredStatesWithReleasesFiltered_Selectors(t *testing.T) { | ||||||
| 	absPaths := map[string]string{ |  | ||||||
| 		".":                   "/path/to", |  | ||||||
| 		"/path/to/helmfile.d": "/path/to/helmfile.d", |  | ||||||
| 	} |  | ||||||
| 	dirs := map[string]bool{ |  | ||||||
| 		"helmfile.d": true, |  | ||||||
| 	} |  | ||||||
| 	files := map[string]string{ | 	files := map[string]string{ | ||||||
| 		"helmfile.yaml": ` | 		"/path/to/helmfile.yaml": ` | ||||||
| helmfiles: | helmfiles: | ||||||
| - helmfile.d/a*.yaml | - helmfile.d/a*.yaml | ||||||
| - helmfile.d/b*.yaml | - helmfile.d/b*.yaml | ||||||
|  | @ -247,39 +260,6 @@ releases: | ||||||
|     duplicated: yes |     duplicated: yes | ||||||
| `, | `, | ||||||
| 	} | 	} | ||||||
| 	globMatches := map[string][]string{ |  | ||||||
| 		"/path/to/helmfile.d/a*.yaml": []string{"/path/to/helmfile.d/a1.yaml", "/path/to/helmfile.d/a2.yaml"}, |  | ||||||
| 		"/path/to/helmfile.d/b*.yaml": []string{"/path/to/helmfile.d/b.yaml"}, |  | ||||||
| 	} |  | ||||||
| 	fileExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := files[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	directoryExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := dirs[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	readFile := func(filename string) ([]byte, error) { |  | ||||||
| 		str, ok := files[filename] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []byte(nil), fmt.Errorf("no file found: %s", filename) |  | ||||||
| 		} |  | ||||||
| 		return []byte(str), nil |  | ||||||
| 	} |  | ||||||
| 	glob := func(pattern string) ([]string, error) { |  | ||||||
| 		matches, ok := globMatches[pattern] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []string(nil), fmt.Errorf("no file matched: %s", pattern) |  | ||||||
| 		} |  | ||||||
| 		return matches, nil |  | ||||||
| 	} |  | ||||||
| 	abs := func(path string) (string, error) { |  | ||||||
| 		a, ok := absPaths[path] |  | ||||||
| 		if !ok { |  | ||||||
| 			return "", fmt.Errorf("abs: unexpected path: %s", path) |  | ||||||
| 		} |  | ||||||
| 		return a, nil |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	testcases := []struct { | 	testcases := []struct { | ||||||
| 		label         string | 		label         string | ||||||
|  | @ -305,18 +285,13 @@ releases: | ||||||
| 			return []error{} | 			return []error{} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		app := &app{ | 		app := appWithFs(&app{ | ||||||
| 			readFile:          readFile, |  | ||||||
| 			glob:              glob, |  | ||||||
| 			abs:               abs, |  | ||||||
| 			fileExistsAt:      fileExistsAt, |  | ||||||
| 			directoryExistsAt: directoryExistsAt, |  | ||||||
| 			kubeContext: "default", | 			kubeContext: "default", | ||||||
| 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | ||||||
| 			namespace:   "", | 			namespace:   "", | ||||||
| 			selectors:   []string{testcase.label}, | 			selectors:   []string{testcase.label}, | ||||||
| 			env:         "default", | 			env:         "default", | ||||||
| 		} | 		}, files) | ||||||
| 
 | 
 | ||||||
| 		err := app.VisitDesiredStatesWithReleasesFiltered( | 		err := app.VisitDesiredStatesWithReleasesFiltered( | ||||||
| 			"helmfile.yaml", collectReleases, | 			"helmfile.yaml", collectReleases, | ||||||
|  | @ -338,15 +313,8 @@ releases: | ||||||
| 
 | 
 | ||||||
| // See https://github.com/roboll/helmfile/issues/312
 | // See https://github.com/roboll/helmfile/issues/312
 | ||||||
| func TestVisitDesiredStatesWithReleasesFiltered_ReverseOrder(t *testing.T) { | func TestVisitDesiredStatesWithReleasesFiltered_ReverseOrder(t *testing.T) { | ||||||
| 	absPaths := map[string]string{ |  | ||||||
| 		".":                   "/path/to", |  | ||||||
| 		"/path/to/helmfile.d": "/path/to/helmfile.d", |  | ||||||
| 	} |  | ||||||
| 	dirs := map[string]bool{ |  | ||||||
| 		"helmfile.d": true, |  | ||||||
| 	} |  | ||||||
| 	files := map[string]string{ | 	files := map[string]string{ | ||||||
| 		"helmfile.yaml": ` | 		"/path/to/helmfile.yaml": ` | ||||||
| helmfiles: | helmfiles: | ||||||
| - helmfile.d/a*.yaml | - helmfile.d/a*.yaml | ||||||
| - helmfile.d/b*.yaml | - helmfile.d/b*.yaml | ||||||
|  | @ -369,39 +337,6 @@ releases: | ||||||
|   chart: stable/grafana |   chart: stable/grafana | ||||||
| `, | `, | ||||||
| 	} | 	} | ||||||
| 	globMatches := map[string][]string{ |  | ||||||
| 		"/path/to/helmfile.d/a*.yaml": []string{"/path/to/helmfile.d/a1.yaml", "/path/to/helmfile.d/a2.yaml"}, |  | ||||||
| 		"/path/to/helmfile.d/b*.yaml": []string{"/path/to/helmfile.d/b.yaml"}, |  | ||||||
| 	} |  | ||||||
| 	fileExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := files[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	directoryExistsAt := func(path string) bool { |  | ||||||
| 		_, ok := dirs[path] |  | ||||||
| 		return ok |  | ||||||
| 	} |  | ||||||
| 	readFile := func(filename string) ([]byte, error) { |  | ||||||
| 		str, ok := files[filename] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []byte(nil), fmt.Errorf("no file found: %s", filename) |  | ||||||
| 		} |  | ||||||
| 		return []byte(str), nil |  | ||||||
| 	} |  | ||||||
| 	glob := func(pattern string) ([]string, error) { |  | ||||||
| 		matches, ok := globMatches[pattern] |  | ||||||
| 		if !ok { |  | ||||||
| 			return []string(nil), fmt.Errorf("no file matched: %s", pattern) |  | ||||||
| 		} |  | ||||||
| 		return matches, nil |  | ||||||
| 	} |  | ||||||
| 	abs := func(path string) (string, error) { |  | ||||||
| 		a, ok := absPaths[path] |  | ||||||
| 		if !ok { |  | ||||||
| 			return "", fmt.Errorf("abs: unexpected path: %s", path) |  | ||||||
| 		} |  | ||||||
| 		return a, nil |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	expected := []string{"grafana", "elasticsearch", "prometheus", "zipkin"} | 	expected := []string{"grafana", "elasticsearch", "prometheus", "zipkin"} | ||||||
| 
 | 
 | ||||||
|  | @ -421,20 +356,14 @@ releases: | ||||||
| 			} | 			} | ||||||
| 			return []error{} | 			return []error{} | ||||||
| 		} | 		} | ||||||
| 
 | 		app := appWithFs(&app{ | ||||||
| 		app := &app{ |  | ||||||
| 			readFile:          readFile, |  | ||||||
| 			glob:              glob, |  | ||||||
| 			abs:               abs, |  | ||||||
| 			fileExistsAt:      fileExistsAt, |  | ||||||
| 			directoryExistsAt: directoryExistsAt, |  | ||||||
| 			kubeContext: "default", | 			kubeContext: "default", | ||||||
| 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | 			logger:      helmexec.NewLogger(os.Stderr, "debug"), | ||||||
| 			reverse:     testcase.reverse, | 			reverse:     testcase.reverse, | ||||||
| 			namespace:   "", | 			namespace:   "", | ||||||
| 			selectors:   []string{}, | 			selectors:   []string{}, | ||||||
| 			env:         "default", | 			env:         "default", | ||||||
| 		} | 		}, files) | ||||||
| 		err := app.VisitDesiredStatesWithReleasesFiltered( | 		err := app.VisitDesiredStatesWithReleasesFiltered( | ||||||
| 			"helmfile.yaml", collectReleases, | 			"helmfile.yaml", collectReleases, | ||||||
| 		) | 		) | ||||||
|  |  | ||||||
							
								
								
									
										89
									
								
								main.go
								
								
								
								
							
							
						
						
									
										89
									
								
								main.go
								
								
								
								
							|  | @ -571,6 +571,9 @@ type app struct { | ||||||
| 	env               string | 	env               string | ||||||
| 	namespace         string | 	namespace         string | ||||||
| 	selectors         []string | 	selectors         []string | ||||||
|  | 
 | ||||||
|  | 	getwd func() (string, error) | ||||||
|  | 	chdir func(string) error | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func findAndIterateOverDesiredStatesUsingFlags(c *cli.Context, converge func(*state.HelmState, helmexec.Interface, context) []error) error { | func findAndIterateOverDesiredStatesUsingFlags(c *cli.Context, converge func(*state.HelmState, helmexec.Interface, context) []error) error { | ||||||
|  | @ -598,6 +601,8 @@ func initAppEntry(c *cli.Context, reverse bool) (*app, string, error) { | ||||||
| 		readFile:          ioutil.ReadFile, | 		readFile:          ioutil.ReadFile, | ||||||
| 		glob:              filepath.Glob, | 		glob:              filepath.Glob, | ||||||
| 		abs:               filepath.Abs, | 		abs:               filepath.Abs, | ||||||
|  | 		getwd:             os.Getwd, | ||||||
|  | 		chdir:             os.Chdir, | ||||||
| 		fileExistsAt:      fileExistsAt, | 		fileExistsAt:      fileExistsAt, | ||||||
| 		directoryExistsAt: directoryExistsAt, | 		directoryExistsAt: directoryExistsAt, | ||||||
| 		kubeContext:       kubeContext, | 		kubeContext:       kubeContext, | ||||||
|  | @ -778,16 +783,69 @@ func (r *twoPassRenderer) renderTemplate(content []byte) (*bytes.Buffer, error) | ||||||
| 	return yamlBuf, nil | 	return yamlBuf, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (a *app) VisitDesiredStates(fileOrDir string, converge func(*state.HelmState, helmexec.Interface) (bool, []error)) error { | func (a *app) within(dir string, do func() error) error { | ||||||
|  | 	prev, err := a.getwd() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("failed getting current working direcotyr: %v", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	absDir, err := a.abs(dir) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	a.logger.Debugf("changing working directory to \"%s\"", absDir) | ||||||
|  | 
 | ||||||
|  | 	if err := a.chdir(absDir); err != nil { | ||||||
|  | 		return fmt.Errorf("failed changing working directory to \"%s\": %v", absDir, err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	appErr := do() | ||||||
|  | 
 | ||||||
|  | 	a.logger.Debugf("changing working directory back to \"%s\"", prev) | ||||||
|  | 
 | ||||||
|  | 	if chdirBackErr := a.chdir(prev); chdirBackErr != nil { | ||||||
|  | 		if appErr != nil { | ||||||
|  | 			a.logger.Warnf("%v", appErr) | ||||||
|  | 		} | ||||||
|  | 		return fmt.Errorf("failed chaging working directory back to \"%s\": %v", prev, chdirBackErr) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return appErr | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (a *app) visitStateFiles(fileOrDir string, do func(string) error) error { | ||||||
| 	desiredStateFiles, err := a.findDesiredStateFiles(fileOrDir) | 	desiredStateFiles, err := a.findDesiredStateFiles(fileOrDir) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	noMatchInHelmfiles := true | 	for _, relPath := range desiredStateFiles { | ||||||
| 	for _, f := range desiredStateFiles { | 		a.logger.Debugf("Processing %s", relPath) | ||||||
| 		a.logger.Debugf("Processing %s", f) |  | ||||||
| 
 | 
 | ||||||
|  | 		var file string | ||||||
|  | 		var dir string | ||||||
|  | 		if a.directoryExistsAt(fileOrDir) { | ||||||
|  | 			file = fileOrDir | ||||||
|  | 			dir = fileOrDir | ||||||
|  | 		} else { | ||||||
|  | 			file = filepath.Base(fileOrDir) | ||||||
|  | 			dir = filepath.Dir(fileOrDir) | ||||||
|  | 		} | ||||||
|  | 		err := a.within(dir, func() error { | ||||||
|  | 			return do(file) | ||||||
|  | 		}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (a *app) VisitDesiredStates(fileOrDir string, converge func(*state.HelmState, helmexec.Interface) (bool, []error)) error { | ||||||
|  | 	noMatchInHelmfiles := true | ||||||
|  | 	err := a.visitStateFiles(fileOrDir, func(f string) error { | ||||||
| 		content, err := a.readFile(f) | 		content, err := a.readFile(f) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
|  | @ -821,7 +879,7 @@ func (a *app) VisitDesiredStates(fileOrDir string, converge func(*state.HelmStat | ||||||
| 			case *state.StateLoadError: | 			case *state.StateLoadError: | ||||||
| 				switch stateLoadErr.Cause.(type) { | 				switch stateLoadErr.Cause.(type) { | ||||||
| 				case *state.UndefinedEnvError: | 				case *state.UndefinedEnvError: | ||||||
| 					continue | 					return nil | ||||||
| 				default: | 				default: | ||||||
| 					return err | 					return err | ||||||
| 				} | 				} | ||||||
|  | @ -859,10 +917,11 @@ func (a *app) VisitDesiredStates(fileOrDir string, converge func(*state.HelmStat | ||||||
| 			noMatchInHelmfiles = noMatchInHelmfiles && !processed | 			noMatchInHelmfiles = noMatchInHelmfiles && !processed | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if err := clean(st, errs); err != nil { | 		return clean(st, errs) | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 	if noMatchInHelmfiles { | 	if noMatchInHelmfiles { | ||||||
| 		return &noMatchingHelmfileError{selectors: a.selectors, env: a.env} | 		return &noMatchingHelmfileError{selectors: a.selectors, env: a.env} | ||||||
| 	} | 	} | ||||||
|  | @ -902,6 +961,22 @@ func (a *app) VisitDesiredStatesWithReleasesFiltered(fileOrDir string, converge | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (a *app) findStateFilesInAbsPaths(specifiedPath string) ([]string, error) { | ||||||
|  | 	rels, err := a.findDesiredStateFiles(specifiedPath) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return rels, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	files := make([]string, len(rels)) | ||||||
|  | 	for i := range rels { | ||||||
|  | 		files[i], err = filepath.Abs(rels[i]) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return []string{}, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return files, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (a *app) findDesiredStateFiles(specifiedPath string) ([]string, error) { | func (a *app) findDesiredStateFiles(specifiedPath string) ([]string, error) { | ||||||
| 	var helmfileDir string | 	var helmfileDir string | ||||||
| 	if specifiedPath != "" { | 	if specifiedPath != "" { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue