mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-31 23:58:03 +08:00
Modify parsing functions and config structs to accept hcl changes
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
This commit is contained in:
184
bake/bake.go
184
bake/bake.go
@@ -15,7 +15,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func ReadTargets(ctx context.Context, files, targets, overrides []string) (map[string]Target, error) {
|
||||
func ReadTargets(ctx context.Context, files, targets, overrides []string) (map[string]*Target, error) {
|
||||
var c Config
|
||||
for _, f := range files {
|
||||
cfg, err := ParseFile(f)
|
||||
@@ -28,7 +28,7 @@ func ReadTargets(ctx context.Context, files, targets, overrides []string) (map[s
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := map[string]Target{}
|
||||
m := map[string]*Target{}
|
||||
for _, n := range targets {
|
||||
for _, n := range c.ResolveGroup(n) {
|
||||
t, err := c.ResolveTarget(n, o)
|
||||
@@ -36,7 +36,7 @@ func ReadTargets(ctx context.Context, files, targets, overrides []string) (map[s
|
||||
return nil, err
|
||||
}
|
||||
if t != nil {
|
||||
m[n] = *t
|
||||
m[n] = t
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,12 +55,12 @@ func ParseFile(fn string) (*Config, error) {
|
||||
}
|
||||
|
||||
if strings.HasSuffix(fnl, ".json") || strings.HasSuffix(fnl, ".hcl") {
|
||||
return ParseHCL(dt)
|
||||
return ParseHCL(dt, fn)
|
||||
}
|
||||
|
||||
cfg, err := ParseCompose(dt)
|
||||
if err != nil {
|
||||
cfg, err2 := ParseHCL(dt)
|
||||
cfg, err2 := ParseHCL(dt, fn)
|
||||
if err2 != nil {
|
||||
return nil, errors.Errorf("failed to parse %s: parsing yaml: %s, parsing hcl: %s", fn, err.Error(), err2.Error())
|
||||
}
|
||||
@@ -70,55 +70,76 @@ func ParseFile(fn string) (*Config, error) {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Group map[string]Group
|
||||
Target map[string]Target
|
||||
Groups []*Group `hcl:"group,block"`
|
||||
Targets []*Target `hcl:"target,block"`
|
||||
}
|
||||
|
||||
func mergeConfig(c1, c2 Config) Config {
|
||||
for k, g := range c2.Group {
|
||||
if c1.Group == nil {
|
||||
c1.Group = map[string]Group{}
|
||||
}
|
||||
if g1, exists := c1.Group[k]; exists {
|
||||
nextTarget:
|
||||
for _, t := range g.Targets {
|
||||
for _, t2 := range g1.Targets {
|
||||
if t == t2 {
|
||||
continue nextTarget
|
||||
}
|
||||
}
|
||||
g1.Targets = append(g1.Targets, t)
|
||||
}
|
||||
c1.Group[k] = g1
|
||||
} else {
|
||||
c1.Group[k] = g
|
||||
}
|
||||
if c1.Groups == nil {
|
||||
c1.Groups = []*Group{}
|
||||
}
|
||||
|
||||
for k, t := range c2.Target {
|
||||
if c1.Target == nil {
|
||||
c1.Target = map[string]Target{}
|
||||
for _, g2 := range c2.Groups {
|
||||
var g1 *Group
|
||||
for _, g := range c1.Groups {
|
||||
if g2.Name == g.Name {
|
||||
g1 = g
|
||||
break
|
||||
}
|
||||
}
|
||||
if base, ok := c1.Target[k]; ok {
|
||||
t = merge(base, t)
|
||||
if g1 == nil {
|
||||
c1.Groups = append(c1.Groups, g2)
|
||||
continue
|
||||
}
|
||||
c1.Target[k] = t
|
||||
|
||||
nextTarget:
|
||||
for _, t2 := range g2.Targets {
|
||||
for _, t1 := range g1.Targets {
|
||||
if t1 == t2 {
|
||||
continue nextTarget
|
||||
}
|
||||
}
|
||||
g1.Targets = append(g1.Targets, t2)
|
||||
}
|
||||
c1.Groups = append(c1.Groups, g1)
|
||||
}
|
||||
|
||||
if c1.Targets == nil {
|
||||
c1.Targets = []*Target{}
|
||||
}
|
||||
|
||||
for _, t2 := range c2.Targets {
|
||||
var t1 *Target
|
||||
for _, t := range c1.Targets {
|
||||
if t2.Name == t.Name {
|
||||
t1 = t
|
||||
break
|
||||
}
|
||||
}
|
||||
if t1 != nil {
|
||||
t2 = merge(t1, t2)
|
||||
}
|
||||
c1.Targets = append(c1.Targets, t2)
|
||||
}
|
||||
|
||||
return c1
|
||||
}
|
||||
|
||||
func (c Config) expandTargets(pattern string) ([]string, error) {
|
||||
if _, ok := c.Target[pattern]; ok {
|
||||
return []string{pattern}, nil
|
||||
for _, target := range c.Targets {
|
||||
if target.Name == pattern {
|
||||
return []string{pattern}, nil
|
||||
}
|
||||
}
|
||||
|
||||
var names []string
|
||||
for name := range c.Target {
|
||||
ok, err := path.Match(pattern, name)
|
||||
for _, target := range c.Targets {
|
||||
ok, err := path.Match(pattern, target.Name)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not match targets with '%s'", pattern)
|
||||
}
|
||||
if ok {
|
||||
names = append(names, name)
|
||||
names = append(names, target.Name)
|
||||
}
|
||||
}
|
||||
if len(names) == 0 {
|
||||
@@ -127,8 +148,8 @@ func (c Config) expandTargets(pattern string) ([]string, error) {
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func (c Config) newOverrides(v []string) (map[string]Target, error) {
|
||||
m := map[string]Target{}
|
||||
func (c Config) newOverrides(v []string) (map[string]*Target, error) {
|
||||
m := map[string]*Target{}
|
||||
for _, v := range v {
|
||||
|
||||
parts := strings.SplitN(v, "=", 2)
|
||||
@@ -148,7 +169,10 @@ func (c Config) newOverrides(v []string) (map[string]Target, error) {
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
t := m[name]
|
||||
t, ok := m[name]
|
||||
if !ok {
|
||||
t = &Target{}
|
||||
}
|
||||
|
||||
switch keys[1] {
|
||||
case "context":
|
||||
@@ -224,8 +248,14 @@ func (c Config) group(name string, visited map[string]struct{}) []string {
|
||||
if _, ok := visited[name]; ok {
|
||||
return nil
|
||||
}
|
||||
g, ok := c.Group[name]
|
||||
if !ok {
|
||||
var g *Group
|
||||
for _, group := range c.Groups {
|
||||
if group.Name == name {
|
||||
g = group
|
||||
break
|
||||
}
|
||||
}
|
||||
if g == nil {
|
||||
return []string{name}
|
||||
}
|
||||
visited[name] = struct{}{}
|
||||
@@ -236,7 +266,7 @@ func (c Config) group(name string, visited map[string]struct{}) []string {
|
||||
return targets
|
||||
}
|
||||
|
||||
func (c Config) ResolveTarget(name string, overrides map[string]Target) (*Target, error) {
|
||||
func (c Config) ResolveTarget(name string, overrides map[string]*Target) (*Target, error) {
|
||||
t, err := c.target(name, map[string]struct{}{}, overrides)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -252,54 +282,66 @@ func (c Config) ResolveTarget(name string, overrides map[string]Target) (*Target
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (c Config) target(name string, visited map[string]struct{}, overrides map[string]Target) (*Target, error) {
|
||||
func (c Config) target(name string, visited map[string]struct{}, overrides map[string]*Target) (*Target, error) {
|
||||
if _, ok := visited[name]; ok {
|
||||
return nil, nil
|
||||
}
|
||||
visited[name] = struct{}{}
|
||||
t, ok := c.Target[name]
|
||||
if !ok {
|
||||
var t *Target
|
||||
for _, target := range c.Targets {
|
||||
if target.Name == name {
|
||||
t = target
|
||||
break
|
||||
}
|
||||
}
|
||||
if t == nil {
|
||||
return nil, errors.Errorf("failed to find target %s", name)
|
||||
}
|
||||
var tt Target
|
||||
tt := &Target{}
|
||||
for _, name := range t.Inherits {
|
||||
t, err := c.target(name, visited, overrides)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t != nil {
|
||||
tt = merge(tt, *t)
|
||||
tt = merge(tt, t)
|
||||
}
|
||||
}
|
||||
t.Inherits = nil
|
||||
tt = merge(merge(merge(defaultTarget(), tt), t), overrides[name])
|
||||
tt = merge(merge(defaultTarget(), tt), t)
|
||||
if override, ok := overrides[name]; ok {
|
||||
tt = merge(tt, override)
|
||||
}
|
||||
tt.normalize()
|
||||
return &tt, nil
|
||||
return tt, nil
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Targets []string
|
||||
Name string `json:"-" hcl:"name,label"`
|
||||
Targets []string `json:"targets" hcl:"targets"`
|
||||
// Target // TODO?
|
||||
}
|
||||
|
||||
type Target struct {
|
||||
// Inherits is the only field that cannot be overridden with --set
|
||||
Inherits []string `json:"inherits,omitempty" hcl:"inherits,omitempty"`
|
||||
Name string `json:"-" hcl:"name,label"`
|
||||
|
||||
Context *string `json:"context,omitempty" hcl:"context,omitempty"`
|
||||
Dockerfile *string `json:"dockerfile,omitempty" hcl:"dockerfile,omitempty"`
|
||||
Args map[string]string `json:"args,omitempty" hcl:"args,omitempty"`
|
||||
Labels map[string]string `json:"labels,omitempty" hcl:"labels,omitempty"`
|
||||
Tags []string `json:"tags,omitempty" hcl:"tags,omitempty"`
|
||||
CacheFrom []string `json:"cache-from,omitempty" hcl:"cache-from,omitempty"`
|
||||
CacheTo []string `json:"cache-to,omitempty" hcl:"cache-to,omitempty"`
|
||||
Target *string `json:"target,omitempty" hcl:"target,omitempty"`
|
||||
Secrets []string `json:"secret,omitempty" hcl:"secret,omitempty"`
|
||||
SSH []string `json:"ssh,omitempty" hcl:"ssh,omitempty"`
|
||||
Platforms []string `json:"platforms,omitempty" hcl:"platforms,omitempty"`
|
||||
Outputs []string `json:"output,omitempty" hcl:"output,omitempty"`
|
||||
Pull bool `json:"pull,omitempty": hcl:"pull,omitempty"`
|
||||
NoCache bool `json:"no-cache,omitempty": hcl:"no-cache,omitempty"`
|
||||
// Inherits is the only field that cannot be overridden with --set
|
||||
Inherits []string `json:"inherits,omitempty" hcl:"inherits,optional"`
|
||||
|
||||
Context *string `json:"context,omitempty" hcl:"context,optional"`
|
||||
Dockerfile *string `json:"dockerfile,omitempty" hcl:"dockerfile,optional"`
|
||||
Args map[string]string `json:"args,omitempty" hcl:"args,optional"`
|
||||
Labels map[string]string `json:"labels,omitempty" hcl:"labels,optional"`
|
||||
Tags []string `json:"tags,omitempty" hcl:"tags,optional"`
|
||||
CacheFrom []string `json:"cache-from,omitempty" hcl:"cache-from,optional"`
|
||||
CacheTo []string `json:"cache-to,omitempty" hcl:"cache-to,optional"`
|
||||
Target *string `json:"target,omitempty" hcl:"target,optional"`
|
||||
Secrets []string `json:"secret,omitempty" hcl:"secret,optional"`
|
||||
SSH []string `json:"ssh,omitempty" hcl:"ssh,optional"`
|
||||
Platforms []string `json:"platforms,omitempty" hcl:"platforms,optional"`
|
||||
Outputs []string `json:"output,omitempty" hcl:"output,optional"`
|
||||
Pull bool `json:"pull,omitempty": hcl:"pull,optional"`
|
||||
NoCache bool `json:"no-cache,omitempty": hcl:"no-cache,optional"`
|
||||
// IMPORTANT: if you add more fields here, do not forget to update newOverrides and README.
|
||||
}
|
||||
|
||||
@@ -313,7 +355,7 @@ func (t *Target) normalize() {
|
||||
t.Outputs = removeDupes(t.Outputs)
|
||||
}
|
||||
|
||||
func TargetsToBuildOpt(m map[string]Target) (map[string]build.Options, error) {
|
||||
func TargetsToBuildOpt(m map[string]*Target) (map[string]build.Options, error) {
|
||||
m2 := make(map[string]build.Options, len(m))
|
||||
for k, v := range m {
|
||||
bo, err := toBuildOpt(v)
|
||||
@@ -325,7 +367,7 @@ func TargetsToBuildOpt(m map[string]Target) (map[string]build.Options, error) {
|
||||
return m2, nil
|
||||
}
|
||||
|
||||
func toBuildOpt(t Target) (*build.Options, error) {
|
||||
func toBuildOpt(t *Target) (*build.Options, error) {
|
||||
if v := t.Context; v != nil && *v == "-" {
|
||||
return nil, errors.Errorf("context from stdin not allowed in bake")
|
||||
}
|
||||
@@ -403,11 +445,11 @@ func toBuildOpt(t Target) (*build.Options, error) {
|
||||
return bo, nil
|
||||
}
|
||||
|
||||
func defaultTarget() Target {
|
||||
return Target{}
|
||||
func defaultTarget() *Target {
|
||||
return &Target{}
|
||||
}
|
||||
|
||||
func merge(t1, t2 Target) Target {
|
||||
func merge(t1, t2 *Target) *Target {
|
||||
if t2.Context != nil {
|
||||
t1.Context = t2.Context
|
||||
}
|
||||
|
Reference in New Issue
Block a user