feat: All the paths are relative to helmfile.yaml (#261)

`helmfile lint` works with relative chart reference (#252)
The tempalte function `readFile` accepts the path relative to helmfile.yaml

Resolves #246
Fixes #252
This commit is contained in:
KUOKA Yusuke 2018-08-30 19:47:52 +09:00 committed by GitHub
parent 79f0e70ce8
commit 421299c883
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 25 additions and 25 deletions

View File

@ -119,7 +119,7 @@ func (helm *execer) DecryptSecret(name string) (string, error) {
// os.Rename seems to results in "cross-device link` errors in some cases // os.Rename seems to results in "cross-device link` errors in some cases
// Instead of moving, copy it to the destination temp file as a work-around // Instead of moving, copy it to the destination temp file as a work-around
// See https://github.com/roboll/helmfile/issues/251#issuecomment-417166296 // See https://github.com/roboll/helmfile/issues/251#issuecomment-417166296f
decFile, err := os.Open(name + ".dec") decFile, err := os.Open(name + ".dec")
if err != nil { if err != nil {
return "", err return "", err

View File

@ -18,6 +18,7 @@ import (
"github.com/urfave/cli" "github.com/urfave/cli"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
"io/ioutil"
) )
const ( const (
@ -400,7 +401,7 @@ func eachDesiredStateDo(c *cli.Context, converge func(*state.HelmState, helmexec
} }
allSelectorNotMatched := true allSelectorNotMatched := true
for _, f := range desiredStateFiles { for _, f := range desiredStateFiles {
yamlBuf, err := tmpl.RenderTemplateFileToBuffer(f) yamlBuf, err := tmpl.NewFileRenderer(ioutil.ReadFile, "").RenderTemplateFileToBuffer(f)
if err != nil { if err != nil {
return err return err
} }

View File

@ -349,7 +349,7 @@ func (state *HelmState) LintReleases(helm helmexec.Interface, additionalValues [
} }
chartPath := "" chartPath := ""
if isLocalChart(release.Chart) { if pathExists(normalizeChart(state.BaseChartPath, release.Chart)) {
chartPath = normalizeChart(state.BaseChartPath, release.Chart) chartPath = normalizeChart(state.BaseChartPath, release.Chart)
} else { } else {
fetchFlags := []string{} fetchFlags := []string{}
@ -586,14 +586,18 @@ func (state *HelmState) UpdateDeps(helm helmexec.Interface) []error {
// be constructed relative to the `base path`. // be constructed relative to the `base path`.
// - Everything else is assumed to be an absolute path or an actual <repository>/<chart> reference. // - Everything else is assumed to be an absolute path or an actual <repository>/<chart> reference.
func normalizeChart(basePath, chart string) string { func normalizeChart(basePath, chart string) string {
regex, _ := regexp.Compile("^[.]?./") if !isLocalChart(chart) {
if !regex.MatchString(chart) {
return chart return chart
} }
return filepath.Join(basePath, chart) return filepath.Join(basePath, chart)
} }
func isLocalChart(chart string) bool { func isLocalChart(chart string) bool {
regex, _ := regexp.Compile("^[.]?./")
return regex.MatchString(chart)
}
func pathExists(chart string) bool {
_, err := os.Stat(chart) _, err := os.Stat(chart)
return err == nil return err == nil
} }
@ -680,7 +684,7 @@ func (state *HelmState) namespaceAndValuesFlags(helm helmexec.Interface, basePat
} }
defer valfile.Close() defer valfile.Close()
r := valuesfile.NewRenderer(ioutil.ReadFile) r := valuesfile.NewRenderer(ioutil.ReadFile, state.BaseChartPath)
yamlBytes, err := r.RenderToBytes(path) yamlBytes, err := r.RenderToBytes(path)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -560,7 +560,7 @@ func Test_isLocalChart(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := isLocalChart(tt.args.chart); got != tt.want { if got := isLocalChart(tt.args.chart); got != tt.want {
t.Errorf("isLocalChart() = %v, want %v", got, tt.want) t.Errorf("pathExists() = %v, want %v", got, tt.want)
} }
}) })
} }
@ -879,7 +879,7 @@ func TestHelmState_UpdateDeps(t *testing.T) {
Chart: "published/deeper", Chart: "published/deeper",
}, },
{ {
Chart: "./error", Chart: ".error",
}, },
}, },
} }

View File

@ -2,16 +2,11 @@ package tmpl
import ( import (
"bytes" "bytes"
"io/ioutil" "path/filepath"
) )
var DefaultFileRenderer *templateFileRenderer
func init() {
DefaultFileRenderer = NewFileRenderer(ioutil.ReadFile)
}
type templateFileRenderer struct { type templateFileRenderer struct {
basePath string
ReadFile func(string) ([]byte, error) ReadFile func(string) ([]byte, error)
Context *Context Context *Context
} }
@ -20,8 +15,9 @@ type FileRenderer interface {
RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error) RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error)
} }
func NewFileRenderer(readFile func(filename string) ([]byte, error)) *templateFileRenderer { func NewFileRenderer(readFile func(filename string) ([]byte, error), basePath string) *templateFileRenderer {
return &templateFileRenderer{ return &templateFileRenderer{
basePath: basePath,
ReadFile: readFile, ReadFile: readFile,
Context: &Context{ Context: &Context{
readFile: readFile, readFile: readFile,
@ -30,14 +26,13 @@ func NewFileRenderer(readFile func(filename string) ([]byte, error)) *templateFi
} }
func (r *templateFileRenderer) RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error) { func (r *templateFileRenderer) RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error) {
content, err := r.ReadFile(file) // path to the file relative to the helmfile.yaml
path := filepath.Join(r.basePath, file)
content, err := r.ReadFile(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return r.Context.RenderTemplateToBuffer(string(content)) return r.Context.RenderTemplateToBuffer(string(content))
} }
func RenderTemplateFileToBuffer(file string) (*bytes.Buffer, error) {
return DefaultFileRenderer.RenderTemplateFileToBuffer(file)
}

View File

@ -11,10 +11,10 @@ type renderer struct {
tmplFileRenderer tmpl.FileRenderer tmplFileRenderer tmpl.FileRenderer
} }
func NewRenderer(readFile func(filename string) ([]byte, error)) *renderer { func NewRenderer(readFile func(filename string) ([]byte, error), basePath string) *renderer {
return &renderer{ return &renderer{
readFile: readFile, readFile: readFile,
tmplFileRenderer: tmpl.NewFileRenderer(readFile), tmplFileRenderer: tmpl.NewFileRenderer(readFile, basePath),
} }
} }

View File

@ -24,7 +24,7 @@ func TestRenderToBytes_Gotmpl(t *testing.T) {
return []byte(dataFileContent), nil return []byte(dataFileContent), nil
} }
return nil, fmt.Errorf("unexpected filename: expected=%v or %v, actual=%s", dataFile, valuesTmplFile, filename) return nil, fmt.Errorf("unexpected filename: expected=%v or %v, actual=%s", dataFile, valuesTmplFile, filename)
}) }, "")
buf, err := r.RenderToBytes(valuesTmplFile) buf, err := r.RenderToBytes(valuesTmplFile)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -49,7 +49,7 @@ func TestRenderToBytes_Yaml(t *testing.T) {
return []byte(valuesYamlContent), nil return []byte(valuesYamlContent), nil
} }
return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", valuesFile, filename) return nil, fmt.Errorf("unexpected filename: expected=%v, actual=%s", valuesFile, filename)
}) }, "")
buf, err := r.RenderToBytes(valuesFile) buf, err := r.RenderToBytes(valuesFile)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)