mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-31 23:58:03 +08:00
Allow for user defined functions
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/docker/buildx/build"
|
||||
"github.com/docker/buildx/util/platformutil"
|
||||
"github.com/docker/docker/pkg/urlutil"
|
||||
hcl "github.com/hashicorp/hcl/v2"
|
||||
"github.com/moby/buildkit/session/auth/authprovider"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -73,6 +74,7 @@ type Config struct {
|
||||
Variables []*Variable `json:"-" hcl:"variable,block"`
|
||||
Groups []*Group `json:"groups" hcl:"group,block"`
|
||||
Targets []*Target `json:"targets" hcl:"target,block"`
|
||||
Remain hcl.Body `json:"-" hcl:",remain"`
|
||||
}
|
||||
|
||||
func mergeConfig(c1, c2 Config) Config {
|
||||
|
30
bake/hcl.go
30
bake/hcl.go
@@ -5,7 +5,9 @@ import (
|
||||
"strings"
|
||||
|
||||
hcl "github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/ext/userfunc"
|
||||
"github.com/hashicorp/hcl/v2/hclsimple"
|
||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/function"
|
||||
"github.com/zclconf/go-cty/cty/function/stdlib"
|
||||
@@ -14,7 +16,7 @@ import (
|
||||
// Collection of generally useful functions in cty-using applications, which
|
||||
// HCL supports. These functions are available for use in HCL files.
|
||||
var (
|
||||
functions = map[string]function.Function{
|
||||
stdlibFunctions = map[string]function.Function{
|
||||
"absolute": stdlib.AbsoluteFunc,
|
||||
"add": stdlib.AddFunc,
|
||||
"and": stdlib.AndFunc,
|
||||
@@ -71,6 +73,21 @@ type staticConfig struct {
|
||||
}
|
||||
|
||||
func ParseHCL(dt []byte, fn string) (*Config, error) {
|
||||
// Decode user defined functions.
|
||||
file, diags := hclsyntax.ParseConfig(dt, fn, hcl.Pos{Line: 1, Column: 1})
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
userFunctions, _, diags := userfunc.DecodeUserFunctions(file.Body, "function", func() *hcl.EvalContext {
|
||||
return &hcl.EvalContext{
|
||||
Functions: stdlibFunctions,
|
||||
}
|
||||
})
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
var sc staticConfig
|
||||
|
||||
// Decode only variable blocks without interpolation.
|
||||
@@ -78,9 +95,8 @@ func ParseHCL(dt []byte, fn string) (*Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
variables := make(map[string]cty.Value)
|
||||
|
||||
// Set all variables to their default value if defined.
|
||||
variables := make(map[string]cty.Value)
|
||||
for _, variable := range sc.Variables {
|
||||
variables[variable.Name] = cty.StringVal(variable.Default)
|
||||
}
|
||||
@@ -94,6 +110,14 @@ func ParseHCL(dt []byte, fn string) (*Config, error) {
|
||||
}
|
||||
}
|
||||
|
||||
functions := make(map[string]function.Function)
|
||||
for k, v := range stdlibFunctions {
|
||||
functions[k] = v
|
||||
}
|
||||
for k, v := range userFunctions {
|
||||
functions[k] = v
|
||||
}
|
||||
|
||||
ctx := &hcl.EvalContext{
|
||||
Variables: variables,
|
||||
Functions: functions,
|
||||
|
@@ -93,6 +93,36 @@ func TestParseHCL(t *testing.T) {
|
||||
require.Equal(t, "124", c.Targets[0].Args["buildno"])
|
||||
})
|
||||
|
||||
t.Run("WithUserDefinedFunctions", func(t *testing.T) {
|
||||
dt := []byte(`
|
||||
function "increment" {
|
||||
params = [number]
|
||||
result = number + 1
|
||||
}
|
||||
|
||||
group "default" {
|
||||
targets = ["webapp"]
|
||||
}
|
||||
|
||||
target "webapp" {
|
||||
args = {
|
||||
buildno = "${increment(123)}"
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
c, err := ParseHCL(dt, "docker-bake.hcl")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(c.Groups))
|
||||
require.Equal(t, "default", c.Groups[0].Name)
|
||||
require.Equal(t, []string{"webapp"}, c.Groups[0].Targets)
|
||||
|
||||
require.Equal(t, 1, len(c.Targets))
|
||||
require.Equal(t, c.Targets[0].Name, "webapp")
|
||||
require.Equal(t, "124", c.Targets[0].Args["buildno"])
|
||||
})
|
||||
|
||||
t.Run("WithVariables", func(t *testing.T) {
|
||||
dt := []byte(`
|
||||
variable "BUILD_NUMBER" {
|
||||
|
Reference in New Issue
Block a user