@@ -26,6 +26,45 @@ type parameterValue struct {
2626 Source parameterValueSource
2727}
2828
29+ type ResolverError struct {
30+ Diagnostics hcl.Diagnostics
31+ Parameter map [string ]hcl.Diagnostics
32+ }
33+
34+ // Error is a pretty bad format for these errors. Try to avoid using this.
35+ func (e * ResolverError ) Error () string {
36+ var diags hcl.Diagnostics
37+ diags = diags .Extend (e .Diagnostics )
38+ for _ , d := range e .Parameter {
39+ diags = diags .Extend (d )
40+ }
41+
42+ return diags .Error ()
43+ }
44+
45+ func (e * ResolverError ) HasError () bool {
46+ if e .Diagnostics .HasErrors () {
47+ return true
48+ }
49+
50+ for _ , diags := range e .Parameter {
51+ if diags .HasErrors () {
52+ return true
53+ }
54+ }
55+ return false
56+ }
57+
58+ func (e * ResolverError ) Extend (parameterName string , diag hcl.Diagnostics ) {
59+ if e .Parameter == nil {
60+ e .Parameter = make (map [string ]hcl.Diagnostics )
61+ }
62+ if _ , ok := e .Parameter [parameterName ]; ! ok {
63+ e .Parameter [parameterName ] = hcl.Diagnostics {}
64+ }
65+ e .Parameter [parameterName ] = e .Parameter [parameterName ].Extend (diag )
66+ }
67+
2968//nolint:revive // firstbuild is a control flag to turn on immutable validation
3069func ResolveParameters (
3170 ctx context.Context ,
@@ -73,7 +112,10 @@ func ResolveParameters(
73112 // always be valid. If there is a case where this is not true, then this has to
74113 // be changed to allow the build to continue with a different set of values.
75114
76- return nil , diags
115+ return nil , & ResolverError {
116+ Diagnostics : diags ,
117+ Parameter : nil ,
118+ }
77119 }
78120
79121 // The user's input now needs to be validated against the parameters.
@@ -113,12 +155,16 @@ func ResolveParameters(
113155 // are fatal. Additional validation for immutability has to be done manually.
114156 output , diags = renderer .Render (ctx , ownerID , values .ValuesMap ())
115157 if diags .HasErrors () {
116- return nil , diags
158+ return nil , & ResolverError {
159+ Diagnostics : diags ,
160+ Parameter : nil ,
161+ }
117162 }
118163
119164 // parameterNames is going to be used to remove any excess values that were left
120165 // around without a parameter.
121166 parameterNames := make (map [string ]struct {}, len (output .Parameters ))
167+ parameterError := & ResolverError {}
122168 for _ , parameter := range output .Parameters {
123169 parameterNames [parameter .Name ] = struct {}{}
124170
@@ -132,20 +178,22 @@ func ResolveParameters(
132178 }
133179
134180 // An immutable parameter was changed, which is not allowed.
135- // Add the failed diagnostic to the output.
136- diags = diags .Append (& hcl.Diagnostic {
137- Severity : hcl .DiagError ,
138- Summary : "Immutable parameter changed" ,
139- Detail : fmt .Sprintf ("Parameter %q is not mutable, so it can't be updated after creating a workspace." , parameter .Name ),
140- Subject : src ,
181+ // Add a failed diagnostic to the output.
182+ parameterError .Extend (parameter .Name , hcl.Diagnostics {
183+ & hcl.Diagnostic {
184+ Severity : hcl .DiagError ,
185+ Summary : "Immutable parameter changed" ,
186+ Detail : fmt .Sprintf ("Parameter %q is not mutable, so it can't be updated after creating a workspace." , parameter .Name ),
187+ Subject : src ,
188+ },
141189 })
142190 }
143191 }
144192
145193 // TODO: Fix the `hcl.Diagnostics(...)` type casting. It should not be needed.
146194 if hcl .Diagnostics (parameter .Diagnostics ).HasErrors () {
147- // All validation errors are raised here.
148- diags = diags .Extend (hcl .Diagnostics (parameter .Diagnostics ))
195+ // All validation errors are raised here for each parameter .
196+ parameterError .Extend (parameter . Name , hcl .Diagnostics (parameter .Diagnostics ))
149197 }
150198
151199 // If the parameter has a value, but it was not set explicitly by the user at any
@@ -174,8 +222,13 @@ func ResolveParameters(
174222 }
175223 }
176224
225+ if parameterError .HasError () {
226+ // If there are any errors, return them.
227+ return nil , parameterError
228+ }
229+
177230 // Return the values to be saved for the build.
178- return values .ValuesMap (), diags
231+ return values .ValuesMap (), nil
179232}
180233
181234type parameterValueMap map [string ]parameterValue
0 commit comments