about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-09-04T09·56+0100
committerVincent Ambo <github@tazj.in>2019-09-04T10·15+0100
commitd0f52766b35a9ccccb131fbbb33f6398ea6042d2 (patch)
treeb62ab71d395159f3c858f1144e5987ac41968b35
parent75a3cd2534bb9138b3f42f4591a65a954c2be9b4 (diff)
fix(context): Ensure resource set paths are made absolute
Resolving of files (for `insertFile` and `insertTemplate`) should
always be relative to the resource set location, the previous
behaviour was considered a bug.

This is fixed by ensuring that resource set paths are absolute at
context loading time.
-rw-r--r--context/context.go12
-rw-r--r--context/context_test.go18
-rw-r--r--templater/templater.go9
3 files changed, 22 insertions, 17 deletions
diff --git a/context/context.go b/context/context.go
index 314fc3584545..262e8c948035 100644
--- a/context/context.go
+++ b/context/context.go
@@ -77,7 +77,7 @@ func LoadContext(filename string, explicitVars *[]string) (*Context, error) {
 	ctx.BaseDir = path.Dir(filename)
 
 	// Prepare the resource sets by resolving parents etc.
-	ctx.ResourceSets = flattenPrepareResourceSetPaths(&ctx.ResourceSets)
+	ctx.ResourceSets = flattenPrepareResourceSetPaths(&ctx.BaseDir, &ctx.ResourceSets)
 
 	// Add variables explicitly specified on the command line
 	ctx.ExplicitVars, err = loadExplicitVars(explicitVars)
@@ -136,7 +136,7 @@ func (ctx *Context) loadImportedVariables() (map[string]interface{}, error) {
 // collections, i.e. resource sets that themselves have an additional 'include' field set.
 // Those will be regarded as a short-hand for including multiple resource sets from a subfolder.
 // See https://github.com/tazjin/kontemplate/issues/9 for more information.
-func flattenPrepareResourceSetPaths(rs *[]ResourceSet) []ResourceSet {
+func flattenPrepareResourceSetPaths(baseDir *string, rs *[]ResourceSet) []ResourceSet {
 	flattened := make([]ResourceSet, 0)
 
 	for _, r := range *rs {
@@ -146,6 +146,12 @@ func flattenPrepareResourceSetPaths(rs *[]ResourceSet) []ResourceSet {
 			r.Path = r.Name
 		}
 
+		// Paths are made absolute by resolving them relative to the context base,
+		// unless absolute paths were specified.
+		if !path.IsAbs(r.Path) {
+			r.Path = path.Join(*baseDir, r.Path)
+		}
+
 		if len(r.Include) == 0 {
 			flattened = append(flattened, r)
 		} else {
@@ -225,7 +231,7 @@ func loadDefaultValues(rs *ResourceSet, c *Context) *map[string]interface{} {
 	var defaultVars map[string]interface{}
 
 	for _, filename := range util.DefaultFilenames {
-		err := util.LoadData(path.Join(c.BaseDir, rs.Path, filename), &defaultVars)
+		err := util.LoadData(path.Join(rs.Path, filename), &defaultVars)
 		if err == nil {
 			return &defaultVars
 		}
diff --git a/context/context_test.go b/context/context_test.go
index d7fdc11e5718..5d6164585cb2 100644
--- a/context/context_test.go
+++ b/context/context_test.go
@@ -32,7 +32,7 @@ func TestLoadFlatContextFromFile(t *testing.T) {
 		ResourceSets: []ResourceSet{
 			{
 				Name: "some-api",
-				Path: "some-api",
+				Path: "testdata/some-api",
 				Values: map[string]interface{}{
 					"apiPort":          float64(4567), // yep!
 					"importantFeature": true,
@@ -67,7 +67,7 @@ func TestLoadContextWithArgs(t *testing.T) {
 		ResourceSets: []ResourceSet{
 			{
 				Name:   "some-api",
-				Path:   "some-api",
+				Path:   "testdata/some-api",
 				Values: make(map[string]interface{}, 0),
 				Args: []string{
 					"--as=some-user",
@@ -106,7 +106,7 @@ func TestLoadContextWithResourceSetCollections(t *testing.T) {
 		ResourceSets: []ResourceSet{
 			{
 				Name: "some-api",
-				Path: "some-api",
+				Path: "testdata/some-api",
 				Values: map[string]interface{}{
 					"apiPort":          float64(4567), // yep!
 					"importantFeature": true,
@@ -118,7 +118,7 @@ func TestLoadContextWithResourceSetCollections(t *testing.T) {
 			},
 			{
 				Name: "collection/nested",
-				Path: "collection/nested",
+				Path: "testdata/collection/nested",
 				Values: map[string]interface{}{
 					"lizards":   "good",
 					"globalVar": "lizards",
@@ -152,7 +152,7 @@ func TestSubresourceVariableInheritance(t *testing.T) {
 		ResourceSets: []ResourceSet{
 			{
 				Name: "parent/child",
-				Path: "parent/child",
+				Path: "testdata/parent/child",
 				Values: map[string]interface{}{
 					"foo": "bar",
 					"bar": "baz",
@@ -185,7 +185,7 @@ func TestSubresourceVariableInheritanceOverride(t *testing.T) {
 		ResourceSets: []ResourceSet{
 			{
 				Name: "parent/child",
-				Path: "parent/child",
+				Path: "testdata/parent/child",
 				Values: map[string]interface{}{
 					"foo": "newvalue",
 				},
@@ -256,7 +256,7 @@ func TestExplicitPathLoading(t *testing.T) {
 		ResourceSets: []ResourceSet{
 			{
 				Name: "some-api-europe",
-				Path: "some-api",
+				Path: "testdata/some-api",
 				Values: map[string]interface{}{
 					"location": "europe",
 				},
@@ -265,7 +265,7 @@ func TestExplicitPathLoading(t *testing.T) {
 			},
 			{
 				Name: "some-api-asia",
-				Path: "some-api",
+				Path: "testdata/some-api",
 				Values: map[string]interface{}{
 					"location": "asia",
 				},
@@ -296,7 +296,7 @@ func TestExplicitSubresourcePathLoading(t *testing.T) {
 		ResourceSets: []ResourceSet{
 			{
 				Name:   "parent/child",
-				Path:   "parent-path/child-path",
+				Path:   "testdata/parent-path/child-path",
 				Parent: "parent",
 				Values: make(map[string]interface{}, 0),
 			},
diff --git a/templater/templater.go b/templater/templater.go
index 55b64766ce8c..6cf8a4c2e2de 100644
--- a/templater/templater.go
+++ b/templater/templater.go
@@ -62,8 +62,7 @@ func LoadAndApplyTemplates(include *[]string, exclude *[]string, c *context.Cont
 func processResourceSet(ctx *context.Context, rs *context.ResourceSet) (*RenderedResourceSet, error) {
 	fmt.Fprintf(os.Stderr, "Loading resources for %s\n", rs.Name)
 
-	resourcePath := path.Join(ctx.BaseDir, rs.Path)
-	fileInfo, err := os.Stat(resourcePath)
+	fileInfo, err := os.Stat(rs.Path)
 	if err != nil {
 		return nil, err
 	}
@@ -78,13 +77,13 @@ func processResourceSet(ctx *context.Context, rs *context.ResourceSet) (*Rendere
 		// list of files instead.
 		// This will end up printing a warning to the user, but it
 		// won't stop the rest of the process.
-		files, _ = ioutil.ReadDir(resourcePath)
+		files, _ = ioutil.ReadDir(rs.Path)
 		resources, err = processFiles(ctx, rs, files)
 		if err != nil {
 			return nil, err
 		}
 	} else {
-		resource, err := templateFile(ctx, rs, resourcePath)
+		resource, err := templateFile(ctx, rs, rs.Path)
 		if err != nil {
 			return nil, err
 		}
@@ -104,7 +103,7 @@ func processFiles(ctx *context.Context, rs *context.ResourceSet, files []os.File
 
 	for _, file := range files {
 		if !file.IsDir() && isResourceFile(file) {
-			path := path.Join(ctx.BaseDir, rs.Path, file.Name())
+			path := path.Join(rs.Path, file.Name())
 			res, err := templateFile(ctx, rs, path)
 
 			if err != nil {