mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
feat: Add support for tofu.workspace
which will be resolved in the same way as terraform.workspace
(#1305)
Signed-off-by: Syasusu <syasusu@163.com>
This commit is contained in:
parent
c748fa0176
commit
1c0cb13bf7
@ -328,11 +328,19 @@ func parseRef(traversal hcl.Traversal) (*Reference, tfdiags.Diagnostics) {
|
||||
case "terraform":
|
||||
name, rng, remain, diags := parseSingleAttrRef(traversal)
|
||||
return &Reference{
|
||||
Subject: TerraformAttr{Name: name},
|
||||
Subject: NewTerraformAttr(IdentTerraform, name),
|
||||
SourceRange: tfdiags.SourceRangeFromHCL(rng),
|
||||
Remaining: remain,
|
||||
}, diags
|
||||
|
||||
case "tofu":
|
||||
name, rng, remain, parsedDiags := parseSingleAttrRef(traversal)
|
||||
return &Reference{
|
||||
Subject: NewTerraformAttr(IdentTofu, name),
|
||||
SourceRange: tfdiags.SourceRangeFromHCL(rng),
|
||||
Remaining: remain,
|
||||
}, parsedDiags
|
||||
|
||||
case "var":
|
||||
name, rng, remain, diags := parseSingleAttrRef(traversal)
|
||||
return &Reference{
|
||||
|
@ -606,9 +606,7 @@ func TestParseRef(t *testing.T) {
|
||||
{
|
||||
`terraform.workspace`,
|
||||
&Reference{
|
||||
Subject: TerraformAttr{
|
||||
Name: "workspace",
|
||||
},
|
||||
Subject: NewTerraformAttr("terraform", "workspace"),
|
||||
SourceRange: tfdiags.SourceRange{
|
||||
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
|
||||
End: tfdiags.SourcePos{Line: 1, Column: 20, Byte: 19},
|
||||
@ -619,9 +617,7 @@ func TestParseRef(t *testing.T) {
|
||||
{
|
||||
`terraform.workspace.blah`,
|
||||
&Reference{
|
||||
Subject: TerraformAttr{
|
||||
Name: "workspace",
|
||||
},
|
||||
Subject: NewTerraformAttr("terraform", "workspace"),
|
||||
SourceRange: tfdiags.SourceRange{
|
||||
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
|
||||
End: tfdiags.SourcePos{Line: 1, Column: 20, Byte: 19},
|
||||
@ -649,6 +645,49 @@ func TestParseRef(t *testing.T) {
|
||||
`The "terraform" object does not support this operation.`,
|
||||
},
|
||||
|
||||
// tofu
|
||||
{
|
||||
`tofu.workspace`,
|
||||
&Reference{
|
||||
Subject: NewTerraformAttr("tofu", "workspace"),
|
||||
SourceRange: tfdiags.SourceRange{
|
||||
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
|
||||
End: tfdiags.SourcePos{Line: 1, Column: 15, Byte: 14},
|
||||
},
|
||||
},
|
||||
``,
|
||||
},
|
||||
{
|
||||
`tofu.workspace.blah`,
|
||||
&Reference{
|
||||
Subject: NewTerraformAttr("tofu", "workspace"),
|
||||
SourceRange: tfdiags.SourceRange{
|
||||
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
|
||||
End: tfdiags.SourcePos{Line: 1, Column: 15, Byte: 14},
|
||||
},
|
||||
Remaining: hcl.Traversal{
|
||||
hcl.TraverseAttr{
|
||||
Name: "blah",
|
||||
SrcRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
|
||||
End: hcl.Pos{Line: 1, Column: 20, Byte: 19},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
``, // valid at this layer, but will fail during eval because "workspace" is a string
|
||||
},
|
||||
{
|
||||
`tofu`,
|
||||
nil,
|
||||
`The "tofu" object cannot be accessed directly. Instead, access one of its attributes.`,
|
||||
},
|
||||
{
|
||||
`tofu["workspace"]`,
|
||||
nil,
|
||||
`The "tofu" object does not support this operation.`,
|
||||
},
|
||||
|
||||
// var
|
||||
{
|
||||
`var.foo`,
|
||||
|
@ -5,15 +5,28 @@
|
||||
|
||||
package addrs
|
||||
|
||||
// TerraformAttr is the address of an attribute of the "terraform" object in
|
||||
// the interpolation scope, like "terraform.workspace".
|
||||
const (
|
||||
IdentTerraform = "terraform"
|
||||
IdentTofu = "tofu"
|
||||
)
|
||||
|
||||
func NewTerraformAttr(alias, name string) TerraformAttr {
|
||||
return TerraformAttr{
|
||||
Name: name,
|
||||
Alias: alias,
|
||||
}
|
||||
}
|
||||
|
||||
// TerraformAttr is the address of an attribute of the "terraform" and "tofu" object in
|
||||
// the interpolation scope, like "terraform.workspace" and "tofu.workspace".
|
||||
type TerraformAttr struct {
|
||||
referenceable
|
||||
Name string
|
||||
Name string
|
||||
Alias string
|
||||
}
|
||||
|
||||
func (ta TerraformAttr) String() string {
|
||||
return "terraform." + ta.Name
|
||||
return ta.Alias + "." + ta.Name
|
||||
}
|
||||
|
||||
func (ta TerraformAttr) UniqueKey() UniqueKey {
|
||||
|
@ -1735,8 +1735,44 @@ func TestApply_disableBackup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply_tfWorkspace(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("apply-tf-workspace"), td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := testProvider()
|
||||
view, done := testView(t)
|
||||
c := &ApplyCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(p),
|
||||
View: view,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
"-state", statePath,
|
||||
}
|
||||
code := c.Run(args)
|
||||
output := done(t)
|
||||
if code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, output.Stderr())
|
||||
}
|
||||
|
||||
expected := strings.TrimSpace(`
|
||||
<no state>
|
||||
Outputs:
|
||||
|
||||
output = default
|
||||
`)
|
||||
testStateOutput(t, statePath, expected)
|
||||
}
|
||||
|
||||
// Test that the OpenTofu env is passed through
|
||||
func TestApply_tofuEnv(t *testing.T) {
|
||||
func TestApply_tofuWorkspace(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("apply-tofu-workspace"), td)
|
||||
@ -1772,8 +1808,69 @@ output = default
|
||||
testStateOutput(t, statePath, expected)
|
||||
}
|
||||
|
||||
func TestApply_tfWorkspaceNonDefault(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("apply-tf-workspace"), td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// Create new env
|
||||
{
|
||||
ui := new(cli.MockUi)
|
||||
newCmd := &WorkspaceNewCommand{
|
||||
Meta: Meta{
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
if code := newCmd.Run([]string{"test"}); code != 0 {
|
||||
t.Fatal("error creating workspace")
|
||||
}
|
||||
}
|
||||
|
||||
// Switch to it
|
||||
{
|
||||
args := []string{"test"}
|
||||
ui := new(cli.MockUi)
|
||||
selCmd := &WorkspaceSelectCommand{
|
||||
Meta: Meta{
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
if code := selCmd.Run(args); code != 0 {
|
||||
t.Fatal("error switching workspace")
|
||||
}
|
||||
}
|
||||
|
||||
p := testProvider()
|
||||
view, done := testView(t)
|
||||
c := &ApplyCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(p),
|
||||
View: view,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-auto-approve",
|
||||
}
|
||||
code := c.Run(args)
|
||||
output := done(t)
|
||||
if code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, output.Stderr())
|
||||
}
|
||||
|
||||
statePath := filepath.Join("terraform.tfstate.d", "test", "terraform.tfstate")
|
||||
expected := strings.TrimSpace(`
|
||||
<no state>
|
||||
Outputs:
|
||||
|
||||
output = test
|
||||
`)
|
||||
testStateOutput(t, statePath, expected)
|
||||
}
|
||||
|
||||
// Test that the OpenTofu env is passed through
|
||||
func TestApply_tofuEnvNonDefault(t *testing.T) {
|
||||
func TestApply_tofuWorkspaceNonDefault(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("apply-tofu-workspace"), td)
|
||||
|
3
internal/command/testdata/apply-tf-workspace/main.tf
vendored
Normal file
3
internal/command/testdata/apply-tf-workspace/main.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
output "output" {
|
||||
value = terraform.workspace
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
output "output" {
|
||||
value = terraform.workspace
|
||||
value = tofu.workspace
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func onlySelfRefs(body hcl.Body) hcl.Diagnostics {
|
||||
for _, v := range attr.Expr.Variables() {
|
||||
valid := false
|
||||
switch v.RootName() {
|
||||
case "self", "path", "terraform":
|
||||
case "self", "path", "terraform", "tofu":
|
||||
valid = true
|
||||
case "count":
|
||||
// count must use "index"
|
||||
|
123
internal/configs/provisioner_test.go
Normal file
123
internal/configs/provisioner_test.go
Normal file
@ -0,0 +1,123 @@
|
||||
// Copyright (c) The OpenTofu Authors
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) 2023 HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package configs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hcltest"
|
||||
)
|
||||
|
||||
func TestProvisionerBlock_decode(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
input *hcl.Block
|
||||
want *Provisioner
|
||||
err string
|
||||
}{
|
||||
"refer terraform.workspace when destroy": {
|
||||
input: &hcl.Block{
|
||||
Type: "provisioner",
|
||||
Labels: []string{"local-exec"},
|
||||
Body: hcltest.MockBody(&hcl.BodyContent{
|
||||
Attributes: hcl.Attributes{
|
||||
"when": {
|
||||
Name: "when",
|
||||
Expr: hcltest.MockExprTraversalSrc("destroy"),
|
||||
},
|
||||
"command": {
|
||||
Name: "command",
|
||||
Expr: hcltest.MockExprTraversalSrc("terraform.workspace"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
DefRange: blockRange,
|
||||
LabelRanges: []hcl.Range{hcl.Range{}},
|
||||
},
|
||||
want: &Provisioner{
|
||||
Type: "local-exec",
|
||||
When: ProvisionerWhenDestroy,
|
||||
OnFailure: ProvisionerOnFailureFail,
|
||||
DeclRange: blockRange,
|
||||
},
|
||||
},
|
||||
"refer tofu.workspace when destroy": {
|
||||
input: &hcl.Block{
|
||||
Type: "provisioner",
|
||||
Labels: []string{"local-exec"},
|
||||
Body: hcltest.MockBody(&hcl.BodyContent{
|
||||
Attributes: hcl.Attributes{
|
||||
"when": {
|
||||
Name: "when",
|
||||
Expr: hcltest.MockExprTraversalSrc("destroy"),
|
||||
},
|
||||
"command": {
|
||||
Name: "command",
|
||||
Expr: hcltest.MockExprTraversalSrc("tofu.workspace"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
DefRange: blockRange,
|
||||
LabelRanges: []hcl.Range{hcl.Range{}},
|
||||
},
|
||||
want: &Provisioner{
|
||||
Type: "local-exec",
|
||||
When: ProvisionerWhenDestroy,
|
||||
OnFailure: ProvisionerOnFailureFail,
|
||||
DeclRange: blockRange,
|
||||
},
|
||||
},
|
||||
"refer unknown.workspace when destroy": {
|
||||
input: &hcl.Block{
|
||||
Type: "provisioner",
|
||||
Labels: []string{"local-exec"},
|
||||
Body: hcltest.MockBody(&hcl.BodyContent{
|
||||
Attributes: hcl.Attributes{
|
||||
"when": {
|
||||
Name: "when",
|
||||
Expr: hcltest.MockExprTraversalSrc("destroy"),
|
||||
},
|
||||
"command": {
|
||||
Name: "command",
|
||||
Expr: hcltest.MockExprTraversalSrc("unknown.workspace"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
DefRange: blockRange,
|
||||
LabelRanges: []hcl.Range{hcl.Range{}},
|
||||
},
|
||||
want: &Provisioner{
|
||||
Type: "local-exec",
|
||||
When: ProvisionerWhenDestroy,
|
||||
OnFailure: ProvisionerOnFailureFail,
|
||||
DeclRange: blockRange,
|
||||
},
|
||||
err: "Invalid reference from destroy provisioner",
|
||||
},
|
||||
}
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
got, diags := decodeProvisionerBlock(test.input)
|
||||
|
||||
if diags.HasErrors() {
|
||||
if test.err == "" {
|
||||
t.Fatalf("unexpected error: %s", diags.Errs())
|
||||
}
|
||||
if gotErr := diags[0].Summary; gotErr != test.err {
|
||||
t.Errorf("wrong error, got %q, want %q", gotErr, test.err)
|
||||
}
|
||||
} else if test.err != "" {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
|
||||
if !cmp.Equal(got, test.want, cmpopts.IgnoreInterfaces(struct{ hcl.Body }{})) {
|
||||
t.Fatalf("wrong result: %s", cmp.Diff(got, test.want))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -11,11 +11,12 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/didyoumean"
|
||||
"github.com/opentofu/opentofu/internal/lang"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// newStaticScope creates a lang.Scope that's backed by the static view of the module represented by the StaticEvaluator
|
||||
|
@ -146,6 +146,7 @@ func (s *Scope) EvalSelfBlock(body hcl.Body, self cty.Value, schema *configschem
|
||||
|
||||
vals["path"] = cty.ObjectVal(pathAttrs)
|
||||
vals["terraform"] = cty.ObjectVal(terraformAttrs)
|
||||
vals["tofu"] = cty.ObjectVal(terraformAttrs)
|
||||
|
||||
ctx := &hcl.EvalContext{
|
||||
Variables: vals,
|
||||
@ -557,6 +558,7 @@ func (b *evalVarBuilder) buildAllVariablesInto(vals map[string]cty.Value) {
|
||||
vals["local"] = cty.ObjectVal(b.localValues)
|
||||
vals["path"] = cty.ObjectVal(b.pathAttrs)
|
||||
vals["terraform"] = cty.ObjectVal(b.terraformAttrs)
|
||||
vals["tofu"] = cty.ObjectVal(b.terraformAttrs)
|
||||
vals["count"] = cty.ObjectVal(b.countAttrs)
|
||||
vals["each"] = cty.ObjectVal(b.forEachAttrs)
|
||||
|
||||
|
@ -349,6 +349,20 @@ func TestScopeEvalContext(t *testing.T) {
|
||||
"terraform": cty.ObjectVal(map[string]cty.Value{
|
||||
"workspace": cty.StringVal("default"),
|
||||
}),
|
||||
"tofu": cty.ObjectVal(map[string]cty.Value{
|
||||
"workspace": cty.StringVal("default"),
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
`tofu.workspace`,
|
||||
map[string]cty.Value{
|
||||
"terraform": cty.ObjectVal(map[string]cty.Value{
|
||||
"workspace": cty.StringVal("default"),
|
||||
}),
|
||||
"tofu": cty.ObjectVal(map[string]cty.Value{
|
||||
"workspace": cty.StringVal("default"),
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -887,6 +901,13 @@ func TestScopeEvalSelfBlock(t *testing.T) {
|
||||
"num": cty.NullVal(cty.Number),
|
||||
},
|
||||
},
|
||||
{
|
||||
Config: `attr = tofu.workspace`,
|
||||
Want: map[string]cty.Value{
|
||||
"attr": cty.StringVal("default"),
|
||||
"num": cty.NullVal(cty.Number),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
)
|
||||
|
||||
@ -194,6 +194,10 @@ func (diags Diagnostics) Sort() {
|
||||
sort.Stable(sortDiagnostics(diags))
|
||||
}
|
||||
|
||||
func (diags Diagnostics) TrimDuplicated() {
|
||||
sort.Stable(sortDiagnostics(diags))
|
||||
}
|
||||
|
||||
type diagnosticsAsError struct {
|
||||
Diagnostics
|
||||
}
|
||||
|
@ -8649,7 +8649,34 @@ resource "null_instance" "depends" {
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Apply_terraformWorkspace(t *testing.T) {
|
||||
func TestContext2Apply_tfWorkspace(t *testing.T) {
|
||||
m := testModule(t, "apply-tf-workspace")
|
||||
p := testProvider("aws")
|
||||
p.PlanResourceChangeFn = testDiffFn
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Meta: &ContextMeta{Env: "foo"},
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(m, states.NewState(), DefaultPlanOpts)
|
||||
assertNoErrors(t, diags)
|
||||
|
||||
state, diags := ctx.Apply(plan, m)
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("diags: %s", diags.Err())
|
||||
}
|
||||
|
||||
actual := state.RootModule().OutputValues["output"]
|
||||
expected := cty.StringVal("foo")
|
||||
if actual == nil || actual.Value != expected {
|
||||
t.Fatalf("wrong value\ngot: %#v\nwant: %#v", actual.Value, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Apply_tofuWorkspace(t *testing.T) {
|
||||
m := testModule(t, "apply-tofu-workspace")
|
||||
p := testProvider("aws")
|
||||
p.PlanResourceChangeFn = testDiffFn
|
||||
|
@ -919,7 +919,6 @@ func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAdd
|
||||
func (d *evaluationStateData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
switch addr.Name {
|
||||
|
||||
case "workspace":
|
||||
workspaceName := d.Evaluator.Meta.Env
|
||||
return cty.StringVal(workspaceName), diags
|
||||
@ -930,8 +929,8 @@ func (d *evaluationStateData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfd
|
||||
// removed.
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: `Invalid "terraform" attribute`,
|
||||
Detail: `The terraform.env attribute was deprecated in v0.10 and removed in v0.12. The "state environment" concept was renamed to "workspace" in v0.12, and so the workspace name can now be accessed using the terraform.workspace attribute.`,
|
||||
Summary: fmt.Sprintf("Invalid %q attribute", addr.Alias),
|
||||
Detail: fmt.Sprintf(`The %s.env attribute was deprecated in v0.10 and removed in v0.12. The "state environment" concept was renamed to "workspace" in v0.12, and so the workspace name can now be accessed using the %s.workspace attribute.`, addr.Alias, addr.Alias),
|
||||
Subject: rng.ToHCL().Ptr(),
|
||||
})
|
||||
return cty.DynamicVal, diags
|
||||
@ -939,8 +938,8 @@ func (d *evaluationStateData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfd
|
||||
default:
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: `Invalid "terraform" attribute`,
|
||||
Detail: fmt.Sprintf(`The "terraform" object does not have an attribute named %q. The only supported attribute is terraform.workspace, the name of the currently-selected workspace.`, addr.Name),
|
||||
Summary: fmt.Sprintf("Invalid %q attribute", addr.Alias),
|
||||
Detail: fmt.Sprintf(`The %q object does not have an attribute named %q. The only supported attribute is %s.workspace, the name of the currently-selected workspace.`, addr.Alias, addr.Name, addr.Alias),
|
||||
Subject: rng.ToHCL().Ptr(),
|
||||
})
|
||||
return cty.DynamicVal, diags
|
||||
|
@ -33,11 +33,20 @@ func TestEvaluatorGetTerraformAttr(t *testing.T) {
|
||||
}
|
||||
scope := evaluator.Scope(data, nil, nil, nil)
|
||||
|
||||
t.Run("workspace", func(t *testing.T) {
|
||||
t.Run("terraform.workspace", func(t *testing.T) {
|
||||
want := cty.StringVal("foo")
|
||||
got, diags := scope.Data.GetTerraformAttr(addrs.TerraformAttr{
|
||||
Name: "workspace",
|
||||
}, tfdiags.SourceRange{})
|
||||
got, diags := scope.Data.GetTerraformAttr(addrs.NewTerraformAttr("terraform", "workspace"), tfdiags.SourceRange{})
|
||||
if len(diags) != 0 {
|
||||
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
|
||||
}
|
||||
if !got.RawEquals(want) {
|
||||
t.Errorf("wrong result %q; want %q", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("tofu.workspace", func(t *testing.T) {
|
||||
want := cty.StringVal("foo")
|
||||
got, diags := scope.Data.GetTerraformAttr(addrs.NewTerraformAttr("tofu", "workspace"), tfdiags.SourceRange{})
|
||||
if len(diags) != 0 {
|
||||
t.Errorf("unexpected diagnostics %s", spew.Sdump(diags))
|
||||
}
|
||||
|
3
internal/tofu/testdata/apply-tf-workspace/main.tf
vendored
Normal file
3
internal/tofu/testdata/apply-tf-workspace/main.tf
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
output "output" {
|
||||
value = terraform.workspace
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
output "output" {
|
||||
value = "${terraform.workspace}"
|
||||
value = tofu.workspace
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user