Merge remote-tracking branch 'origin/master' into main
This commit is contained in:
		
						commit
						19ba9d2c4d
					
				
							
								
								
									
										1
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										1
									
								
								Makefile
								
								
								
								
							|  | @ -23,6 +23,7 @@ build-test-tools: | |||
| .PHONY: build-test-tools | ||||
| 
 | ||||
| test: | ||||
| 	@which helm &> /dev/null || (echo "helm binary not found. Please see: https://helm.sh/docs/intro/install/" && exit 1) | ||||
| 	go build -o helmfile . | ||||
| 	go test -v ${PKGS} -cover -race -p=1 | ||||
| .PHONY: test | ||||
|  |  | |||
|  | @ -872,7 +872,10 @@ environments: | |||
|       - git::https://git.company.org/helmfiles/global/gcp.yaml?ref=master | ||||
|       - git::https://git.company.org/helmfiles/global/europe-west.yaml?ref=master | ||||
|       - git::https://ci:{{ env "CI_JOB_TOKEN" }}@gitlab.com/org/repository-name.git@/config.dev.yaml?ref={{ env "APP_COMMIT_SHA" }}  # Private Gitlab Repo | ||||
| 
 | ||||
|   staging: | ||||
|      values: | ||||
|       -  git::https://{{ env "GITHUB_PAT" }}@github.com/[$GITHUB_ORGorGITHUB_USER]/repository-name.git@/values.dev.yaml?ref=main #Github Private repo | ||||
|       -  http://$HOSTNAME/artifactory/example-repo-local/test.tgz@values.yaml #Artifactory url | ||||
| --- | ||||
| 
 | ||||
| releases: | ||||
|  |  | |||
							
								
								
									
										116
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										116
									
								
								go.mod
								
								
								
								
							|  | @ -1,9 +1,8 @@ | |||
| module github.com/roboll/helmfile | ||||
| 
 | ||||
| go 1.14 | ||||
| go 1.17 | ||||
| 
 | ||||
| require ( | ||||
| 	cloud.google.com/go/secretmanager v1.3.0 // indirect | ||||
| 	github.com/Masterminds/semver/v3 v3.1.1 | ||||
| 	github.com/Masterminds/sprig/v3 v3.2.2 | ||||
| 	github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a | ||||
|  | @ -14,21 +13,18 @@ require ( | |||
| 	github.com/google/go-cmp v0.5.7 | ||||
| 	github.com/gosuri/uitable v0.0.4 | ||||
| 	github.com/hashicorp/go-getter v1.5.9 | ||||
| 	github.com/hashicorp/go-retryablehttp v0.6.3 // indirect | ||||
| 	github.com/hashicorp/go-version v1.2.1 | ||||
| 	github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c // indirect | ||||
| 	github.com/imdario/mergo v0.3.12 | ||||
| 	github.com/jessevdk/go-flags v1.4.0 | ||||
| 	github.com/kylelemons/godebug v1.1.0 | ||||
| 	github.com/logrusorgru/aurora v2.0.3+incompatible | ||||
| 	github.com/mattn/go-isatty v0.0.14 | ||||
| 	github.com/pierrec/lz4 v2.3.0+incompatible // indirect | ||||
| 	github.com/r3labs/diff v1.1.0 | ||||
| 	github.com/spf13/cobra v1.3.0 | ||||
| 	github.com/stretchr/testify v1.7.0 | ||||
| 	github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939 | ||||
| 	github.com/urfave/cli v1.22.5 | ||||
| 	github.com/variantdev/chartify v0.9.4 | ||||
| 	github.com/variantdev/chartify v0.9.5 | ||||
| 	github.com/variantdev/dag v1.1.0 | ||||
| 	github.com/variantdev/vals v0.15.0 | ||||
| 	go.uber.org/multierr v1.6.0 | ||||
|  | @ -39,3 +35,111 @@ require ( | |||
| 	gotest.tools/v3 v3.0.3 | ||||
| 	k8s.io/apimachinery v0.23.4 | ||||
| ) | ||||
| 
 | ||||
| require ( | ||||
| 	cloud.google.com/go v0.100.2 // indirect | ||||
| 	cloud.google.com/go/compute v1.3.0 // indirect | ||||
| 	cloud.google.com/go/iam v0.1.0 // indirect | ||||
| 	cloud.google.com/go/secretmanager v1.3.0 // indirect | ||||
| 	cloud.google.com/go/storage v1.15.0 // indirect | ||||
| 	filippo.io/age v1.0.0-beta7 // indirect | ||||
| 	github.com/Azure/azure-pipeline-go v0.2.3 // indirect | ||||
| 	github.com/Azure/azure-sdk-for-go v56.2.0+incompatible // indirect | ||||
| 	github.com/Azure/azure-storage-blob-go v0.14.0 // indirect | ||||
| 	github.com/Azure/go-autorest v14.2.0+incompatible // indirect | ||||
| 	github.com/Azure/go-autorest/autorest v0.11.19 // indirect | ||||
| 	github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect | ||||
| 	github.com/Azure/go-autorest/autorest/azure/auth v0.5.8 // indirect | ||||
| 	github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 // indirect | ||||
| 	github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect | ||||
| 	github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect | ||||
| 	github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect | ||||
| 	github.com/Azure/go-autorest/logger v0.2.1 // indirect | ||||
| 	github.com/Azure/go-autorest/tracing v0.6.0 // indirect | ||||
| 	github.com/Masterminds/goutils v1.1.1 // indirect | ||||
| 	github.com/alecthomas/participle v0.4.2-0.20191220090139-9fbceec1d131 // indirect | ||||
| 	github.com/aws/aws-sdk-go v1.40.28 // indirect | ||||
| 	github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect | ||||
| 	github.com/blang/semver v3.5.1+incompatible // indirect | ||||
| 	github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect | ||||
| 	github.com/dimchansky/utfbom v1.1.1 // indirect | ||||
| 	github.com/fatih/color v1.13.0 // indirect | ||||
| 	github.com/form3tech-oss/jwt-go v3.2.2+incompatible // indirect | ||||
| 	github.com/frankban/quicktest v1.14.3 // indirect | ||||
| 	github.com/fujiwara/tfstate-lookup v0.4.0 // indirect | ||||
| 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | ||||
| 	github.com/golang/protobuf v1.5.2 // indirect | ||||
| 	github.com/golang/snappy v0.0.3 // indirect | ||||
| 	github.com/google/go-querystring v1.0.0 // indirect | ||||
| 	github.com/google/uuid v1.2.0 // indirect | ||||
| 	github.com/googleapis/gax-go/v2 v2.1.1 // indirect | ||||
| 	github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect | ||||
| 	github.com/hashicorp/errwrap v1.0.0 // indirect | ||||
| 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect | ||||
| 	github.com/hashicorp/go-hclog v1.0.0 // indirect | ||||
| 	github.com/hashicorp/go-multierror v1.1.0 // indirect | ||||
| 	github.com/hashicorp/go-retryablehttp v0.6.3 // indirect | ||||
| 	github.com/hashicorp/go-rootcerts v1.0.2 // indirect | ||||
| 	github.com/hashicorp/go-safetemp v1.0.0 // indirect | ||||
| 	github.com/hashicorp/go-slug v0.7.0 // indirect | ||||
| 	github.com/hashicorp/go-sockaddr v1.0.2 // indirect | ||||
| 	github.com/hashicorp/go-tfe v0.17.1 // indirect | ||||
| 	github.com/hashicorp/golang-lru v0.5.4 // indirect | ||||
| 	github.com/hashicorp/hcl v1.0.0 // indirect | ||||
| 	github.com/hashicorp/jsonapi v0.0.0-20210518035559-1e50d74c8db3 // indirect | ||||
| 	github.com/hashicorp/vault/api v1.0.4 // indirect | ||||
| 	github.com/hashicorp/vault/sdk v0.1.14-0.20200215224050-f6547fa8e820 // indirect | ||||
| 	github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c // indirect | ||||
| 	github.com/huandu/xstrings v1.3.1 // indirect | ||||
| 	github.com/inconshreveable/mousetrap v1.0.0 // indirect | ||||
| 	github.com/itchyny/gojq v0.9.0 // indirect | ||||
| 	github.com/jmespath/go-jmespath v0.4.0 // indirect | ||||
| 	github.com/klauspost/compress v1.13.6 // indirect | ||||
| 	github.com/lestrrat-go/strftime v1.0.1 // indirect | ||||
| 	github.com/lib/pq v1.2.0 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.12 // indirect | ||||
| 	github.com/mattn/go-ieproxy v0.0.1 // indirect | ||||
| 	github.com/mattn/go-runewidth v0.0.8 // indirect | ||||
| 	github.com/mitchellh/copystructure v1.0.0 // indirect | ||||
| 	github.com/mitchellh/go-homedir v1.1.0 // indirect | ||||
| 	github.com/mitchellh/go-testing-interface v1.0.0 // indirect | ||||
| 	github.com/mitchellh/go-wordwrap v1.0.0 // indirect | ||||
| 	github.com/mitchellh/mapstructure v1.4.3 // indirect | ||||
| 	github.com/mitchellh/reflectwalk v1.0.0 // indirect | ||||
| 	github.com/otiai10/copy v1.1.1 // indirect | ||||
| 	github.com/pbnjay/strptime v0.0.0-20140226051138-5c05b0d668c9 // indirect | ||||
| 	github.com/pierrec/lz4 v2.3.0+incompatible // indirect | ||||
| 	github.com/pkg/errors v0.9.1 // indirect | ||||
| 	github.com/pmezard/go-difflib v1.0.0 // indirect | ||||
| 	github.com/russross/blackfriday/v2 v2.1.0 // indirect | ||||
| 	github.com/ryanuber/go-glob v1.0.0 // indirect | ||||
| 	github.com/sergi/go-diff v1.1.0 // indirect | ||||
| 	github.com/shopspring/decimal v1.2.0 // indirect | ||||
| 	github.com/sirupsen/logrus v1.8.1 // indirect | ||||
| 	github.com/spf13/cast v1.4.1 // indirect | ||||
| 	github.com/spf13/pflag v1.0.5 // indirect | ||||
| 	github.com/ulikunitz/xz v0.5.8 // indirect | ||||
| 	go.mozilla.org/gopgagent v0.0.0-20170926210634-4d7ea76ff71a // indirect | ||||
| 	go.mozilla.org/sops/v3 v3.7.1 // indirect | ||||
| 	go.opencensus.io v0.23.0 // indirect | ||||
| 	go.uber.org/atomic v1.7.0 // indirect | ||||
| 	golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect | ||||
| 	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-20220209214540-3681064d5158 // 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-20210723032227-1f47c861a9ac // indirect | ||||
| 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect | ||||
| 	google.golang.org/api v0.70.0 // indirect | ||||
| 	google.golang.org/appengine v1.6.7 // indirect | ||||
| 	google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf // indirect | ||||
| 	google.golang.org/grpc v1.44.0 // indirect | ||||
| 	google.golang.org/protobuf v1.27.1 // indirect | ||||
| 	gopkg.in/ini.v1 v1.66.2 // indirect | ||||
| 	gopkg.in/square/go-jose.v2 v2.3.1 // indirect | ||||
| 	gopkg.in/urfave/cli.v1 v1.20.0 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect | ||||
| 	sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect | ||||
| 	sigs.k8s.io/yaml v1.3.0 // indirect | ||||
| ) | ||||
|  |  | |||
|  | @ -21,11 +21,7 @@ func prependLineNumbers(text string) string { | |||
| } | ||||
| 
 | ||||
| func (r *desiredStateLoader) renderPrestate(firstPassEnv *environment.Environment, baseDir, filename string, content []byte) (*environment.Environment, *state.HelmState) { | ||||
| 	tmplData := state.EnvironmentTemplateData{ | ||||
| 		Environment: *firstPassEnv, | ||||
| 		Namespace:   r.namespace, | ||||
| 		Values:      map[string]interface{}{}, | ||||
| 	} | ||||
| 	tmplData := state.NewEnvironmentTemplateData(*firstPassEnv, r.namespace, map[string]interface{}{}) | ||||
| 	firstPassRenderer := tmpl.NewFirstPassRenderer(baseDir, tmplData) | ||||
| 
 | ||||
| 	// parse as much as we can, tolerate errors, this is a preparse
 | ||||
|  | @ -127,11 +123,7 @@ func (r *desiredStateLoader) twoPassRenderTemplateToYaml(inherited, overrode *en | |||
| 		r.logger.Debugf("vals:\n%v\ndefaultVals:%v", vals, prestate.DefaultValues) | ||||
| 	} | ||||
| 
 | ||||
| 	tmplData := state.EnvironmentTemplateData{ | ||||
| 		Environment: *finalEnv, | ||||
| 		Namespace:   r.namespace, | ||||
| 		Values:      vals, | ||||
| 	} | ||||
| 	tmplData := state.NewEnvironmentTemplateData(*finalEnv, r.namespace, vals) | ||||
| 	secondPassRenderer := tmpl.NewFileRenderer(r.readFile, baseDir, tmplData) | ||||
| 	yamlBuf, err := secondPassRenderer.RenderTemplateContentToBuffer(content) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -61,7 +61,8 @@ func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *str | |||
| 				} else { | ||||
| 					env = *ctxEnv | ||||
| 				} | ||||
| 				tmplData := EnvironmentTemplateData{env, "", map[string]interface{}{}} | ||||
| 
 | ||||
| 				tmplData := NewEnvironmentTemplateData(env, "", map[string]interface{}{}) | ||||
| 				r := tmpl.NewFileRenderer(ld.readFile, filepath.Dir(f), tmplData) | ||||
| 				bytes, err := r.RenderToBytes(f) | ||||
| 				if err != nil { | ||||
|  |  | |||
|  | @ -60,8 +60,12 @@ type ReleaseSetSpec struct { | |||
| 	CommonLabels        map[string]string `yaml:"commonLabels,omitempty"` | ||||
| 	Releases            []ReleaseSpec     `yaml:"releases,omitempty"` | ||||
| 	Selectors           []string          `yaml:"-"` | ||||
| 	ApiVersions         []string          `yaml:"apiVersions,omitempty"` | ||||
| 	KubeVersion         string            `yaml:"kubeVersion,omitempty"` | ||||
| 
 | ||||
| 	// Capabilities.APIVersions
 | ||||
| 	ApiVersions []string `yaml:"apiVersions,omitempty"` | ||||
| 
 | ||||
| 	// Capabilities.KubeVersion
 | ||||
| 	KubeVersion string `yaml:"kubeVersion,omitempty"` | ||||
| 
 | ||||
| 	// Hooks is a list of extension points paired with operations, that are executed in specific points of the lifecycle of releases defined in helmfile
 | ||||
| 	Hooks []event.Hook `yaml:"hooks,omitempty"` | ||||
|  | @ -249,6 +253,12 @@ type ReleaseSpec struct { | |||
| 	ValuesTemplate    []interface{} `yaml:"valuesTemplate,omitempty"` | ||||
| 	SetValuesTemplate []SetValue    `yaml:"setTemplate,omitempty"` | ||||
| 
 | ||||
| 	// Capabilities.APIVersions
 | ||||
| 	ApiVersions []string `yaml:"apiVersions,omitempty"` | ||||
| 
 | ||||
| 	// Capabilities.KubeVersion
 | ||||
| 	KubeVersion string `yaml:"kubeVersion,omitempty"` | ||||
| 
 | ||||
| 	// The 'env' section is not really necessary any longer, as 'set' would now provide the same functionality
 | ||||
| 	EnvValues []SetValue `yaml:"env,omitempty"` | ||||
| 
 | ||||
|  | @ -1121,6 +1131,9 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre | |||
| 
 | ||||
| 					chartifyOpts.Validate = opts.Validate | ||||
| 
 | ||||
| 					chartifyOpts.KubeVersion = release.KubeVersion | ||||
| 					chartifyOpts.ApiVersions = release.ApiVersions | ||||
| 
 | ||||
| 					out, err := c.Chartify(release.Name, chartPath, chartify.WithChartifyOpts(chartifyOpts)) | ||||
| 					if err != nil { | ||||
| 						results <- &chartPrepareResult{err: err} | ||||
|  | @ -1692,10 +1705,8 @@ func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValu | |||
| 					flags = append(flags, "--include-tests") | ||||
| 				} | ||||
| 
 | ||||
| 				if suppress != nil { | ||||
| 					for _, s := range suppress { | ||||
| 						flags = append(flags, "--suppress", s) | ||||
| 					} | ||||
| 				for _, s := range suppress { | ||||
| 					flags = append(flags, "--suppress", s) | ||||
| 				} | ||||
| 
 | ||||
| 				if suppressSecrets { | ||||
|  | @ -2471,10 +2482,7 @@ func (st *HelmState) flagsForTemplate(helm helmexec.Interface, release *ReleaseS | |||
| 		return nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	flags = st.appendApiVersionsFlags(flags) | ||||
| 	if st.KubeVersion != "" { | ||||
| 		flags = append(flags, "--kube-version", st.KubeVersion) | ||||
| 	} | ||||
| 	flags = st.appendApiVersionsFlags(flags, release) | ||||
| 
 | ||||
| 	common, files, err := st.namespaceAndValuesFlags(helm, release, workerIndex) | ||||
| 	if err != nil { | ||||
|  | @ -2536,10 +2544,15 @@ func (st *HelmState) chartVersionFlags(release *ReleaseSpec) []string { | |||
| 	return flags | ||||
| } | ||||
| 
 | ||||
| func (st *HelmState) appendApiVersionsFlags(flags []string) []string { | ||||
| 	for _, a := range st.ApiVersions { | ||||
| func (st *HelmState) appendApiVersionsFlags(flags []string, r *ReleaseSpec) []string { | ||||
| 	for _, a := range r.ApiVersions { | ||||
| 		flags = append(flags, "--api-versions", a) | ||||
| 	} | ||||
| 
 | ||||
| 	if r.KubeVersion != "" { | ||||
| 		flags = append(flags, "--kube-version", st.KubeVersion) | ||||
| 	} | ||||
| 
 | ||||
| 	return flags | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -100,6 +100,13 @@ func (st *HelmState) ExecuteTemplates() (*HelmState, error) { | |||
| 		for k, v := range st.CommonLabels { | ||||
| 			release.Labels[k] = v | ||||
| 		} | ||||
| 		if len(release.ApiVersions) == 0 { | ||||
| 			release.ApiVersions = st.ApiVersions | ||||
| 		} | ||||
| 		if release.KubeVersion == "" { | ||||
| 			release.KubeVersion = st.KubeVersion | ||||
| 		} | ||||
| 
 | ||||
| 		successFlag := false | ||||
| 		for it, prev := 0, &release; it < 6; it++ { | ||||
| 			tmplData := st.createReleaseTemplateData(prev, vals) | ||||
|  |  | |||
|  | @ -38,39 +38,39 @@ func TestGenerateID(t *testing.T) { | |||
| 	run(testcase{ | ||||
| 		subject: "baseline", | ||||
| 		release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, | ||||
| 		want:    "foo-values-779795898b", | ||||
| 		want:    "foo-values-6d97d4c7ff", | ||||
| 	}) | ||||
| 
 | ||||
| 	run(testcase{ | ||||
| 		subject: "different bytes content", | ||||
| 		release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, | ||||
| 		data:    []byte(`{"k":"v"}`), | ||||
| 		want:    "foo-values-6b7ffbccc", | ||||
| 		want:    "foo-values-74fcbfbd68", | ||||
| 	}) | ||||
| 
 | ||||
| 	run(testcase{ | ||||
| 		subject: "different map content", | ||||
| 		release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, | ||||
| 		data:    map[string]interface{}{"k": "v"}, | ||||
| 		want:    "foo-values-6d57bbfccf", | ||||
| 		want:    "foo-values-7b954b6b6b", | ||||
| 	}) | ||||
| 
 | ||||
| 	run(testcase{ | ||||
| 		subject: "different chart", | ||||
| 		release: ReleaseSpec{Name: "foo", Chart: "stable/envoy"}, | ||||
| 		want:    "foo-values-5c45b58947", | ||||
| 		want:    "foo-values-5c54676568", | ||||
| 	}) | ||||
| 
 | ||||
| 	run(testcase{ | ||||
| 		subject: "different name", | ||||
| 		release: ReleaseSpec{Name: "bar", Chart: "incubator/raw"}, | ||||
| 		want:    "bar-values-99d5fdbcc", | ||||
| 		want:    "bar-values-5fff459546", | ||||
| 	}) | ||||
| 
 | ||||
| 	run(testcase{ | ||||
| 		subject: "specific ns", | ||||
| 		release: ReleaseSpec{Name: "foo", Chart: "incubator/raw", Namespace: "myns"}, | ||||
| 		want:    "myns-foo-values-544cb97d7f", | ||||
| 		want:    "myns-foo-values-cfd9959dd", | ||||
| 	}) | ||||
| 
 | ||||
| 	for id, n := range ids { | ||||
|  |  | |||
|  | @ -16,7 +16,14 @@ type EnvironmentTemplateData struct { | |||
| 	// Namespace is accessible as `.Namespace` from any non-values template executed by the renderer
 | ||||
| 	Namespace string | ||||
| 	// Values is accessible as `.Values` and it contains default state values overrode by environment values and override values.
 | ||||
| 	Values map[string]interface{} | ||||
| 	Values      map[string]interface{} | ||||
| 	StateValues *map[string]interface{} | ||||
| } | ||||
| 
 | ||||
| func NewEnvironmentTemplateData(environment environment.Environment, namespace string, values map[string]interface{}) *EnvironmentTemplateData { | ||||
| 	d := EnvironmentTemplateData{environment, namespace, values, nil} | ||||
| 	d.StateValues = &d.Values | ||||
| 	return &d | ||||
| } | ||||
| 
 | ||||
| // releaseTemplateData provides variables accessible while executing golang text/template expressions in release templates
 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| package tmpl | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
|  | @ -20,6 +21,7 @@ type Values = map[string]interface{} | |||
| func (c *Context) createFuncMap() template.FuncMap { | ||||
| 	funcMap := template.FuncMap{ | ||||
| 		"exec":             c.Exec, | ||||
| 		"isFile":           c.IsFile, | ||||
| 		"readFile":         c.ReadFile, | ||||
| 		"readDir":          c.ReadDir, | ||||
| 		"toYaml":           ToYaml, | ||||
|  | @ -117,6 +119,24 @@ func (c *Context) Exec(command string, args []interface{}, inputs ...string) (st | |||
| 	return string(bytes), nil | ||||
| } | ||||
| 
 | ||||
| func (c *Context) IsFile(filename string) (bool, error) { | ||||
| 	var path string | ||||
| 	if filepath.IsAbs(filename) { | ||||
| 		path = filename | ||||
| 	} else { | ||||
| 		path = filepath.Join(c.basePath, filename) | ||||
| 	} | ||||
| 
 | ||||
| 	stat, err := os.Stat(path) | ||||
| 	if err == nil { | ||||
| 		return !stat.IsDir(), nil | ||||
| 	} | ||||
| 	if errors.Is(err, os.ErrNotExist) { | ||||
| 		return false, nil | ||||
| 	} | ||||
| 	return false, err | ||||
| } | ||||
| 
 | ||||
| func (c *Context) ReadFile(filename string) (string, error) { | ||||
| 	var path string | ||||
| 	if filepath.IsAbs(filename) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue