From 042aead714955d8c1cd6f3879c224c5a786563cb Mon Sep 17 00:00:00 2001 From: Andreas Sommer Date: Tue, 2 Jul 2019 14:30:30 +0200 Subject: [PATCH] lang/funcs: add "abspath" function (#21409) --- lang/funcs/filesystem.go | 15 ++++++++++ lang/functions.go | 1 + lang/functions_test.go | 14 +++++++++ .../configuration/functions/abspath.html.md | 30 +++++++++++++++++++ website/layouts/functions.erb | 4 +++ 5 files changed, 64 insertions(+) create mode 100644 website/docs/configuration/functions/abspath.html.md diff --git a/lang/funcs/filesystem.go b/lang/funcs/filesystem.go index 7dfc9058758b..016b102d946b 100644 --- a/lang/funcs/filesystem.go +++ b/lang/funcs/filesystem.go @@ -237,6 +237,21 @@ var DirnameFunc = function.New(&function.Spec{ }, }) +// AbsPathFunc constructs a function that converts a filesystem path to an absolute path +var AbsPathFunc = function.New(&function.Spec{ + Params: []function.Parameter{ + { + Name: "path", + Type: cty.String, + }, + }, + Type: function.StaticReturnType(cty.String), + Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { + absPath, err := filepath.Abs(args[0].AsString()) + return cty.StringVal(filepath.ToSlash(absPath)), err + }, +}) + // PathExpandFunc constructs a function that expands a leading ~ character to the current user's home directory. var PathExpandFunc = function.New(&function.Spec{ Params: []function.Parameter{ diff --git a/lang/functions.go b/lang/functions.go index 5cc26d49b567..b77a55fdea21 100644 --- a/lang/functions.go +++ b/lang/functions.go @@ -31,6 +31,7 @@ func (s *Scope) Functions() map[string]function.Function { s.funcs = map[string]function.Function{ "abs": stdlib.AbsoluteFunc, + "abspath": funcs.AbsPathFunc, "basename": funcs.BasenameFunc, "base64decode": funcs.Base64DecodeFunc, "base64encode": funcs.Base64EncodeFunc, diff --git a/lang/functions_test.go b/lang/functions_test.go index 82a74ddaa7b3..985da7644633 100644 --- a/lang/functions_test.go +++ b/lang/functions_test.go @@ -2,6 +2,7 @@ package lang import ( "fmt" + "os" "path/filepath" "testing" @@ -53,6 +54,19 @@ func TestFunctions(t *testing.T) { }, }, + "abspath": { + { + `abspath(".")`, + cty.StringVal((func() string { + cwd, err := os.Getwd() + if err != nil { + panic(err) + } + return cwd + })()), + }, + }, + "base64decode": { { `base64decode("YWJjMTIzIT8kKiYoKSctPUB+")`, diff --git a/website/docs/configuration/functions/abspath.html.md b/website/docs/configuration/functions/abspath.html.md new file mode 100644 index 000000000000..cf5bceba1a7b --- /dev/null +++ b/website/docs/configuration/functions/abspath.html.md @@ -0,0 +1,30 @@ +--- +layout: "functions" +page_title: "abspath - Functions - Configuration Language" +sidebar_current: "docs-funcs-file-abspath" +description: |- + The abspath function converts the argument to an absolute filesystem path. +--- + +# `abspath` Function + +-> **Note:** This page is about Terraform 0.12 and later. For Terraform 0.11 and +earlier, see +[0.11 Configuration Language: Interpolation Syntax](../../configuration-0-11/interpolation.html). + +`abspath` takes a string containing a filesystem path and converts it +to an absolute path. That is, if the path is not absolute, it will be joined +with the current working directory. + +Referring directly to filesystem paths in resource arguments may cause +spurious diffs if the same configuration is applied from multiple systems or on +different host operating systems. We recommend using filesystem paths only +for transient values, such as the argument to [`file`](./file.html) (where +only the contents are then stored) or in `connection` and `provisioner` blocks. + +## Examples + +``` +> abspath(path.root) +/home/user/some/terraform/root +``` diff --git a/website/layouts/functions.erb b/website/layouts/functions.erb index ecde4226f784..ce88dff48d3f 100644 --- a/website/layouts/functions.erb +++ b/website/layouts/functions.erb @@ -272,6 +272,10 @@ Filesystem Functions