mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			418 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			418 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package bake
 | 
						|
 | 
						|
import (
 | 
						|
	"os"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/require"
 | 
						|
)
 | 
						|
 | 
						|
func TestHCLBasic(t *testing.T) {
 | 
						|
	t.Parallel()
 | 
						|
	dt := []byte(`
 | 
						|
		group "default" {
 | 
						|
			targets = ["db", "webapp"]
 | 
						|
		}
 | 
						|
 | 
						|
		target "db" {
 | 
						|
			context = "./db"
 | 
						|
			tags = ["docker.io/tonistiigi/db"]
 | 
						|
		}
 | 
						|
 | 
						|
		target "webapp" {
 | 
						|
			context = "./dir"
 | 
						|
			dockerfile = "Dockerfile-alternate"
 | 
						|
			args = {
 | 
						|
				buildno = "123"
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		target "cross" {
 | 
						|
			platforms = [
 | 
						|
				"linux/amd64",
 | 
						|
				"linux/arm64"
 | 
						|
			]
 | 
						|
		}
 | 
						|
 | 
						|
		target "webapp-plus" {
 | 
						|
			inherits = ["webapp", "cross"]
 | 
						|
			args = {
 | 
						|
				IAMCROSS = "true"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := ParseFile(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{"db", "webapp"}, c.Groups[0].Targets)
 | 
						|
 | 
						|
	require.Equal(t, 4, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "db")
 | 
						|
	require.Equal(t, "./db", *c.Targets[0].Context)
 | 
						|
 | 
						|
	require.Equal(t, c.Targets[1].Name, "webapp")
 | 
						|
	require.Equal(t, 1, len(c.Targets[1].Args))
 | 
						|
	require.Equal(t, "123", c.Targets[1].Args["buildno"])
 | 
						|
 | 
						|
	require.Equal(t, c.Targets[2].Name, "cross")
 | 
						|
	require.Equal(t, 2, len(c.Targets[2].Platforms))
 | 
						|
	require.Equal(t, []string{"linux/amd64", "linux/arm64"}, c.Targets[2].Platforms)
 | 
						|
 | 
						|
	require.Equal(t, c.Targets[3].Name, "webapp-plus")
 | 
						|
	require.Equal(t, 1, len(c.Targets[3].Args))
 | 
						|
	require.Equal(t, map[string]string{"IAMCROSS": "true"}, c.Targets[3].Args)
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLBasicInJSON(t *testing.T) {
 | 
						|
	dt := []byte(`
 | 
						|
		{
 | 
						|
			"group": {
 | 
						|
				"default": {
 | 
						|
					"targets": ["db", "webapp"]
 | 
						|
				}
 | 
						|
			},
 | 
						|
			"target": {
 | 
						|
				"db": {
 | 
						|
					"context": "./db",
 | 
						|
					"tags": ["docker.io/tonistiigi/db"]
 | 
						|
				},
 | 
						|
				"webapp": {
 | 
						|
					"context": "./dir",
 | 
						|
					"dockerfile": "Dockerfile-alternate",
 | 
						|
					"args": {
 | 
						|
						"buildno": "123"
 | 
						|
					}
 | 
						|
				},
 | 
						|
				"cross": {
 | 
						|
					"platforms": [
 | 
						|
						"linux/amd64",
 | 
						|
						"linux/arm64"
 | 
						|
					]
 | 
						|
				},
 | 
						|
				"webapp-plus": {
 | 
						|
					"inherits": ["webapp", "cross"],
 | 
						|
					"args": {
 | 
						|
						"IAMCROSS": "true"
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := ParseFile(dt, "docker-bake.json")
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 1, len(c.Groups))
 | 
						|
	require.Equal(t, "default", c.Groups[0].Name)
 | 
						|
	require.Equal(t, []string{"db", "webapp"}, c.Groups[0].Targets)
 | 
						|
 | 
						|
	require.Equal(t, 4, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "db")
 | 
						|
	require.Equal(t, "./db", *c.Targets[0].Context)
 | 
						|
 | 
						|
	require.Equal(t, c.Targets[1].Name, "webapp")
 | 
						|
	require.Equal(t, 1, len(c.Targets[1].Args))
 | 
						|
	require.Equal(t, "123", c.Targets[1].Args["buildno"])
 | 
						|
 | 
						|
	require.Equal(t, c.Targets[2].Name, "cross")
 | 
						|
	require.Equal(t, 2, len(c.Targets[2].Platforms))
 | 
						|
	require.Equal(t, []string{"linux/amd64", "linux/arm64"}, c.Targets[2].Platforms)
 | 
						|
 | 
						|
	require.Equal(t, c.Targets[3].Name, "webapp-plus")
 | 
						|
	require.Equal(t, 1, len(c.Targets[3].Args))
 | 
						|
	require.Equal(t, map[string]string{"IAMCROSS": "true"}, c.Targets[3].Args)
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLWithFunctions(t *testing.T) {
 | 
						|
	dt := []byte(`
 | 
						|
		group "default" {
 | 
						|
			targets = ["webapp"]
 | 
						|
		}
 | 
						|
 | 
						|
		target "webapp" {
 | 
						|
			args = {
 | 
						|
				buildno = "${add(123, 1)}"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := ParseFile(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"])
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLWithUserDefinedFunctions(t *testing.T) {
 | 
						|
	dt := []byte(`
 | 
						|
		function "increment" {
 | 
						|
			params = [number]
 | 
						|
			result = number + 1
 | 
						|
		}
 | 
						|
 | 
						|
		group "default" {
 | 
						|
			targets = ["webapp"]
 | 
						|
		}
 | 
						|
 | 
						|
		target "webapp" {
 | 
						|
			args = {
 | 
						|
				buildno = "${increment(123)}"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := ParseFile(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"])
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLWithVariables(t *testing.T) {
 | 
						|
	dt := []byte(`
 | 
						|
		variable "BUILD_NUMBER" {
 | 
						|
			default = "123"
 | 
						|
		}
 | 
						|
 | 
						|
		group "default" {
 | 
						|
			targets = ["webapp"]
 | 
						|
		}
 | 
						|
 | 
						|
		target "webapp" {
 | 
						|
			args = {
 | 
						|
				buildno = "${BUILD_NUMBER}"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := ParseFile(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, "123", c.Targets[0].Args["buildno"])
 | 
						|
 | 
						|
	os.Setenv("BUILD_NUMBER", "456")
 | 
						|
 | 
						|
	c, err = ParseFile(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, "456", c.Targets[0].Args["buildno"])
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLWithVariablesInFunctions(t *testing.T) {
 | 
						|
	dt := []byte(`
 | 
						|
		variable "REPO" {
 | 
						|
			default = "user/repo"
 | 
						|
		}
 | 
						|
		function "tag" {
 | 
						|
			params = [tag]
 | 
						|
			result = ["${REPO}:${tag}"]
 | 
						|
		}
 | 
						|
 | 
						|
		target "webapp" {
 | 
						|
			tags = tag("v1")
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := ParseFile(dt, "docker-bake.hcl")
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "webapp")
 | 
						|
	require.Equal(t, []string{"user/repo:v1"}, c.Targets[0].Tags)
 | 
						|
 | 
						|
	os.Setenv("REPO", "docker/buildx")
 | 
						|
 | 
						|
	c, err = ParseFile(dt, "docker-bake.hcl")
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "webapp")
 | 
						|
	require.Equal(t, []string{"docker/buildx:v1"}, c.Targets[0].Tags)
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLMultiFileSharedVariables(t *testing.T) {
 | 
						|
	dt := []byte(`
 | 
						|
		variable "FOO" {
 | 
						|
			default = "abc"
 | 
						|
		}
 | 
						|
		target "app" {
 | 
						|
			args = {
 | 
						|
				v1 = "pre-${FOO}"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
	dt2 := []byte(`
 | 
						|
		target "app" {
 | 
						|
			args = {
 | 
						|
				v2 = "${FOO}-post"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := parseFiles([]File{
 | 
						|
		{Data: dt, Name: "c1.hcl"},
 | 
						|
		{Data: dt2, Name: "c2.hcl"},
 | 
						|
	})
 | 
						|
	require.NoError(t, err)
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "app")
 | 
						|
	require.Equal(t, "pre-abc", c.Targets[0].Args["v1"])
 | 
						|
	require.Equal(t, "abc-post", c.Targets[0].Args["v2"])
 | 
						|
 | 
						|
	os.Setenv("FOO", "def")
 | 
						|
 | 
						|
	c, err = parseFiles([]File{
 | 
						|
		{Data: dt, Name: "c1.hcl"},
 | 
						|
		{Data: dt2, Name: "c2.hcl"},
 | 
						|
	})
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "app")
 | 
						|
	require.Equal(t, "pre-def", c.Targets[0].Args["v1"])
 | 
						|
	require.Equal(t, "def-post", c.Targets[0].Args["v2"])
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLVarsWithVars(t *testing.T) {
 | 
						|
	os.Unsetenv("FOO")
 | 
						|
	dt := []byte(`
 | 
						|
		variable "FOO" {
 | 
						|
			default = upper("${BASE}def")
 | 
						|
		}
 | 
						|
		variable "BAR" {
 | 
						|
			default = "-${FOO}-"
 | 
						|
		}
 | 
						|
		target "app" {
 | 
						|
			args = {
 | 
						|
				v1 = "pre-${BAR}"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
	dt2 := []byte(`
 | 
						|
		variable "BASE" {
 | 
						|
			default = "abc"
 | 
						|
		}
 | 
						|
		target "app" {
 | 
						|
			args = {
 | 
						|
				v2 = "${FOO}-post"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := parseFiles([]File{
 | 
						|
		{Data: dt, Name: "c1.hcl"},
 | 
						|
		{Data: dt2, Name: "c2.hcl"},
 | 
						|
	})
 | 
						|
	require.NoError(t, err)
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "app")
 | 
						|
	require.Equal(t, "pre--ABCDEF-", c.Targets[0].Args["v1"])
 | 
						|
	require.Equal(t, "ABCDEF-post", c.Targets[0].Args["v2"])
 | 
						|
 | 
						|
	os.Setenv("BASE", "new")
 | 
						|
 | 
						|
	c, err = parseFiles([]File{
 | 
						|
		{Data: dt, Name: "c1.hcl"},
 | 
						|
		{Data: dt2, Name: "c2.hcl"},
 | 
						|
	})
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "app")
 | 
						|
	require.Equal(t, "pre--NEWDEF-", c.Targets[0].Args["v1"])
 | 
						|
	require.Equal(t, "NEWDEF-post", c.Targets[0].Args["v2"])
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLTypedVariables(t *testing.T) {
 | 
						|
	os.Unsetenv("FOO")
 | 
						|
	dt := []byte(`
 | 
						|
		variable "FOO" {
 | 
						|
			default = 3
 | 
						|
		}
 | 
						|
		variable "IS_FOO" {
 | 
						|
			default = true
 | 
						|
		}
 | 
						|
		target "app" {
 | 
						|
			args = {
 | 
						|
				v1 = FOO > 5 ? "higher" : "lower" 
 | 
						|
				v2 = IS_FOO ? "yes" : "no"
 | 
						|
			}
 | 
						|
		}
 | 
						|
		`)
 | 
						|
 | 
						|
	c, err := ParseFile(dt, "docker-bake.hcl")
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "app")
 | 
						|
	require.Equal(t, "lower", c.Targets[0].Args["v1"])
 | 
						|
	require.Equal(t, "yes", c.Targets[0].Args["v2"])
 | 
						|
 | 
						|
	os.Setenv("FOO", "5.1")
 | 
						|
	os.Setenv("IS_FOO", "0")
 | 
						|
 | 
						|
	c, err = ParseFile(dt, "docker-bake.hcl")
 | 
						|
	require.NoError(t, err)
 | 
						|
 | 
						|
	require.Equal(t, 1, len(c.Targets))
 | 
						|
	require.Equal(t, c.Targets[0].Name, "app")
 | 
						|
	require.Equal(t, "higher", c.Targets[0].Args["v1"])
 | 
						|
	require.Equal(t, "no", c.Targets[0].Args["v2"])
 | 
						|
 | 
						|
	os.Setenv("FOO", "NaN")
 | 
						|
	_, err = ParseFile(dt, "docker-bake.hcl")
 | 
						|
	require.Error(t, err)
 | 
						|
	require.Contains(t, err.Error(), "failed to parse FOO as number")
 | 
						|
 | 
						|
	os.Setenv("FOO", "0")
 | 
						|
	os.Setenv("IS_FOO", "maybe")
 | 
						|
 | 
						|
	_, err = ParseFile(dt, "docker-bake.hcl")
 | 
						|
	require.Error(t, err)
 | 
						|
	require.Contains(t, err.Error(), "failed to parse IS_FOO as bool")
 | 
						|
}
 | 
						|
 | 
						|
func TestHCLVariableCycle(t *testing.T) {
 | 
						|
	dt := []byte(`
 | 
						|
		variable "FOO" {
 | 
						|
			default = BAR
 | 
						|
		}
 | 
						|
		variable "FOO2" {
 | 
						|
			default = FOO
 | 
						|
		}
 | 
						|
		variable "BAR" {
 | 
						|
			default = FOO
 | 
						|
		}
 | 
						|
		target "app" {}
 | 
						|
		`)
 | 
						|
 | 
						|
	_, err := ParseFile(dt, "docker-bake.hcl")
 | 
						|
	require.Error(t, err)
 | 
						|
	require.Contains(t, err.Error(), "variable cycle not allowed")
 | 
						|
}
 |