Skip to content

Commit

Permalink
core: path.module, path.root, path.cwd use fwd slashes on all platforms
Browse files Browse the repository at this point in the history
Previously we used the native slash type for the host platform, but that
leads to issues if the same configuration is applied on both Windows and
non-Windows systems.

Since Windows supports slashes and backslashes, we can safely return
always slashes here and require that users combine the result with
subsequent path parts using slashes, like:

    "${path.module}/foo/bar"

Previously the above would lead to an error on Windows if path.module
contained any backslashes.

This is not really possible to unit test directly right now since we
always run our tests on Unix systems and filepath.ToSlash is a no-op on
Unix. However, this does include some tests for the basic behavior to
verify that it's not regressed as a result of this change.

This will need to be reported in the changelog as a potential breaking
change, since anyone who was using Terraform _exclusively_ on Windows may
have been using expressions like "${path.module}foo\\bar" which they will
now need to update.

This fixes #14986.
  • Loading branch information
apparentlymart committed Dec 19, 2018
1 parent 456f28d commit 72f3a0f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
7 changes: 4 additions & 3 deletions terraform/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"sync"

Expand Down Expand Up @@ -423,7 +424,7 @@ func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.Sourc
})
return cty.DynamicVal, diags
}
return cty.StringVal(wd), diags
return cty.StringVal(filepath.ToSlash(wd)), diags

case "module":
moduleConfig := d.Evaluator.Config.DescendentForInstance(d.ModulePath)
Expand All @@ -433,11 +434,11 @@ func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.Sourc
panic(fmt.Sprintf("module.path read from module %s, which has no configuration", d.ModulePath))
}
sourceDir := moduleConfig.Module.SourceDir
return cty.StringVal(sourceDir), diags
return cty.StringVal(filepath.ToSlash(sourceDir)), diags

case "root":
sourceDir := d.Evaluator.Config.Module.SourceDir
return cty.StringVal(sourceDir), diags
return cty.StringVal(filepath.ToSlash(sourceDir)), diags

default:
suggestion := nameSuggestion(addr.Name, []string{"cwd", "module", "root"})
Expand Down
44 changes: 44 additions & 0 deletions terraform/evaluate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/zclconf/go-cty/cty"

"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
"github.com/hashicorp/terraform/tfdiags"
)

Expand Down Expand Up @@ -34,3 +35,46 @@ func TestEvaluatorGetTerraformAttr(t *testing.T) {
}
})
}

func TestEvaluatorGetPathAttr(t *testing.T) {
evaluator := &Evaluator{
Meta: &ContextMeta{
Env: "foo",
},
Config: &configs.Config{
Module: &configs.Module{
SourceDir: "bar/baz",
},
},
}
data := &evaluationStateData{
Evaluator: evaluator,
}
scope := evaluator.Scope(data, nil)

t.Run("module", func(t *testing.T) {
want := cty.StringVal("bar/baz")
got, diags := scope.Data.GetPathAttr(addrs.PathAttr{
Name: "module",
}, tfdiags.SourceRange{})
if len(diags) != 0 {
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
}
if !got.RawEquals(want) {
t.Errorf("wrong result %#v; want %#v", got, want)
}
})

t.Run("root", func(t *testing.T) {
want := cty.StringVal("bar/baz")
got, diags := scope.Data.GetPathAttr(addrs.PathAttr{
Name: "root",
}, tfdiags.SourceRange{})
if len(diags) != 0 {
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
}
if !got.RawEquals(want) {
t.Errorf("wrong result %#v; want %#v", got, want)
}
})
}

0 comments on commit 72f3a0f

Please sign in to comment.