Skip to content

Commit 1a0b055

Browse files
committed
accept empty default values
1 parent 3fcc847 commit 1a0b055

File tree

7 files changed

+77
-45
lines changed

7 files changed

+77
-45
lines changed

extract/parameter.go

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func ParameterFromBlock(block *terraform.Block) (*types.Parameter, hcl.Diagnosti
5050

5151
pVal := richParameterValue(block)
5252

53-
def := types.StringLiteral("")
53+
def := types.NullString()
5454
defAttr := block.GetAttribute("default")
5555
if !defAttr.IsNil() {
5656
def = types.ToHCLString(block, defAttr)
@@ -138,45 +138,10 @@ func ParameterFromBlock(block *terraform.Block) (*types.Parameter, hcl.Diagnosti
138138
p.Validations = append(p.Validations, &valid)
139139
}
140140

141-
ctyType, err := p.CtyType()
142-
if err != nil {
143-
paramTypeDiag := &hcl.Diagnostic{
144-
Severity: hcl.DiagError,
145-
Summary: fmt.Sprintf("Invalid parameter type %q", p.Type),
146-
Detail: err.Error(),
147-
Context: &block.HCLBlock().DefRange,
148-
}
149-
150-
if attr := block.GetAttribute("type"); attr != nil && !attr.IsNil() {
151-
paramTypeDiag.Subject = &attr.HCLAttribute().Range
152-
paramTypeDiag.Expression = attr.HCLAttribute().Expr
153-
paramTypeDiag.EvalContext = block.Context().Inner()
154-
}
155-
diags = diags.Append(paramTypeDiag)
156-
p.FormType = provider.ParameterFormTypeError
157-
}
158-
159-
if ctyType != cty.NilType && pVal.Value.Type().Equals(cty.String) {
160-
// TODO: Wish we could support more types, but only string types are
161-
// allowed.
162-
valStr := pVal.Value.AsString()
163-
// Apply validations to the parameter value
164-
for _, v := range p.Validations {
165-
if err := v.Valid(string(pType), valStr); err != nil {
166-
diags = diags.Append(&hcl.Diagnostic{
167-
Severity: hcl.DiagError,
168-
Summary: fmt.Sprintf("Paramater validation failed for value %q", valStr),
169-
Detail: err.Error(),
170-
Expression: pVal.ValueExpr,
171-
})
172-
}
173-
}
174-
}
175-
176141
if !diags.HasErrors() {
177142
// Only do this validation if the parameter is valid, as if some errors
178143
// exist, then this is likely to fail be excess information.
179-
diags = diags.Extend(p.Valid())
144+
diags = diags.Extend(p.Valid(p.Value))
180145
}
181146

182147
usageDiags := ParameterUsageDiagnostics(p)
@@ -194,7 +159,9 @@ func ParameterFromBlock(block *terraform.Block) (*types.Parameter, hcl.Diagnosti
194159
func ParameterUsageDiagnostics(p types.Parameter) hcl.Diagnostics {
195160
valErr := "The value of a parameter is required to be sourced (default or input) for the parameter to function."
196161
var diags hcl.Diagnostics
197-
if !p.Value.Valid() {
162+
if p.Value.Value.IsNull() {
163+
// Allow null values
164+
} else if !p.Value.Valid() {
198165
diags = diags.Append(&hcl.Diagnostic{
199166
Severity: hcl.DiagError,
200167
Summary: "Parameter value is not valid",
@@ -478,6 +445,14 @@ func richParameterValue(block *terraform.Block) types.HCLString {
478445

479446
val, diags := valRef.Value(block.Context().Inner())
480447
source := hclext.CreateDotReferenceFromTraversal(valRef.Traversal)
448+
449+
// If no value attribute exists, then the value is `null`.
450+
if diags.HasErrors() && diags[0].Summary == "Unsupported attribute" {
451+
s := types.NullString()
452+
s.Source = &source
453+
return s
454+
}
455+
481456
return types.HCLString{
482457
Value: val,
483458
ValueDiags: diags,

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/aquasecurity/trivy v0.58.2
88
github.com/coder/guts v1.0.2-0.20250227211802-139809366a22
99
github.com/coder/serpent v0.10.0
10-
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250502142605-22f12cb73817
10+
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250505161541-0fd96eeace73
1111
github.com/coder/websocket v1.8.13
1212
github.com/go-chi/chi v4.1.2+incompatible
1313
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,8 @@ github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx
718718
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0/go.mod h1:5UuS2Ts+nTToAMeOjNlnHFkPahrtDkmpydBen/3wgZc=
719719
github.com/coder/serpent v0.10.0 h1:ofVk9FJXSek+SmL3yVE3GoArP83M+1tX+H7S4t8BSuM=
720720
github.com/coder/serpent v0.10.0/go.mod h1:cZFW6/fP+kE9nd/oRkEHJpG6sXCtQ+AX7WMMEHv0Y3Q=
721-
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250502142605-22f12cb73817 h1:4ryzTbgCe+AHk/G03y48Rtg3Y+pfr5FfhGt/eEckJ6g=
722-
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250502142605-22f12cb73817/go.mod h1:56/KdGYaA+VbwXJbTI8CA57XPfnuTxN8rjxbR34PbZw=
721+
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250505161541-0fd96eeace73 h1:Gax/pSsln9cSTueP5teoWM4EPqEux4BUp7VlECiuW2M=
722+
github.com/coder/terraform-provider-coder/v2 v2.4.0-pre1.0.20250505161541-0fd96eeace73/go.mod h1:2kaBpn5k9ZWtgKq5k4JbkVZG9DzEqR4mJSmpdshcO+s=
723723
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=
724724
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
725725
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=

preview_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,16 @@ func Test_Extract(t *testing.T) {
211211
unknownTags: []string{},
212212
params: map[string]assertParam{},
213213
},
214+
{
215+
name: "empty default",
216+
dir: "emptydefault",
217+
expTags: map[string]string{},
218+
input: preview.Input{},
219+
unknownTags: []string{},
220+
params: map[string]assertParam{
221+
"word": ap(),
222+
},
223+
},
214224
{
215225
name: "many modules",
216226
dir: "manymodules",

testdata/emptydefault/main.tf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
version = "2.4.0-pre0"
6+
}
7+
}
8+
}
9+
10+
data "coder_parameter" "word" {
11+
name = "word"
12+
description = "Select something"
13+
type = "string"
14+
order = 1
15+
# No default selected
16+
17+
option {
18+
name = "Bird"
19+
value = "bird"
20+
description = "An animal that can fly."
21+
}
22+
option {
23+
name = "Boat"
24+
value = "boat"
25+
}
26+
}

types/parameter.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,35 @@ type ParameterOption struct {
9393
Icon string `json:"icon"`
9494
}
9595

96-
func (r *ParameterData) Valid() hcl.Diagnostics {
97-
diag := (&provider.Parameter{
96+
func (r *ParameterData) Valid(value HCLString) hcl.Diagnostics {
97+
var defPtr *string
98+
if !r.DefaultValue.Value.IsNull() {
99+
def := r.DefaultValue.Value.AsString()
100+
defPtr = &def
101+
}
102+
103+
var valuePtr *string
104+
// TODO: What to do if it is not valid?
105+
if value.Valid() {
106+
val := value.Value.AsString()
107+
valuePtr = &val
108+
}
109+
110+
_, diag := (&provider.Parameter{
98111
Name: r.Name,
99112
DisplayName: r.DisplayName,
100113
Description: r.Description,
101114
Type: provider.OptionType(r.Type),
102115
FormType: r.FormType,
103116
Mutable: r.Mutable,
104-
Default: r.DefaultValue.AsString(),
117+
Default: defPtr,
105118
Icon: r.Icon,
106119
Option: providerOptions(r.Options),
107120
Validation: providerValidations(r.Validations),
108121
Optional: false,
109122
Order: int(r.Order),
110123
Ephemeral: r.Ephemeral,
111-
}).Valid()
124+
}).ValidateInput(valuePtr)
112125

113126
if diag.HasError() {
114127
// TODO: We can take the attr path and decorate the error with

types/value.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ func StringLiteral(s string) HCLString {
7373
}
7474
}
7575

76+
func NullString() HCLString {
77+
v := cty.NullVal(cty.String)
78+
return HCLString{
79+
Value: v,
80+
ValueExpr: &hclsyntax.LiteralValueExpr{Val: v},
81+
}
82+
}
83+
7684
// AsString is a safe function. It will always return a string.
7785
// The caller should check if this value is Valid and known before
7886
// calling this function.

0 commit comments

Comments
 (0)