A variable that appears only inside the message of a required-variable expansion is left out of ExtractVariables: ${U:?${B}} and ${U?$B} report U alone, while ${U:-${B}} and ${U:+${B}} report both U and B, and Substitute expands B into the message of the same template:
package main
import (
"fmt"
"sort"
"github.com/compose-spec/compose-go/v2/template"
)
func main() {
for _, tmpl := range []string{"${U:-${B}}", "${U:+${B}}", "${U:?${B}}", "${U?$B}"} {
vars := template.ExtractVariables(map[string]interface{}{"k": tmpl}, nil)
names := make([]string, 0, len(vars))
for name := range vars {
names = append(names, name)
}
sort.Strings(names)
fmt.Printf("%-12s %v\n", tmpl, names)
}
mapping := func(name string) (string, bool) {
if name == "B" {
return "value of B", true
}
return "", false
}
_, err := template.SubstituteWithOptions("${U:?${B}}", mapping, template.WithoutLogging)
fmt.Println(err)
}
Output:
${U:-${B}} [B U]
${U:+${B}} [B U]
${U:?${B}} [U]
${U?$B} [U]
required variable U is missing a value: value of B
The specification lists ${VARIABLE?$FOO} among the nested interpolations, and substitution does read B when building the message, so I expected ExtractVariables to report B for the :? and ? forms as it does for :- and :+.
Tested on compose-go v2.15.0 and on current main (f18e211).
BTW, this was found by an automated program that writes property-based tests for various open source projects using hegel (but it has been reviewed by hand before reporting). We've also potentially found (but not yet hand validated) 2 other bugs in compose-go. You can see the tests at https://github.com/hegeldev/hegel-zoo/tree/main/targets/go/compose-go. Let us know if you would like us to file the other bugs found and/or contribute the tests. NB the tests are currently LLM generated and probably not yet suitable for inclusion as is, but we're happy to help get them into a better state if you want them.
A variable that appears only inside the message of a required-variable expansion is left out of
ExtractVariables:${U:?${B}}and${U?$B}reportUalone, while${U:-${B}}and${U:+${B}}report bothUandB, andSubstituteexpandsBinto the message of the same template:Output:
The specification lists
${VARIABLE?$FOO}among the nested interpolations, and substitution does readBwhen building the message, so I expectedExtractVariablesto reportBfor the:?and?forms as it does for:-and:+.Tested on compose-go v2.15.0 and on current
main(f18e211).BTW, this was found by an automated program that writes property-based tests for various open source projects using hegel (but it has been reviewed by hand before reporting). We've also potentially found (but not yet hand validated) 2 other bugs in compose-go. You can see the tests at https://github.com/hegeldev/hegel-zoo/tree/main/targets/go/compose-go. Let us know if you would like us to file the other bugs found and/or contribute the tests. NB the tests are currently LLM generated and probably not yet suitable for inclusion as is, but we're happy to help get them into a better state if you want them.