mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	Merge pull request #2760 from tonistiigi/update-compose-v2.4.1
vendor: update compose to v2.4.1
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -6,7 +6,7 @@ require (
 | 
				
			|||||||
	github.com/Masterminds/semver/v3 v3.2.1
 | 
						github.com/Masterminds/semver/v3 v3.2.1
 | 
				
			||||||
	github.com/Microsoft/go-winio v0.6.2
 | 
						github.com/Microsoft/go-winio v0.6.2
 | 
				
			||||||
	github.com/aws/aws-sdk-go-v2/config v1.26.6
 | 
						github.com/aws/aws-sdk-go-v2/config v1.26.6
 | 
				
			||||||
	github.com/compose-spec/compose-go/v2 v2.2.0
 | 
						github.com/compose-spec/compose-go/v2 v2.4.1
 | 
				
			||||||
	github.com/containerd/console v1.0.4
 | 
						github.com/containerd/console v1.0.4
 | 
				
			||||||
	github.com/containerd/containerd v1.7.22
 | 
						github.com/containerd/containerd v1.7.22
 | 
				
			||||||
	github.com/containerd/continuity v0.4.4
 | 
						github.com/containerd/continuity v0.4.4
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							@@ -83,8 +83,8 @@ github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnTh
 | 
				
			|||||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
 | 
					github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
 | 
				
			||||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
 | 
					github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
 | 
				
			||||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
 | 
					github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
 | 
				
			||||||
github.com/compose-spec/compose-go/v2 v2.2.0 h1:VsQosGhuO+H9wh5laiIiAe4TVd73kQ5NWwmNrdm0HRA=
 | 
					github.com/compose-spec/compose-go/v2 v2.4.1 h1:tEg6Qn/9LZnKg42fZlFmxN4lxSqnCvsiG5TXnxzvI4c=
 | 
				
			||||||
github.com/compose-spec/compose-go/v2 v2.2.0/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
 | 
					github.com/compose-spec/compose-go/v2 v2.4.1/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
 | 
				
			||||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
 | 
					github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
 | 
				
			||||||
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
 | 
					github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
 | 
				
			||||||
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
 | 
					github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										64
									
								
								vendor/github.com/compose-spec/compose-go/v2/cli/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/compose-spec/compose-go/v2/cli/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -403,22 +403,24 @@ func (o *ProjectOptions) GetWorkingDir() (string, error) {
 | 
				
			|||||||
	return os.Getwd()
 | 
						return os.Getwd()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (o *ProjectOptions) GetConfigFiles() ([]types.ConfigFile, error) {
 | 
					// ReadConfigFiles reads ConfigFiles and populates the content field
 | 
				
			||||||
	configPaths, err := o.getConfigPaths()
 | 
					func (o *ProjectOptions) ReadConfigFiles(ctx context.Context, workingDir string, options *ProjectOptions) (*types.ConfigDetails, error) {
 | 
				
			||||||
 | 
						config, err := loader.LoadConfigFiles(ctx, options.ConfigPaths, workingDir, options.loadOptions...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						configs := make([][]byte, len(config.ConfigFiles))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var configs []types.ConfigFile
 | 
						for i, c := range config.ConfigFiles {
 | 
				
			||||||
	for _, f := range configPaths {
 | 
							var err error
 | 
				
			||||||
		var b []byte
 | 
							var b []byte
 | 
				
			||||||
		if f == "-" {
 | 
							if c.Filename == "-" {
 | 
				
			||||||
			b, err = io.ReadAll(os.Stdin)
 | 
								b, err = io.ReadAll(os.Stdin)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			f, err := filepath.Abs(f)
 | 
								f, err := filepath.Abs(c.Filename)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -427,27 +429,31 @@ func (o *ProjectOptions) GetConfigFiles() ([]types.ConfigFile, error) {
 | 
				
			|||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		configs = append(configs, types.ConfigFile{
 | 
							configs[i] = b
 | 
				
			||||||
			Filename: f,
 | 
					 | 
				
			||||||
			Content:  b,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return configs, err
 | 
						for i, c := range configs {
 | 
				
			||||||
 | 
							config.ConfigFiles[i].Content = c
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return config, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LoadProject loads compose file according to options and bind to types.Project go structs
 | 
					// LoadProject loads compose file according to options and bind to types.Project go structs
 | 
				
			||||||
func (o *ProjectOptions) LoadProject(ctx context.Context) (*types.Project, error) {
 | 
					func (o *ProjectOptions) LoadProject(ctx context.Context) (*types.Project, error) {
 | 
				
			||||||
	configDetails, err := o.prepare()
 | 
						config, err := o.prepare(ctx)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	project, err := loader.LoadWithContext(ctx, configDetails, o.loadOptions...)
 | 
						project, err := loader.LoadWithContext(ctx, types.ConfigDetails{
 | 
				
			||||||
 | 
							ConfigFiles: config.ConfigFiles,
 | 
				
			||||||
 | 
							WorkingDir:  config.WorkingDir,
 | 
				
			||||||
 | 
							Environment: o.Environment,
 | 
				
			||||||
 | 
						}, o.loadOptions...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, config := range configDetails.ConfigFiles {
 | 
						for _, config := range config.ConfigFiles {
 | 
				
			||||||
		project.ComposeFiles = append(project.ComposeFiles, config.Filename)
 | 
							project.ComposeFiles = append(project.ComposeFiles, config.Filename)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -456,36 +462,31 @@ func (o *ProjectOptions) LoadProject(ctx context.Context) (*types.Project, error
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// LoadModel loads compose file according to options and returns a raw (yaml tree) model
 | 
					// LoadModel loads compose file according to options and returns a raw (yaml tree) model
 | 
				
			||||||
func (o *ProjectOptions) LoadModel(ctx context.Context) (map[string]any, error) {
 | 
					func (o *ProjectOptions) LoadModel(ctx context.Context) (map[string]any, error) {
 | 
				
			||||||
	configDetails, err := o.prepare()
 | 
						configDetails, err := o.prepare(ctx)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return loader.LoadModelWithContext(ctx, configDetails, o.loadOptions...)
 | 
						return loader.LoadModelWithContext(ctx, *configDetails, o.loadOptions...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// prepare converts ProjectOptions into loader's types.ConfigDetails and configures default load options
 | 
					// prepare converts ProjectOptions into loader's types.ConfigDetails and configures default load options
 | 
				
			||||||
func (o *ProjectOptions) prepare() (types.ConfigDetails, error) {
 | 
					func (o *ProjectOptions) prepare(ctx context.Context) (*types.ConfigDetails, error) {
 | 
				
			||||||
	configs, err := o.GetConfigFiles()
 | 
						defaultDir, err := o.GetWorkingDir()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return types.ConfigDetails{}, err
 | 
							return &types.ConfigDetails{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	workingDir, err := o.GetWorkingDir()
 | 
						configDetails, err := o.ReadConfigFiles(ctx, defaultDir, o)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return types.ConfigDetails{}, err
 | 
							return configDetails, err
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	configDetails := types.ConfigDetails{
 | 
					 | 
				
			||||||
		ConfigFiles: configs,
 | 
					 | 
				
			||||||
		WorkingDir:  workingDir,
 | 
					 | 
				
			||||||
		Environment: o.Environment,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o.loadOptions = append(o.loadOptions,
 | 
						o.loadOptions = append(o.loadOptions,
 | 
				
			||||||
		withNamePrecedenceLoad(workingDir, o),
 | 
							withNamePrecedenceLoad(defaultDir, o),
 | 
				
			||||||
		withConvertWindowsPaths(o),
 | 
							withConvertWindowsPaths(o),
 | 
				
			||||||
		withListeners(o))
 | 
							withListeners(o))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return configDetails, nil
 | 
						return configDetails, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -502,8 +503,13 @@ func withNamePrecedenceLoad(absWorkingDir string, options *ProjectOptions) func(
 | 
				
			|||||||
		} else if nameFromEnv, ok := options.Environment[consts.ComposeProjectName]; ok && nameFromEnv != "" {
 | 
							} else if nameFromEnv, ok := options.Environment[consts.ComposeProjectName]; ok && nameFromEnv != "" {
 | 
				
			||||||
			opts.SetProjectName(nameFromEnv, true)
 | 
								opts.SetProjectName(nameFromEnv, true)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
 | 
								dirname := filepath.Base(absWorkingDir)
 | 
				
			||||||
 | 
								symlink, err := filepath.EvalSymlinks(absWorkingDir)
 | 
				
			||||||
 | 
								if err == nil && filepath.Base(symlink) != dirname {
 | 
				
			||||||
 | 
									logrus.Warnf("project has been loaded without an explicit name from a symlink. Using name %q", dirname)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			opts.SetProjectName(
 | 
								opts.SetProjectName(
 | 
				
			||||||
				loader.NormalizeProjectName(filepath.Base(absWorkingDir)),
 | 
									loader.NormalizeProjectName(dirname),
 | 
				
			||||||
				false,
 | 
									false,
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								vendor/github.com/compose-spec/compose-go/v2/dotenv/format.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/compose-spec/compose-go/v2/dotenv/format.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					   Copyright 2020 The Compose Specification Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package dotenv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var formats = map[string]Parser{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Parser func(r io.Reader, filename string, lookup func(key string) (string, bool)) (map[string]string, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RegisterFormat(format string, p Parser) {
 | 
				
			||||||
 | 
						formats[format] = p
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ParseWithFormat(r io.Reader, filename string, resolve LookupFn, format string) (map[string]string, error) {
 | 
				
			||||||
 | 
						parser, ok := formats[format]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("unsupported env_file format %q", format)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return parser(r, filename, resolve)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								vendor/github.com/compose-spec/compose-go/v2/dotenv/godotenv.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/compose-spec/compose-go/v2/dotenv/godotenv.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -86,7 +86,7 @@ func ReadWithLookup(lookupFn LookupFn, filenames ...string) (map[string]string,
 | 
				
			|||||||
	envMap := make(map[string]string)
 | 
						envMap := make(map[string]string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, filename := range filenames {
 | 
						for _, filename := range filenames {
 | 
				
			||||||
		individualEnvMap, individualErr := readFile(filename, lookupFn)
 | 
							individualEnvMap, individualErr := ReadFile(filename, lookupFn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if individualErr != nil {
 | 
							if individualErr != nil {
 | 
				
			||||||
			return envMap, individualErr
 | 
								return envMap, individualErr
 | 
				
			||||||
@@ -129,7 +129,7 @@ func filenamesOrDefault(filenames []string) []string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func loadFile(filename string, overload bool) error {
 | 
					func loadFile(filename string, overload bool) error {
 | 
				
			||||||
	envMap, err := readFile(filename, nil)
 | 
						envMap, err := ReadFile(filename, nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -150,7 +150,7 @@ func loadFile(filename string, overload bool) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func readFile(filename string, lookupFn LookupFn) (map[string]string, error) {
 | 
					func ReadFile(filename string, lookupFn LookupFn) (map[string]string, error) {
 | 
				
			||||||
	file, err := os.Open(filename)
 | 
						file, err := os.Open(filename)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								vendor/github.com/compose-spec/compose-go/v2/dotenv/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/compose-spec/compose-go/v2/dotenv/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -119,7 +119,7 @@ loop:
 | 
				
			|||||||
			offset = i + 1
 | 
								offset = i + 1
 | 
				
			||||||
			inherited = rune == '\n'
 | 
								inherited = rune == '\n'
 | 
				
			||||||
			break loop
 | 
								break loop
 | 
				
			||||||
		case '_', '.', '[', ']':
 | 
							case '_', '.', '-', '[', ']':
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			// variable name should match [A-Za-z0-9_.-]
 | 
								// variable name should match [A-Za-z0-9_.-]
 | 
				
			||||||
			if unicode.IsLetter(rune) || unicode.IsNumber(rune) {
 | 
								if unicode.IsLetter(rune) || unicode.IsNumber(rune) {
 | 
				
			||||||
@@ -136,6 +136,10 @@ loop:
 | 
				
			|||||||
		return "", "", inherited, errors.New("zero length string")
 | 
							return "", "", inherited, errors.New("zero length string")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if inherited && strings.IndexByte(key, ' ') == -1 {
 | 
				
			||||||
 | 
							p.line++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// trim whitespace
 | 
						// trim whitespace
 | 
				
			||||||
	key = strings.TrimRightFunc(key, unicode.IsSpace)
 | 
						key = strings.TrimRightFunc(key, unicode.IsSpace)
 | 
				
			||||||
	cutset := strings.TrimLeftFunc(src[offset:], isSpace)
 | 
						cutset := strings.TrimLeftFunc(src[offset:], isSpace)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/github.com/compose-spec/compose-go/v2/format/volume.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/compose-spec/compose-go/v2/format/volume.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -95,7 +95,7 @@ func populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolu
 | 
				
			|||||||
			if isBindOption(option) {
 | 
								if isBindOption(option) {
 | 
				
			||||||
				setBindOption(volume, option)
 | 
									setBindOption(volume, option)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// ignore unknown options
 | 
								// ignore unknown options FIXME why not report an error here?
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										61
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/loader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/loader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -30,6 +30,7 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/compose-spec/compose-go/v2/consts"
 | 
						"github.com/compose-spec/compose-go/v2/consts"
 | 
				
			||||||
 | 
						"github.com/compose-spec/compose-go/v2/errdefs"
 | 
				
			||||||
	interp "github.com/compose-spec/compose-go/v2/interpolation"
 | 
						interp "github.com/compose-spec/compose-go/v2/interpolation"
 | 
				
			||||||
	"github.com/compose-spec/compose-go/v2/override"
 | 
						"github.com/compose-spec/compose-go/v2/override"
 | 
				
			||||||
	"github.com/compose-spec/compose-go/v2/paths"
 | 
						"github.com/compose-spec/compose-go/v2/paths"
 | 
				
			||||||
@@ -139,9 +140,9 @@ func (l localResourceLoader) abs(p string) string {
 | 
				
			|||||||
	return filepath.Join(l.WorkingDir, p)
 | 
						return filepath.Join(l.WorkingDir, p)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l localResourceLoader) Accept(p string) bool {
 | 
					func (l localResourceLoader) Accept(_ string) bool {
 | 
				
			||||||
	_, err := os.Stat(l.abs(p))
 | 
						// LocalResourceLoader is the last loader tested so it always should accept the config and try to get the content.
 | 
				
			||||||
	return err == nil
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l localResourceLoader) Load(_ context.Context, p string) (string, error) {
 | 
					func (l localResourceLoader) Load(_ context.Context, p string) (string, error) {
 | 
				
			||||||
@@ -300,6 +301,51 @@ func parseYAML(decoder *yaml.Decoder) (map[string]interface{}, PostProcessor, er
 | 
				
			|||||||
	return converted.(map[string]interface{}), &processor, nil
 | 
						return converted.(map[string]interface{}), &processor, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LoadConfigFiles ingests config files with ResourceLoader and returns config details with paths to local copies
 | 
				
			||||||
 | 
					func LoadConfigFiles(ctx context.Context, configFiles []string, workingDir string, options ...func(*Options)) (*types.ConfigDetails, error) {
 | 
				
			||||||
 | 
						if len(configFiles) < 1 {
 | 
				
			||||||
 | 
							return &types.ConfigDetails{}, fmt.Errorf("no configuration file provided: %w", errdefs.ErrNotFound)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts := &Options{}
 | 
				
			||||||
 | 
						config := &types.ConfigDetails{
 | 
				
			||||||
 | 
							ConfigFiles: make([]types.ConfigFile, len(configFiles)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, op := range options {
 | 
				
			||||||
 | 
							op(opts)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opts.ResourceLoaders = append(opts.ResourceLoaders, localResourceLoader{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, p := range configFiles {
 | 
				
			||||||
 | 
							for _, loader := range opts.ResourceLoaders {
 | 
				
			||||||
 | 
								_, isLocalResourceLoader := loader.(localResourceLoader)
 | 
				
			||||||
 | 
								if !loader.Accept(p) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								local, err := loader.Load(ctx, p)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if config.WorkingDir == "" && !isLocalResourceLoader {
 | 
				
			||||||
 | 
									config.WorkingDir = filepath.Dir(local)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								abs, err := filepath.Abs(local)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									abs = local
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								config.ConfigFiles[i] = types.ConfigFile{
 | 
				
			||||||
 | 
									Filename: abs,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if config.WorkingDir == "" {
 | 
				
			||||||
 | 
							config.WorkingDir = workingDir
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return config, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Load reads a ConfigDetails and returns a fully loaded configuration.
 | 
					// Load reads a ConfigDetails and returns a fully loaded configuration.
 | 
				
			||||||
// Deprecated: use LoadWithContext.
 | 
					// Deprecated: use LoadWithContext.
 | 
				
			||||||
func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.Project, error) {
 | 
					func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.Project, error) {
 | 
				
			||||||
@@ -470,6 +516,8 @@ func loadYamlFile(ctx context.Context, file types.ConfigFile, opts *Options, wor
 | 
				
			|||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dict = OmitEmpty(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Canonical transformation can reveal duplicates, typically as ports can be a range and conflict with an override
 | 
							// Canonical transformation can reveal duplicates, typically as ports can be a range and conflict with an override
 | 
				
			||||||
		dict, err = override.EnforceUnicity(dict)
 | 
							dict, err = override.EnforceUnicity(dict)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -675,6 +723,7 @@ func NormalizeProjectName(s string) string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var userDefinedKeys = []tree.Path{
 | 
					var userDefinedKeys = []tree.Path{
 | 
				
			||||||
	"services",
 | 
						"services",
 | 
				
			||||||
 | 
						"services.*.depends_on",
 | 
				
			||||||
	"volumes",
 | 
						"volumes",
 | 
				
			||||||
	"networks",
 | 
						"networks",
 | 
				
			||||||
	"secrets",
 | 
						"secrets",
 | 
				
			||||||
@@ -687,7 +736,7 @@ func processExtensions(dict map[string]any, p tree.Path, extensions map[string]a
 | 
				
			|||||||
	for key, value := range dict {
 | 
						for key, value := range dict {
 | 
				
			||||||
		skip := false
 | 
							skip := false
 | 
				
			||||||
		for _, uk := range userDefinedKeys {
 | 
							for _, uk := range userDefinedKeys {
 | 
				
			||||||
			if uk.Matches(p) {
 | 
								if p.Matches(uk) {
 | 
				
			||||||
				skip = true
 | 
									skip = true
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -770,14 +819,14 @@ func secretConfigDecoderHook(from, to reflect.Type, data interface{}) (interface
 | 
				
			|||||||
	// Check if the input is a map and we're decoding into a SecretConfig
 | 
						// Check if the input is a map and we're decoding into a SecretConfig
 | 
				
			||||||
	if from.Kind() == reflect.Map && to == reflect.TypeOf(types.SecretConfig{}) {
 | 
						if from.Kind() == reflect.Map && to == reflect.TypeOf(types.SecretConfig{}) {
 | 
				
			||||||
		if v, ok := data.(map[string]interface{}); ok {
 | 
							if v, ok := data.(map[string]interface{}); ok {
 | 
				
			||||||
			if ext, ok := v["#extensions"].(map[string]interface{}); ok {
 | 
								if ext, ok := v[consts.Extensions].(map[string]interface{}); ok {
 | 
				
			||||||
				if val, ok := ext[types.SecretConfigXValue].(string); ok {
 | 
									if val, ok := ext[types.SecretConfigXValue].(string); ok {
 | 
				
			||||||
					// Return a map with the Content field populated
 | 
										// Return a map with the Content field populated
 | 
				
			||||||
					v["Content"] = val
 | 
										v["Content"] = val
 | 
				
			||||||
					delete(ext, types.SecretConfigXValue)
 | 
										delete(ext, types.SecretConfigXValue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if len(ext) == 0 {
 | 
										if len(ext) == 0 {
 | 
				
			||||||
						delete(v, "#extensions")
 | 
											delete(v, consts.Extensions)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/normalize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/normalize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,6 +18,7 @@ package loader
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -102,6 +103,17 @@ func Normalize(dict map[string]any, env types.Mapping) (map[string]any, error) {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if v, ok := service["volumes"]; ok {
 | 
				
			||||||
 | 
									volumes := v.([]any)
 | 
				
			||||||
 | 
									for i, volume := range volumes {
 | 
				
			||||||
 | 
										vol := volume.(map[string]any)
 | 
				
			||||||
 | 
										target := vol["target"].(string)
 | 
				
			||||||
 | 
										vol["target"] = path.Clean(target)
 | 
				
			||||||
 | 
										volumes[i] = vol
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									service["volumes"] = volumes
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if n, ok := service["volumes_from"]; ok {
 | 
								if n, ok := service["volumes_from"]; ok {
 | 
				
			||||||
				volumesFrom := n.([]any)
 | 
									volumesFrom := n.([]any)
 | 
				
			||||||
				for _, v := range volumesFrom {
 | 
									for _, v := range volumesFrom {
 | 
				
			||||||
@@ -123,9 +135,9 @@ func Normalize(dict map[string]any, env types.Mapping) (map[string]any, error) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			services[name] = service
 | 
								services[name] = service
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dict["services"] = services
 | 
							dict["services"] = services
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	setNameFromKey(dict)
 | 
						setNameFromKey(dict)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return dict, nil
 | 
						return dict, nil
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										74
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/omitEmpty.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/omitEmpty.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					   Copyright 2020 The Compose Specification Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package loader
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "github.com/compose-spec/compose-go/v2/tree"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var omitempty = []tree.Path{
 | 
				
			||||||
 | 
						"services.*.dns"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OmitEmpty removes empty attributes which are irrelevant when unset
 | 
				
			||||||
 | 
					func OmitEmpty(yaml map[string]any) map[string]any {
 | 
				
			||||||
 | 
						cleaned := omitEmpty(yaml, tree.NewPath())
 | 
				
			||||||
 | 
						return cleaned.(map[string]any)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func omitEmpty(data any, p tree.Path) any {
 | 
				
			||||||
 | 
						switch v := data.(type) {
 | 
				
			||||||
 | 
						case map[string]any:
 | 
				
			||||||
 | 
							for k, e := range v {
 | 
				
			||||||
 | 
								if isEmpty(e) && mustOmit(p) {
 | 
				
			||||||
 | 
									delete(v, k)
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								v[k] = omitEmpty(e, p.Next(k))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return v
 | 
				
			||||||
 | 
						case []any:
 | 
				
			||||||
 | 
							var c []any
 | 
				
			||||||
 | 
							for _, e := range v {
 | 
				
			||||||
 | 
								if isEmpty(e) && mustOmit(p) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								c = append(c, omitEmpty(e, p.Next("[]")))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return c
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return data
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func mustOmit(p tree.Path) bool {
 | 
				
			||||||
 | 
						for _, pattern := range omitempty {
 | 
				
			||||||
 | 
							if p.Matches(pattern) {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func isEmpty(e any) bool {
 | 
				
			||||||
 | 
						if e == nil {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if v, ok := e.(string); ok && v == "" {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										28
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/reset.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/compose-spec/compose-go/v2/loader/reset.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -26,13 +26,15 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ResetProcessor struct {
 | 
					type ResetProcessor struct {
 | 
				
			||||||
	target interface{}
 | 
						target       interface{}
 | 
				
			||||||
	paths  []tree.Path
 | 
						paths        []tree.Path
 | 
				
			||||||
 | 
						visitedNodes map[*yaml.Node]string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UnmarshalYAML implement yaml.Unmarshaler
 | 
					// UnmarshalYAML implement yaml.Unmarshaler
 | 
				
			||||||
func (p *ResetProcessor) UnmarshalYAML(value *yaml.Node) error {
 | 
					func (p *ResetProcessor) UnmarshalYAML(value *yaml.Node) error {
 | 
				
			||||||
	resolved, err := p.resolveReset(value, tree.NewPath())
 | 
						resolved, err := p.resolveReset(value, tree.NewPath())
 | 
				
			||||||
 | 
						p.visitedNodes = nil
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -41,10 +43,28 @@ func (p *ResetProcessor) UnmarshalYAML(value *yaml.Node) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// resolveReset detects `!reset` tag being set on yaml nodes and record position in the yaml tree
 | 
					// resolveReset detects `!reset` tag being set on yaml nodes and record position in the yaml tree
 | 
				
			||||||
func (p *ResetProcessor) resolveReset(node *yaml.Node, path tree.Path) (*yaml.Node, error) {
 | 
					func (p *ResetProcessor) resolveReset(node *yaml.Node, path tree.Path) (*yaml.Node, error) {
 | 
				
			||||||
 | 
						pathStr := path.String()
 | 
				
			||||||
	// If the path contains "<<", removing the "<<" element and merging the path
 | 
						// If the path contains "<<", removing the "<<" element and merging the path
 | 
				
			||||||
	if strings.Contains(path.String(), ".<<") {
 | 
						if strings.Contains(pathStr, ".<<") {
 | 
				
			||||||
		path = tree.NewPath(strings.Replace(path.String(), ".<<", "", 1))
 | 
							path = tree.NewPath(strings.Replace(pathStr, ".<<", "", 1))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for cycle
 | 
				
			||||||
 | 
						if p.visitedNodes == nil {
 | 
				
			||||||
 | 
							p.visitedNodes = make(map[*yaml.Node]string)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for cycle by seeing if the node has already been visited at this path
 | 
				
			||||||
 | 
						if previousPath, found := p.visitedNodes[node]; found {
 | 
				
			||||||
 | 
							// If the current node has been visited, we have a cycle if the previous path is a prefix
 | 
				
			||||||
 | 
							if strings.HasPrefix(pathStr, previousPath) {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("cycle detected at path: %s", pathStr)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Mark the current node as visited
 | 
				
			||||||
 | 
						p.visitedNodes[node] = pathStr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If the node is an alias, We need to process the alias field in order to consider the !override and !reset tags
 | 
						// If the node is an alias, We need to process the alias field in order to consider the !override and !reset tags
 | 
				
			||||||
	if node.Kind == yaml.AliasNode {
 | 
						if node.Kind == yaml.AliasNode {
 | 
				
			||||||
		return p.resolveReset(node.Alias, path)
 | 
							return p.resolveReset(node.Alias, path)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								vendor/github.com/compose-spec/compose-go/v2/override/merge.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/compose-spec/compose-go/v2/override/merge.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -47,7 +47,7 @@ func init() {
 | 
				
			|||||||
	mergeSpecials["services.*.build"] = mergeBuild
 | 
						mergeSpecials["services.*.build"] = mergeBuild
 | 
				
			||||||
	mergeSpecials["services.*.build.args"] = mergeToSequence
 | 
						mergeSpecials["services.*.build.args"] = mergeToSequence
 | 
				
			||||||
	mergeSpecials["services.*.build.additional_contexts"] = mergeToSequence
 | 
						mergeSpecials["services.*.build.additional_contexts"] = mergeToSequence
 | 
				
			||||||
	mergeSpecials["services.*.build.extra_hosts"] = mergeToSequence
 | 
						mergeSpecials["services.*.build.extra_hosts"] = mergeExtraHosts
 | 
				
			||||||
	mergeSpecials["services.*.build.labels"] = mergeToSequence
 | 
						mergeSpecials["services.*.build.labels"] = mergeToSequence
 | 
				
			||||||
	mergeSpecials["services.*.command"] = override
 | 
						mergeSpecials["services.*.command"] = override
 | 
				
			||||||
	mergeSpecials["services.*.depends_on"] = mergeDependsOn
 | 
						mergeSpecials["services.*.depends_on"] = mergeDependsOn
 | 
				
			||||||
@@ -58,7 +58,7 @@ func init() {
 | 
				
			|||||||
	mergeSpecials["services.*.entrypoint"] = override
 | 
						mergeSpecials["services.*.entrypoint"] = override
 | 
				
			||||||
	mergeSpecials["services.*.env_file"] = mergeToSequence
 | 
						mergeSpecials["services.*.env_file"] = mergeToSequence
 | 
				
			||||||
	mergeSpecials["services.*.environment"] = mergeToSequence
 | 
						mergeSpecials["services.*.environment"] = mergeToSequence
 | 
				
			||||||
	mergeSpecials["services.*.extra_hosts"] = mergeToSequence
 | 
						mergeSpecials["services.*.extra_hosts"] = mergeExtraHosts
 | 
				
			||||||
	mergeSpecials["services.*.healthcheck.test"] = override
 | 
						mergeSpecials["services.*.healthcheck.test"] = override
 | 
				
			||||||
	mergeSpecials["services.*.labels"] = mergeToSequence
 | 
						mergeSpecials["services.*.labels"] = mergeToSequence
 | 
				
			||||||
	mergeSpecials["services.*.logging"] = mergeLogging
 | 
						mergeSpecials["services.*.logging"] = mergeLogging
 | 
				
			||||||
@@ -163,6 +163,22 @@ func mergeNetworks(c any, o any, path tree.Path) (any, error) {
 | 
				
			|||||||
	return mergeMappings(right, left, path)
 | 
						return mergeMappings(right, left, path)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func mergeExtraHosts(c any, o any, _ tree.Path) (any, error) {
 | 
				
			||||||
 | 
						right := convertIntoSequence(c)
 | 
				
			||||||
 | 
						left := convertIntoSequence(o)
 | 
				
			||||||
 | 
						// Rewrite content of left slice to remove duplicate elements
 | 
				
			||||||
 | 
						i := 0
 | 
				
			||||||
 | 
						for _, v := range left {
 | 
				
			||||||
 | 
							if !slices.Contains(right, v) {
 | 
				
			||||||
 | 
								left[i] = v
 | 
				
			||||||
 | 
								i++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// keep only not duplicated elements from left slice
 | 
				
			||||||
 | 
						left = left[:i]
 | 
				
			||||||
 | 
						return append(right, left...), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func mergeToSequence(c any, o any, _ tree.Path) (any, error) {
 | 
					func mergeToSequence(c any, o any, _ tree.Path) (any, error) {
 | 
				
			||||||
	right := convertIntoSequence(c)
 | 
						right := convertIntoSequence(c)
 | 
				
			||||||
	left := convertIntoSequence(o)
 | 
						left := convertIntoSequence(o)
 | 
				
			||||||
@@ -172,15 +188,21 @@ func mergeToSequence(c any, o any, _ tree.Path) (any, error) {
 | 
				
			|||||||
func convertIntoSequence(value any) []any {
 | 
					func convertIntoSequence(value any) []any {
 | 
				
			||||||
	switch v := value.(type) {
 | 
						switch v := value.(type) {
 | 
				
			||||||
	case map[string]any:
 | 
						case map[string]any:
 | 
				
			||||||
		seq := make([]any, len(v))
 | 
							var seq []any
 | 
				
			||||||
		i := 0
 | 
							for k, val := range v {
 | 
				
			||||||
		for k, v := range v {
 | 
								if val == nil {
 | 
				
			||||||
			if v == nil {
 | 
									seq = append(seq, k)
 | 
				
			||||||
				seq[i] = k
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				seq[i] = fmt.Sprintf("%s=%v", k, v)
 | 
									switch vl := val.(type) {
 | 
				
			||||||
 | 
									// if val is an array we need to add the key with each value one by one
 | 
				
			||||||
 | 
									case []any:
 | 
				
			||||||
 | 
										for _, vlv := range vl {
 | 
				
			||||||
 | 
											seq = append(seq, fmt.Sprintf("%s=%v", k, vlv))
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										seq = append(seq, fmt.Sprintf("%s=%v", k, val))
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			i++
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		slices.SortFunc(seq, func(a, b any) int {
 | 
							slices.SortFunc(seq, func(a, b any) int {
 | 
				
			||||||
			return cmp.Compare(a.(string), b.(string))
 | 
								return cmp.Compare(a.(string), b.(string))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										52
									
								
								vendor/github.com/compose-spec/compose-go/v2/schema/compose-spec.json
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/compose-spec/compose-go/v2/schema/compose-spec.json
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -267,6 +267,7 @@
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 | 
					        "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
 | 
				
			||||||
        "extra_hosts": {"$ref": "#/definitions/extra_hosts"},
 | 
					        "extra_hosts": {"$ref": "#/definitions/extra_hosts"},
 | 
				
			||||||
 | 
					        "gpus": {"$ref": "#/definitions/gpus"},
 | 
				
			||||||
        "group_add": {
 | 
					        "group_add": {
 | 
				
			||||||
          "type": "array",
 | 
					          "type": "array",
 | 
				
			||||||
          "items": {
 | 
					          "items": {
 | 
				
			||||||
@@ -370,6 +371,8 @@
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          "uniqueItems": true
 | 
					          "uniqueItems": true
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "post_start": {"type": "array", "items": {"$ref": "#/definitions/service_hook"}},
 | 
				
			||||||
 | 
					        "pre_stop": {"type": "array", "items": {"$ref": "#/definitions/service_hook"}},
 | 
				
			||||||
        "privileged": {"type": ["boolean", "string"]},
 | 
					        "privileged": {"type": ["boolean", "string"]},
 | 
				
			||||||
        "profiles": {"$ref": "#/definitions/list_of_strings"},
 | 
					        "profiles": {"$ref": "#/definitions/list_of_strings"},
 | 
				
			||||||
        "pull_policy": {"type": "string", "enum": [
 | 
					        "pull_policy": {"type": "string", "enum": [
 | 
				
			||||||
@@ -416,6 +419,7 @@
 | 
				
			|||||||
                    "properties": {
 | 
					                    "properties": {
 | 
				
			||||||
                      "propagation": {"type": "string"},
 | 
					                      "propagation": {"type": "string"},
 | 
				
			||||||
                      "create_host_path": {"type": ["boolean", "string"]},
 | 
					                      "create_host_path": {"type": ["boolean", "string"]},
 | 
				
			||||||
 | 
					                      "recursive": {"type": "string", "enum": ["enabled", "disabled", "writable", "readonly"]},
 | 
				
			||||||
                      "selinux": {"type": "string", "enum": ["z", "Z"]}
 | 
					                      "selinux": {"type": "string", "enum": ["z", "Z"]}
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    "additionalProperties": false,
 | 
					                    "additionalProperties": false,
 | 
				
			||||||
@@ -500,11 +504,11 @@
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
            "additionalProperties": false,
 | 
					            "additionalProperties": false,
 | 
				
			||||||
            "patternProperties": {"^x-": {}}
 | 
					            "patternProperties": {"^x-": {}}
 | 
				
			||||||
          },
 | 
					          }
 | 
				
			||||||
          "additionalProperties": false,
 | 
					 | 
				
			||||||
          "patternProperties": {"^x-": {}}
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      },
 | 
				
			||||||
 | 
					      "additionalProperties": false,
 | 
				
			||||||
 | 
					      "patternProperties": {"^x-": {}}
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "deployment": {
 | 
					    "deployment": {
 | 
				
			||||||
      "id": "#/definitions/deployment",
 | 
					      "id": "#/definitions/deployment",
 | 
				
			||||||
@@ -632,6 +636,26 @@
 | 
				
			|||||||
    "devices": {
 | 
					    "devices": {
 | 
				
			||||||
      "id": "#/definitions/devices",
 | 
					      "id": "#/definitions/devices",
 | 
				
			||||||
      "type": "array",
 | 
					      "type": "array",
 | 
				
			||||||
 | 
					      "items": {
 | 
				
			||||||
 | 
					        "type": "object",
 | 
				
			||||||
 | 
					        "properties": {
 | 
				
			||||||
 | 
					          "capabilities": {"$ref": "#/definitions/list_of_strings"},
 | 
				
			||||||
 | 
					          "count": {"type": ["string", "integer"]},
 | 
				
			||||||
 | 
					          "device_ids": {"$ref": "#/definitions/list_of_strings"},
 | 
				
			||||||
 | 
					          "driver":{"type": "string"},
 | 
				
			||||||
 | 
					          "options":{"$ref": "#/definitions/list_or_dict"}
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "additionalProperties": false,
 | 
				
			||||||
 | 
					        "patternProperties": {"^x-": {}},
 | 
				
			||||||
 | 
					        "required": [
 | 
				
			||||||
 | 
					          "capabilities"
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "gpus": {
 | 
				
			||||||
 | 
					      "id": "#/definitions/gpus",
 | 
				
			||||||
 | 
					      "type": "array",
 | 
				
			||||||
      "items": {
 | 
					      "items": {
 | 
				
			||||||
        "type": "object",
 | 
					        "type": "object",
 | 
				
			||||||
        "properties": {
 | 
					        "properties": {
 | 
				
			||||||
@@ -813,6 +837,20 @@
 | 
				
			|||||||
      ]
 | 
					      ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "service_hook": {
 | 
				
			||||||
 | 
					      "id": "#/definitions/service_hook",
 | 
				
			||||||
 | 
					      "type": "object",
 | 
				
			||||||
 | 
					      "properties": {
 | 
				
			||||||
 | 
					        "command": {"$ref": "#/definitions/command"},
 | 
				
			||||||
 | 
					        "user": {"type": "string"},
 | 
				
			||||||
 | 
					        "privileged": {"type": ["boolean", "string"]},
 | 
				
			||||||
 | 
					        "working_dir": {"type": "string"},
 | 
				
			||||||
 | 
					        "environment": {"$ref": "#/definitions/list_or_dict"}
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "additionalProperties": false,
 | 
				
			||||||
 | 
					      "patternProperties": {"^x-": {}}
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    "env_file": {
 | 
					    "env_file": {
 | 
				
			||||||
      "oneOf": [
 | 
					      "oneOf": [
 | 
				
			||||||
        {"type": "string"},
 | 
					        {"type": "string"},
 | 
				
			||||||
@@ -828,6 +866,9 @@
 | 
				
			|||||||
                  "path": {
 | 
					                  "path": {
 | 
				
			||||||
                    "type": "string"
 | 
					                    "type": "string"
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
 | 
					                  "format": {
 | 
				
			||||||
 | 
					                    "type": "string"
 | 
				
			||||||
 | 
					                  },
 | 
				
			||||||
                  "required": {
 | 
					                  "required": {
 | 
				
			||||||
                    "type": ["boolean", "string"],
 | 
					                    "type": ["boolean", "string"],
 | 
				
			||||||
                    "default": true
 | 
					                    "default": true
 | 
				
			||||||
@@ -878,7 +919,8 @@
 | 
				
			|||||||
          "patternProperties": {
 | 
					          "patternProperties": {
 | 
				
			||||||
            ".+": {
 | 
					            ".+": {
 | 
				
			||||||
              "type": ["string", "array"]
 | 
					              "type": ["string", "array"]
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
 | 
					            "uniqueItems": false
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          "additionalProperties": false
 | 
					          "additionalProperties": false
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								vendor/github.com/compose-spec/compose-go/v2/transform/canonical.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/compose-spec/compose-go/v2/transform/canonical.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -33,6 +33,7 @@ func init() {
 | 
				
			|||||||
	transformers["services.*.extends"] = transformExtends
 | 
						transformers["services.*.extends"] = transformExtends
 | 
				
			||||||
	transformers["services.*.networks"] = transformServiceNetworks
 | 
						transformers["services.*.networks"] = transformServiceNetworks
 | 
				
			||||||
	transformers["services.*.volumes.*"] = transformVolumeMount
 | 
						transformers["services.*.volumes.*"] = transformVolumeMount
 | 
				
			||||||
 | 
						transformers["services.*.dns"] = transformStringOrList
 | 
				
			||||||
	transformers["services.*.devices.*"] = transformDeviceMapping
 | 
						transformers["services.*.devices.*"] = transformDeviceMapping
 | 
				
			||||||
	transformers["services.*.secrets.*"] = transformFileMount
 | 
						transformers["services.*.secrets.*"] = transformFileMount
 | 
				
			||||||
	transformers["services.*.configs.*"] = transformFileMount
 | 
						transformers["services.*.configs.*"] = transformFileMount
 | 
				
			||||||
@@ -48,6 +49,15 @@ func init() {
 | 
				
			|||||||
	transformers["include.*"] = transformInclude
 | 
						transformers["include.*"] = transformInclude
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func transformStringOrList(data any, _ tree.Path, _ bool) (any, error) {
 | 
				
			||||||
 | 
						switch t := data.(type) {
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							return []any{t}, nil
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return data, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Canonical transforms a compose model into canonical syntax
 | 
					// Canonical transforms a compose model into canonical syntax
 | 
				
			||||||
func Canonical(yaml map[string]any, ignoreParseError bool) (map[string]any, error) {
 | 
					func Canonical(yaml map[string]any, ignoreParseError bool) (map[string]any, error) {
 | 
				
			||||||
	canonical, err := transform(yaml, tree.NewPath(), ignoreParseError)
 | 
						canonical, err := transform(yaml, tree.NewPath(), ignoreParseError)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/github.com/compose-spec/compose-go/v2/transform/defaults.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/compose-spec/compose-go/v2/transform/defaults.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -26,6 +26,8 @@ func init() {
 | 
				
			|||||||
	defaultValues["services.*.build"] = defaultBuildContext
 | 
						defaultValues["services.*.build"] = defaultBuildContext
 | 
				
			||||||
	defaultValues["services.*.secrets.*"] = defaultSecretMount
 | 
						defaultValues["services.*.secrets.*"] = defaultSecretMount
 | 
				
			||||||
	defaultValues["services.*.ports.*"] = portDefaults
 | 
						defaultValues["services.*.ports.*"] = portDefaults
 | 
				
			||||||
 | 
						defaultValues["services.*.deploy.resources.reservations.devices.*"] = deviceRequestDefaults
 | 
				
			||||||
 | 
						defaultValues["services.*.gpus.*"] = deviceRequestDefaults
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetDefaultValues transforms a compose model to set default values to missing attributes
 | 
					// SetDefaultValues transforms a compose model to set default values to missing attributes
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								vendor/github.com/compose-spec/compose-go/v2/transform/devices.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/compose-spec/compose-go/v2/transform/devices.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					   Copyright 2020 The Compose Specification Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package transform
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/compose-spec/compose-go/v2/tree"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func deviceRequestDefaults(data any, p tree.Path, _ bool) (any, error) {
 | 
				
			||||||
 | 
						v, ok := data.(map[string]any)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return data, fmt.Errorf("%s: invalid type %T for device request", p, v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, hasCount := v["count"]
 | 
				
			||||||
 | 
						_, hasIds := v["device_ids"]
 | 
				
			||||||
 | 
						if !hasCount && !hasIds {
 | 
				
			||||||
 | 
							v["count"] = "all"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return v, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/cpus.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/cpus.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					   Copyright 2020 The Compose Specification Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NanoCPUs float32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *NanoCPUs) DecodeMapstructure(a any) error {
 | 
				
			||||||
 | 
						switch v := a.(type) {
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							f, err := strconv.ParseFloat(v, 64)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							*n = NanoCPUs(f)
 | 
				
			||||||
 | 
						case int:
 | 
				
			||||||
 | 
							*n = NanoCPUs(v)
 | 
				
			||||||
 | 
						case float32:
 | 
				
			||||||
 | 
							*n = NanoCPUs(v)
 | 
				
			||||||
 | 
						case float64:
 | 
				
			||||||
 | 
							*n = NanoCPUs(v)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return fmt.Errorf("unexpected value type %T for cpus", v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *NanoCPUs) Value() float32 {
 | 
				
			||||||
 | 
						return float32(*n)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										681
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/derived.gen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										681
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/derived.gen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/device.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/device.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -27,6 +27,7 @@ type DeviceRequest struct {
 | 
				
			|||||||
	Driver       string      `yaml:"driver,omitempty" json:"driver,omitempty"`
 | 
						Driver       string      `yaml:"driver,omitempty" json:"driver,omitempty"`
 | 
				
			||||||
	Count        DeviceCount `yaml:"count,omitempty" json:"count,omitempty"`
 | 
						Count        DeviceCount `yaml:"count,omitempty" json:"count,omitempty"`
 | 
				
			||||||
	IDs          []string    `yaml:"device_ids,omitempty" json:"device_ids,omitempty"`
 | 
						IDs          []string    `yaml:"device_ids,omitempty" json:"device_ids,omitempty"`
 | 
				
			||||||
 | 
						Options      Mapping     `yaml:"options,omitempty" json:"options,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type DeviceCount int64
 | 
					type DeviceCount int64
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/envfile.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/envfile.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,6 +23,7 @@ import (
 | 
				
			|||||||
type EnvFile struct {
 | 
					type EnvFile struct {
 | 
				
			||||||
	Path     string `yaml:"path,omitempty" json:"path,omitempty"`
 | 
						Path     string `yaml:"path,omitempty" json:"path,omitempty"`
 | 
				
			||||||
	Required bool   `yaml:"required" json:"required"`
 | 
						Required bool   `yaml:"required" json:"required"`
 | 
				
			||||||
 | 
						Format   string `yaml:"format,omitempty" json:"format,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MarshalYAML makes EnvFile implement yaml.Marshaler
 | 
					// MarshalYAML makes EnvFile implement yaml.Marshaler
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/hooks.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					   Copyright 2020 The Compose Specification Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ServiceHook is a command to exec inside container by some lifecycle events
 | 
				
			||||||
 | 
					type ServiceHook struct {
 | 
				
			||||||
 | 
						Command     ShellCommand      `yaml:"command,omitempty" json:"command"`
 | 
				
			||||||
 | 
						User        string            `yaml:"user,omitempty" json:"user,omitempty"`
 | 
				
			||||||
 | 
						Privileged  bool              `yaml:"privileged,omitempty" json:"privileged,omitempty"`
 | 
				
			||||||
 | 
						WorkingDir  string            `yaml:"working_dir,omitempty" json:"working_dir,omitempty"`
 | 
				
			||||||
 | 
						Environment MappingWithEquals `yaml:"environment,omitempty" json:"environment,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/project.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/project.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -616,22 +616,11 @@ func (p Project) WithServicesEnvironmentResolved(discardEnvFiles bool) (*Project
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, envFile := range service.EnvFiles {
 | 
							for _, envFile := range service.EnvFiles {
 | 
				
			||||||
			if _, err := os.Stat(envFile.Path); os.IsNotExist(err) {
 | 
								vars, err := loadEnvFile(envFile, resolve)
 | 
				
			||||||
				if envFile.Required {
 | 
					 | 
				
			||||||
					return nil, fmt.Errorf("env file %s not found: %w", envFile.Path, err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			b, err := os.ReadFile(envFile.Path)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, fmt.Errorf("failed to load %s: %w", envFile.Path, err)
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								environment.OverrideBy(vars.ToMappingWithEquals())
 | 
				
			||||||
			fileVars, err := dotenv.ParseWithLookup(bytes.NewBuffer(b), resolve)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, fmt.Errorf("failed to read %s: %w", envFile.Path, err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			environment.OverrideBy(Mapping(fileVars).ToMappingWithEquals())
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		service.Environment = environment.OverrideBy(service.Environment)
 | 
							service.Environment = environment.OverrideBy(service.Environment)
 | 
				
			||||||
@@ -644,6 +633,31 @@ func (p Project) WithServicesEnvironmentResolved(discardEnvFiles bool) (*Project
 | 
				
			|||||||
	return newProject, nil
 | 
						return newProject, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func loadEnvFile(envFile EnvFile, resolve dotenv.LookupFn) (Mapping, error) {
 | 
				
			||||||
 | 
						if _, err := os.Stat(envFile.Path); os.IsNotExist(err) {
 | 
				
			||||||
 | 
							if envFile.Required {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("env file %s not found: %w", envFile.Path, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						file, err := os.Open(envFile.Path)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer file.Close() //nolint:errcheck
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var fileVars map[string]string
 | 
				
			||||||
 | 
						if envFile.Format != "" {
 | 
				
			||||||
 | 
							fileVars, err = dotenv.ParseWithFormat(file, envFile.Path, resolve, envFile.Format)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							fileVars, err = dotenv.ParseWithLookup(file, resolve)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fileVars, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *Project) deepCopy() *Project {
 | 
					func (p *Project) deepCopy() *Project {
 | 
				
			||||||
	if p == nil {
 | 
						if p == nil {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/compose-spec/compose-go/v2/types/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -20,7 +20,6 @@ import (
 | 
				
			|||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/go-connections/nat"
 | 
						"github.com/docker/go-connections/nat"
 | 
				
			||||||
@@ -82,6 +81,7 @@ type ServiceConfig struct {
 | 
				
			|||||||
	ExternalLinks   []string                         `yaml:"external_links,omitempty" json:"external_links,omitempty"`
 | 
						ExternalLinks   []string                         `yaml:"external_links,omitempty" json:"external_links,omitempty"`
 | 
				
			||||||
	ExtraHosts      HostsList                        `yaml:"extra_hosts,omitempty" json:"extra_hosts,omitempty"`
 | 
						ExtraHosts      HostsList                        `yaml:"extra_hosts,omitempty" json:"extra_hosts,omitempty"`
 | 
				
			||||||
	GroupAdd        []string                         `yaml:"group_add,omitempty" json:"group_add,omitempty"`
 | 
						GroupAdd        []string                         `yaml:"group_add,omitempty" json:"group_add,omitempty"`
 | 
				
			||||||
 | 
						Gpus            []DeviceRequest                  `yaml:"gpus,omitempty" json:"gpus,omitempty"`
 | 
				
			||||||
	Hostname        string                           `yaml:"hostname,omitempty" json:"hostname,omitempty"`
 | 
						Hostname        string                           `yaml:"hostname,omitempty" json:"hostname,omitempty"`
 | 
				
			||||||
	HealthCheck     *HealthCheckConfig               `yaml:"healthcheck,omitempty" json:"healthcheck,omitempty"`
 | 
						HealthCheck     *HealthCheckConfig               `yaml:"healthcheck,omitempty" json:"healthcheck,omitempty"`
 | 
				
			||||||
	Image           string                           `yaml:"image,omitempty" json:"image,omitempty"`
 | 
						Image           string                           `yaml:"image,omitempty" json:"image,omitempty"`
 | 
				
			||||||
@@ -132,6 +132,8 @@ type ServiceConfig struct {
 | 
				
			|||||||
	Volumes         []ServiceVolumeConfig            `yaml:"volumes,omitempty" json:"volumes,omitempty"`
 | 
						Volumes         []ServiceVolumeConfig            `yaml:"volumes,omitempty" json:"volumes,omitempty"`
 | 
				
			||||||
	VolumesFrom     []string                         `yaml:"volumes_from,omitempty" json:"volumes_from,omitempty"`
 | 
						VolumesFrom     []string                         `yaml:"volumes_from,omitempty" json:"volumes_from,omitempty"`
 | 
				
			||||||
	WorkingDir      string                           `yaml:"working_dir,omitempty" json:"working_dir,omitempty"`
 | 
						WorkingDir      string                           `yaml:"working_dir,omitempty" json:"working_dir,omitempty"`
 | 
				
			||||||
 | 
						PostStart       []ServiceHook                    `yaml:"post_start,omitempty" json:"post_start,omitempty"`
 | 
				
			||||||
 | 
						PreStop         []ServiceHook                    `yaml:"pre_stop,omitempty" json:"pre_stop,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 | 
						Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -388,30 +390,6 @@ type Resource struct {
 | 
				
			|||||||
	Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 | 
						Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type NanoCPUs float32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n *NanoCPUs) DecodeMapstructure(a any) error {
 | 
					 | 
				
			||||||
	switch v := a.(type) {
 | 
					 | 
				
			||||||
	case string:
 | 
					 | 
				
			||||||
		f, err := strconv.ParseFloat(v, 64)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		*n = NanoCPUs(f)
 | 
					 | 
				
			||||||
	case float32:
 | 
					 | 
				
			||||||
		*n = NanoCPUs(v)
 | 
					 | 
				
			||||||
	case float64:
 | 
					 | 
				
			||||||
		*n = NanoCPUs(v)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return fmt.Errorf("unexpected value type %T for cpus", v)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n *NanoCPUs) Value() float32 {
 | 
					 | 
				
			||||||
	return float32(*n)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GenericResource represents a "user defined" resource which can
 | 
					// GenericResource represents a "user defined" resource which can
 | 
				
			||||||
// only be an integer (e.g: SSD=3) for a service
 | 
					// only be an integer (e.g: SSD=3) for a service
 | 
				
			||||||
type GenericResource struct {
 | 
					type GenericResource struct {
 | 
				
			||||||
@@ -552,9 +530,6 @@ func (s ServiceVolumeConfig) String() string {
 | 
				
			|||||||
	if s.Volume != nil && s.Volume.NoCopy {
 | 
						if s.Volume != nil && s.Volume.NoCopy {
 | 
				
			||||||
		options = append(options, "nocopy")
 | 
							options = append(options, "nocopy")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if s.Volume != nil && s.Volume.Subpath != "" {
 | 
					 | 
				
			||||||
		options = append(options, s.Volume.Subpath)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%s:%s:%s", s.Source, s.Target, strings.Join(options, ","))
 | 
						return fmt.Sprintf("%s:%s:%s", s.Source, s.Target, strings.Join(options, ","))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -581,6 +556,7 @@ type ServiceVolumeBind struct {
 | 
				
			|||||||
	SELinux        string `yaml:"selinux,omitempty" json:"selinux,omitempty"`
 | 
						SELinux        string `yaml:"selinux,omitempty" json:"selinux,omitempty"`
 | 
				
			||||||
	Propagation    string `yaml:"propagation,omitempty" json:"propagation,omitempty"`
 | 
						Propagation    string `yaml:"propagation,omitempty" json:"propagation,omitempty"`
 | 
				
			||||||
	CreateHostPath bool   `yaml:"create_host_path,omitempty" json:"create_host_path,omitempty"`
 | 
						CreateHostPath bool   `yaml:"create_host_path,omitempty" json:"create_host_path,omitempty"`
 | 
				
			||||||
 | 
						Recursive      string `yaml:"recursive,omitempty" json:"recursive,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 | 
						Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								vendor/github.com/compose-spec/compose-go/v2/validation/validation.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/compose-spec/compose-go/v2/validation/validation.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -30,6 +30,8 @@ var checks = map[tree.Path]checkerFunc{
 | 
				
			|||||||
	"configs.*":                       checkFileObject("file", "environment", "content"),
 | 
						"configs.*":                       checkFileObject("file", "environment", "content"),
 | 
				
			||||||
	"secrets.*":                       checkFileObject("file", "environment"),
 | 
						"secrets.*":                       checkFileObject("file", "environment"),
 | 
				
			||||||
	"services.*.develop.watch.*.path": checkPath,
 | 
						"services.*.develop.watch.*.path": checkPath,
 | 
				
			||||||
 | 
						"services.*.deploy.resources.reservations.devices.*": checkDeviceRequest,
 | 
				
			||||||
 | 
						"services.*.gpus.*": checkDeviceRequest,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Validate(dict map[string]any) error {
 | 
					func Validate(dict map[string]any) error {
 | 
				
			||||||
@@ -94,3 +96,13 @@ func checkPath(value any, p tree.Path) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func checkDeviceRequest(value any, p tree.Path) error {
 | 
				
			||||||
 | 
						v := value.(map[string]any)
 | 
				
			||||||
 | 
						_, hasCount := v["count"]
 | 
				
			||||||
 | 
						_, hasIds := v["device_ids"]
 | 
				
			||||||
 | 
						if hasCount && hasIds {
 | 
				
			||||||
 | 
							return fmt.Errorf(`%s: "count" and "device_ids" attributes are exclusive`, p)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -128,7 +128,7 @@ github.com/cenkalti/backoff/v4
 | 
				
			|||||||
# github.com/cespare/xxhash/v2 v2.3.0
 | 
					# github.com/cespare/xxhash/v2 v2.3.0
 | 
				
			||||||
## explicit; go 1.11
 | 
					## explicit; go 1.11
 | 
				
			||||||
github.com/cespare/xxhash/v2
 | 
					github.com/cespare/xxhash/v2
 | 
				
			||||||
# github.com/compose-spec/compose-go/v2 v2.2.0
 | 
					# github.com/compose-spec/compose-go/v2 v2.4.1
 | 
				
			||||||
## explicit; go 1.21
 | 
					## explicit; go 1.21
 | 
				
			||||||
github.com/compose-spec/compose-go/v2/cli
 | 
					github.com/compose-spec/compose-go/v2/cli
 | 
				
			||||||
github.com/compose-spec/compose-go/v2/consts
 | 
					github.com/compose-spec/compose-go/v2/consts
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user