diff --git a/go.mod b/go.mod index 5c082cad0..f7f775e65 100644 --- a/go.mod +++ b/go.mod @@ -13,9 +13,9 @@ require ( github.com/docker/docker v20.10.10+incompatible github.com/docker/docker-credential-helpers v0.6.4 // indirect github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/libcompose v0.4.0 + github.com/docker/go-units v0.4.0 github.com/drone/envsubst v1.0.3 - github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect + github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.7.4 diff --git a/go.sum b/go.sum index e0c476d96..288865d1b 100644 --- a/go.sum +++ b/go.sum @@ -263,8 +263,6 @@ github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libcompose v0.4.0 h1:zK7Ug0lCxPB8FDFNdCvR2ZjJjeJZ/607lfAYkp1hrtc= -github.com/docker/libcompose v0.4.0/go.mod h1:EyqDS+Iyca0hS44T7qIMTeO1EOYWWWNOGpufHu9R8cs= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= diff --git a/pipeline/frontend/yaml/compiler/cacher.go b/pipeline/frontend/yaml/compiler/cacher.go index 15c3122d7..3de19b50c 100644 --- a/pipeline/frontend/yaml/compiler/cacher.go +++ b/pipeline/frontend/yaml/compiler/cacher.go @@ -4,9 +4,8 @@ import ( "path" "strings" - libcompose "github.com/docker/libcompose/yaml" - "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml" + "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types" ) // Cacher defines a compiler transform that can be used @@ -31,8 +30,8 @@ func (c *volumeCacher) Restore(repo, branch string, mounts []string) *yaml.Conta "file": strings.Replace(branch, "/", "_", -1) + ".tar", "fallback_to": "master.tar", }, - Volumes: libcompose.Volumes{ - Volumes: []*libcompose.Volume{ + Volumes: types.Volumes{ + Volumes: []*types.Volume{ { Source: path.Join(c.base, repo), Destination: "/cache", @@ -54,8 +53,8 @@ func (c *volumeCacher) Rebuild(repo, branch string, mounts []string) *yaml.Conta "flush": true, "file": strings.Replace(branch, "/", "_", -1) + ".tar", }, - Volumes: libcompose.Volumes{ - Volumes: []*libcompose.Volume{ + Volumes: types.Volumes{ + Volumes: []*types.Volume{ { Source: path.Join(c.base, repo), Destination: "/cache", diff --git a/pipeline/frontend/yaml/config.go b/pipeline/frontend/yaml/config.go index 6879d3eaf..9bf676d07 100644 --- a/pipeline/frontend/yaml/config.go +++ b/pipeline/frontend/yaml/config.go @@ -5,14 +5,15 @@ import ( "io/ioutil" "os" - libcompose "github.com/docker/libcompose/yaml" "gopkg.in/yaml.v3" + + "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types" ) type ( // Config defines a pipeline configuration. Config struct { - Cache libcompose.Stringorslice + Cache types.Stringorslice Platform string Branches Constraint Workspace Workspace @@ -21,7 +22,7 @@ type ( Services Containers Networks Networks Volumes Volumes - Labels libcompose.SliceorMap + Labels types.SliceorMap DependsOn []string `yaml:"depends_on,omitempty"` RunsOn []string `yaml:"runs_on,omitempty"` SkipClone bool `yaml:"skip_clone"` diff --git a/pipeline/frontend/yaml/config_test.go b/pipeline/frontend/yaml/config_test.go index 86fb5b77a..9220135e0 100644 --- a/pipeline/frontend/yaml/config_test.go +++ b/pipeline/frontend/yaml/config_test.go @@ -3,8 +3,9 @@ package yaml import ( "testing" - "github.com/docker/libcompose/yaml" "github.com/franela/goblin" + + "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types" ) func TestParse(t *testing.T) { @@ -29,10 +30,10 @@ func TestParse(t *testing.T) { g.Assert(out.Services.Containers[0].Image).Equal("mysql") g.Assert(out.Pipeline.Containers[0].Name).Equal("test") g.Assert(out.Pipeline.Containers[0].Image).Equal("golang") - g.Assert(out.Pipeline.Containers[0].Commands).Equal(yaml.Stringorslice{"go install", "go test"}) + g.Assert(out.Pipeline.Containers[0].Commands).Equal(types.Stringorslice{"go install", "go test"}) g.Assert(out.Pipeline.Containers[1].Name).Equal("build") g.Assert(out.Pipeline.Containers[1].Image).Equal("golang") - g.Assert(out.Pipeline.Containers[1].Commands).Equal(yaml.Stringorslice{"go build"}) + g.Assert(out.Pipeline.Containers[1].Commands).Equal(types.Stringorslice{"go build"}) g.Assert(out.Pipeline.Containers[2].Name).Equal("notify") g.Assert(out.Pipeline.Containers[2].Image).Equal("slack") // g.Assert(out.Pipeline.Containers[2].NetworkMode).Equal("container:name") diff --git a/pipeline/frontend/yaml/constraint.go b/pipeline/frontend/yaml/constraint.go index ac7150755..a605a6dd9 100644 --- a/pipeline/frontend/yaml/constraint.go +++ b/pipeline/frontend/yaml/constraint.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/bmatcuk/doublestar/v4" - libcompose "github.com/docker/libcompose/yaml" "gopkg.in/yaml.v3" "github.com/woodpecker-ci/woodpecker/pipeline/frontend" @@ -101,11 +100,11 @@ func (c *Constraint) Excludes(v string) bool { // UnmarshalYAML unmarshals the constraint. func (c *Constraint) UnmarshalYAML(value *yaml.Node) error { var out1 = struct { - Include libcompose.Stringorslice - Exclude libcompose.Stringorslice + Include types.Stringorslice + Exclude types.Stringorslice }{} - var out2 libcompose.Stringorslice + var out2 types.Stringorslice err1 := value.Decode(&out1) err2 := value.Decode(&out2) @@ -179,12 +178,12 @@ func (c *ConstraintMap) UnmarshalYAML(unmarshal func(interface{}) error) error { // UnmarshalYAML unmarshals the constraint. func (c *ConstraintPath) UnmarshalYAML(value *yaml.Node) error { var out1 = struct { - Include libcompose.Stringorslice `yaml:"include,omitempty"` - Exclude libcompose.Stringorslice `yaml:"exclude,omitempty"` - IgnoreMessage string `yaml:"ignore_message,omitempty"` + Include types.Stringorslice `yaml:"include,omitempty"` + Exclude types.Stringorslice `yaml:"exclude,omitempty"` + IgnoreMessage string `yaml:"ignore_message,omitempty"` }{} - var out2 libcompose.Stringorslice + var out2 types.Stringorslice err1 := value.Decode(&out1) err2 := value.Decode(&out2) diff --git a/pipeline/frontend/yaml/container.go b/pipeline/frontend/yaml/container.go index 6fb6b4ea2..e72339f34 100644 --- a/pipeline/frontend/yaml/container.go +++ b/pipeline/frontend/yaml/container.go @@ -3,8 +3,9 @@ package yaml import ( "fmt" - libcompose "github.com/docker/libcompose/yaml" "gopkg.in/yaml.v3" + + "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types" ) type ( @@ -22,42 +23,42 @@ type ( // Container defines a container. Container struct { - AuthConfig AuthConfig `yaml:"auth_config,omitempty"` - CapAdd []string `yaml:"cap_add,omitempty"` - CapDrop []string `yaml:"cap_drop,omitempty"` - Command libcompose.Command `yaml:"command,omitempty"` - Commands libcompose.Stringorslice `yaml:"commands,omitempty"` - CPUQuota libcompose.StringorInt `yaml:"cpu_quota,omitempty"` - CPUSet string `yaml:"cpuset,omitempty"` - CPUShares libcompose.StringorInt `yaml:"cpu_shares,omitempty"` - Detached bool `yaml:"detach,omitempty"` - Devices []string `yaml:"devices,omitempty"` - Tmpfs []string `yaml:"tmpfs,omitempty"` - DNS libcompose.Stringorslice `yaml:"dns,omitempty"` - DNSSearch libcompose.Stringorslice `yaml:"dns_search,omitempty"` - Entrypoint libcompose.Command `yaml:"entrypoint,omitempty"` - Environment libcompose.SliceorMap `yaml:"environment,omitempty"` - ExtraHosts []string `yaml:"extra_hosts,omitempty"` - Group string `yaml:"group,omitempty"` - Image string `yaml:"image,omitempty"` - Isolation string `yaml:"isolation,omitempty"` - Labels libcompose.SliceorMap `yaml:"labels,omitempty"` - MemLimit libcompose.MemStringorInt `yaml:"mem_limit,omitempty"` - MemSwapLimit libcompose.MemStringorInt `yaml:"memswap_limit,omitempty"` - MemSwappiness libcompose.MemStringorInt `yaml:"mem_swappiness,omitempty"` - Name string `yaml:"name,omitempty"` - NetworkMode string `yaml:"network_mode,omitempty"` - IpcMode string `yaml:"ipc_mode,omitempty"` - Networks libcompose.Networks `yaml:"networks,omitempty"` - Privileged bool `yaml:"privileged,omitempty"` - Pull bool `yaml:"pull,omitempty"` - ShmSize libcompose.MemStringorInt `yaml:"shm_size,omitempty"` - Ulimits libcompose.Ulimits `yaml:"ulimits,omitempty"` - Volumes libcompose.Volumes `yaml:"volumes,omitempty"` - Secrets Secrets `yaml:"secrets,omitempty"` - Sysctls libcompose.SliceorMap `yaml:"sysctls,omitempty"` - Constraints Constraints `yaml:"when,omitempty"` - Vargs map[string]interface{} `yaml:",inline"` + AuthConfig AuthConfig `yaml:"auth_config,omitempty"` + CapAdd []string `yaml:"cap_add,omitempty"` + CapDrop []string `yaml:"cap_drop,omitempty"` + Command types.Command `yaml:"command,omitempty"` + Commands types.Stringorslice `yaml:"commands,omitempty"` + CPUQuota types.StringorInt `yaml:"cpu_quota,omitempty"` + CPUSet string `yaml:"cpuset,omitempty"` + CPUShares types.StringorInt `yaml:"cpu_shares,omitempty"` + Detached bool `yaml:"detach,omitempty"` + Devices []string `yaml:"devices,omitempty"` + Tmpfs []string `yaml:"tmpfs,omitempty"` + DNS types.Stringorslice `yaml:"dns,omitempty"` + DNSSearch types.Stringorslice `yaml:"dns_search,omitempty"` + Entrypoint types.Command `yaml:"entrypoint,omitempty"` + Environment types.SliceorMap `yaml:"environment,omitempty"` + ExtraHosts []string `yaml:"extra_hosts,omitempty"` + Group string `yaml:"group,omitempty"` + Image string `yaml:"image,omitempty"` + Isolation string `yaml:"isolation,omitempty"` + Labels types.SliceorMap `yaml:"labels,omitempty"` + MemLimit types.MemStringorInt `yaml:"mem_limit,omitempty"` + MemSwapLimit types.MemStringorInt `yaml:"memswap_limit,omitempty"` + MemSwappiness types.MemStringorInt `yaml:"mem_swappiness,omitempty"` + Name string `yaml:"name,omitempty"` + NetworkMode string `yaml:"network_mode,omitempty"` + IpcMode string `yaml:"ipc_mode,omitempty"` + Networks types.Networks `yaml:"networks,omitempty"` + Privileged bool `yaml:"privileged,omitempty"` + Pull bool `yaml:"pull,omitempty"` + ShmSize types.MemStringorInt `yaml:"shm_size,omitempty"` + Ulimits types.Ulimits `yaml:"ulimits,omitempty"` + Volumes types.Volumes `yaml:"volumes,omitempty"` + Secrets Secrets `yaml:"secrets,omitempty"` + Sysctls types.SliceorMap `yaml:"sysctls,omitempty"` + Constraints Constraints `yaml:"when,omitempty"` + Vargs map[string]interface{} `yaml:",inline"` } ) diff --git a/pipeline/frontend/yaml/container_test.go b/pipeline/frontend/yaml/container_test.go index 3e920728f..03d1f0c0c 100644 --- a/pipeline/frontend/yaml/container_test.go +++ b/pipeline/frontend/yaml/container_test.go @@ -4,9 +4,10 @@ import ( "reflect" "testing" - libcompose "github.com/docker/libcompose/yaml" "github.com/kr/pretty" "gopkg.in/yaml.v3" + + "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types" ) var containerYaml = []byte(` @@ -68,27 +69,27 @@ func TestUnmarshalContainer(t *testing.T) { }, CapAdd: []string{"ALL"}, CapDrop: []string{"NET_ADMIN", "SYS_ADMIN"}, - Command: libcompose.Command{"bundle", "exec", "thin", "-p", "3000"}, - Commands: libcompose.Stringorslice{"go build", "go test"}, - CPUQuota: libcompose.StringorInt(11), + Command: types.Command{"bundle", "exec", "thin", "-p", "3000"}, + Commands: types.Stringorslice{"go build", "go test"}, + CPUQuota: types.StringorInt(11), CPUSet: "1,2", - CPUShares: libcompose.StringorInt(99), + CPUShares: types.StringorInt(99), Detached: true, Devices: []string{"/dev/ttyUSB0:/dev/ttyUSB0"}, - DNS: libcompose.Stringorslice{"8.8.8.8"}, - DNSSearch: libcompose.Stringorslice{"example.com"}, - Entrypoint: libcompose.Command{"/code/entrypoint.sh"}, - Environment: libcompose.SliceorMap{"RACK_ENV": "development", "SHOW": "true"}, + DNS: types.Stringorslice{"8.8.8.8"}, + DNSSearch: types.Stringorslice{"example.com"}, + Entrypoint: types.Command{"/code/entrypoint.sh"}, + Environment: types.SliceorMap{"RACK_ENV": "development", "SHOW": "true"}, ExtraHosts: []string{"somehost:162.242.195.82", "otherhost:50.31.209.229"}, Image: "golang:latest", Isolation: "hyperv", - Labels: libcompose.SliceorMap{"com.example.type": "build", "com.example.team": "frontend"}, - MemLimit: libcompose.MemStringorInt(1024), - MemSwapLimit: libcompose.MemStringorInt(1024), - MemSwappiness: libcompose.MemStringorInt(1024), + Labels: types.SliceorMap{"com.example.type": "build", "com.example.team": "frontend"}, + MemLimit: types.MemStringorInt(1024), + MemSwapLimit: types.MemStringorInt(1024), + MemSwappiness: types.MemStringorInt(1024), Name: "my-build-container", - Networks: libcompose.Networks{ - Networks: []*libcompose.Network{ + Networks: types.Networks{ + Networks: []*types.Network{ {Name: "some-network"}, {Name: "other-network"}, }, @@ -96,10 +97,10 @@ func TestUnmarshalContainer(t *testing.T) { NetworkMode: "bridge", Pull: true, Privileged: true, - ShmSize: libcompose.MemStringorInt(1024), - Tmpfs: libcompose.Stringorslice{"/var/lib/test"}, - Volumes: libcompose.Volumes{ - Volumes: []*libcompose.Volume{ + ShmSize: types.MemStringorInt(1024), + Tmpfs: types.Stringorslice{"/var/lib/test"}, + Volumes: types.Volumes{ + Volumes: []*types.Volume{ {Source: "", Destination: "/var/lib/mysql"}, {Source: "/opt/data", Destination: "/var/lib/mysql"}, {Source: "/etc/configs", Destination: "/etc/configs/", AccessMode: "ro"}, diff --git a/vendor/github.com/docker/libcompose/yaml/command.go b/pipeline/frontend/yaml/types/command.go similarity index 88% rename from vendor/github.com/docker/libcompose/yaml/command.go rename to pipeline/frontend/yaml/types/command.go index ace69b5d3..8a1635bbf 100644 --- a/vendor/github.com/docker/libcompose/yaml/command.go +++ b/pipeline/frontend/yaml/types/command.go @@ -1,17 +1,18 @@ -package yaml +package types import ( "errors" "fmt" "github.com/docker/docker/api/types/strslice" + // TODO: search for maintained "github.com/flynn/go-shlex" ) // Command represents a docker command, can be a string or an array of strings. type Command strslice.StrSlice -// UnmarshalYAML implements the Unmarshaller interface. +// UnmarshalYAML implements the Unmarshaler interface. func (s *Command) UnmarshalYAML(unmarshal func(interface{}) error) error { var stringType string if err := unmarshal(&stringType); err == nil { diff --git a/pipeline/frontend/yaml/types/command_test.go b/pipeline/frontend/yaml/types/command_test.go new file mode 100644 index 000000000..a8fa66a7e --- /dev/null +++ b/pipeline/frontend/yaml/types/command_test.go @@ -0,0 +1,60 @@ +package types + +import ( + "strings" + "testing" + + "gopkg.in/yaml.v3" + + "github.com/stretchr/testify/assert" +) + +type StructCommand struct { + Entrypoint Command `yaml:"entrypoint,flow,omitempty"` + Command Command `yaml:"command,flow,omitempty"` +} + +func TestUnmarshalCommand(t *testing.T) { + s := &StructCommand{} + err := yaml.Unmarshal([]byte(`command: bash`), s) + + assert.Nil(t, err) + assert.Equal(t, Command{"bash"}, s.Command) + assert.Nil(t, s.Entrypoint) + bytes, err := yaml.Marshal(s) + assert.Nil(t, err) + + s2 := &StructCommand{} + err = yaml.Unmarshal(bytes, s2) + + assert.Nil(t, err) + assert.Equal(t, Command{"bash"}, s2.Command) + assert.Nil(t, s2.Entrypoint) + + s3 := &StructCommand{} + err = yaml.Unmarshal([]byte(`command: + - echo AAA; echo "wow" + - sleep 3s`), s3) + assert.Nil(t, err) + assert.Equal(t, Command{`echo AAA; echo "wow"`, `sleep 3s`}, s3.Command) +} + +var sampleEmptyCommand = `{}` + +func TestUnmarshalEmptyCommand(t *testing.T) { + s := &StructCommand{} + err := yaml.Unmarshal([]byte(sampleEmptyCommand), s) + + assert.Nil(t, err) + assert.Nil(t, s.Command) + + bytes, err := yaml.Marshal(s) + assert.Nil(t, err) + assert.Equal(t, "{}", strings.TrimSpace(string(bytes))) + + s2 := &StructCommand{} + err = yaml.Unmarshal(bytes, s2) + + assert.Nil(t, err) + assert.Nil(t, s2.Command) +} diff --git a/vendor/github.com/docker/libcompose/yaml/network.go b/pipeline/frontend/yaml/types/network.go similarity index 96% rename from vendor/github.com/docker/libcompose/yaml/network.go rename to pipeline/frontend/yaml/types/network.go index 2776b8586..5659d376d 100644 --- a/vendor/github.com/docker/libcompose/yaml/network.go +++ b/pipeline/frontend/yaml/types/network.go @@ -1,4 +1,4 @@ -package yaml +package types import ( "errors" @@ -14,7 +14,6 @@ type Networks struct { // Network represents a service network in compose file. type Network struct { Name string `yaml:"-"` - RealName string `yaml:"-"` Aliases []string `yaml:"aliases,omitempty"` IPv4Address string `yaml:"ipv4_address,omitempty"` IPv6Address string `yaml:"ipv6_address,omitempty"` @@ -29,7 +28,7 @@ func (n Networks) MarshalYAML() (interface{}, error) { return m, nil } -// UnmarshalYAML implements the Unmarshaller interface. +// UnmarshalYAML implements the Unmarshaler interface. func (n *Networks) UnmarshalYAML(unmarshal func(interface{}) error) error { var sliceType []interface{} if err := unmarshal(&sliceType); err == nil { diff --git a/pipeline/frontend/yaml/types/network_test.go b/pipeline/frontend/yaml/types/network_test.go new file mode 100644 index 000000000..35792aacc --- /dev/null +++ b/pipeline/frontend/yaml/types/network_test.go @@ -0,0 +1,165 @@ +package types + +import ( + "testing" + + todo_yaml "gopkg.in/yaml.v2" + "gopkg.in/yaml.v3" + + "github.com/stretchr/testify/assert" +) + +func TestMarshalNetworks(t *testing.T) { + networks := []struct { + networks Networks + expected string + }{ + { + networks: Networks{}, + expected: `{} +`, + }, + { + networks: Networks{ + Networks: []*Network{ + { + Name: "network1", + }, + { + Name: "network2", + }, + }, + }, + expected: `network1: {} +network2: {} +`, + }, + { + networks: Networks{ + Networks: []*Network{ + { + Name: "network1", + Aliases: []string{"alias1", "alias2"}, + }, + { + Name: "network2", + }, + }, + }, + expected: `network1: + aliases: + - alias1 + - alias2 +network2: {} +`, + }, + { + networks: Networks{ + Networks: []*Network{ + { + Name: "network1", + Aliases: []string{"alias1", "alias2"}, + }, + { + Name: "network2", + IPv4Address: "172.16.238.10", + IPv6Address: "2001:3984:3989::10", + }, + }, + }, + expected: `network1: + aliases: + - alias1 + - alias2 +network2: + ipv4_address: 172.16.238.10 + ipv6_address: 2001:3984:3989::10 +`, + }, + } + for _, network := range networks { + bytes, err := yaml.Marshal(network.networks) + assert.Nil(t, err) + assert.Equal(t, network.expected, string(bytes), "should be equal") + } +} + +func TestUnmarshalNetworks(t *testing.T) { + networks := []struct { + yaml string + expected *Networks + }{ + { + yaml: `- network1 +- network2`, + expected: &Networks{ + Networks: []*Network{ + { + Name: "network1", + }, + { + Name: "network2", + }, + }, + }, + }, + { + yaml: `network1:`, + expected: &Networks{ + Networks: []*Network{ + { + Name: "network1", + }, + }, + }, + }, + { + yaml: `network1: {}`, + expected: &Networks{ + Networks: []*Network{ + { + Name: "network1", + }, + }, + }, + }, + { + yaml: `network1: + aliases: + - alias1 + - alias2`, + expected: &Networks{ + Networks: []*Network{ + { + Name: "network1", + Aliases: []string{"alias1", "alias2"}, + }, + }, + }, + }, + { + yaml: `network1: + aliases: + - alias1 + - alias2 + ipv4_address: 172.16.238.10 + ipv6_address: 2001:3984:3989::10`, + expected: &Networks{ + Networks: []*Network{ + { + Name: "network1", + Aliases: []string{"alias1", "alias2"}, + IPv4Address: "172.16.238.10", + IPv6Address: "2001:3984:3989::10", + }, + }, + }, + }, + } + for _, network := range networks { + actual := &Networks{} + err := todo_yaml.Unmarshal([]byte(network.yaml), actual) + assert.Nil(t, err) + assert.Equal(t, network.expected, actual, "should be equal") + } +} diff --git a/vendor/github.com/docker/libcompose/yaml/types_yaml.go b/pipeline/frontend/yaml/types/types_yaml.go similarity index 54% rename from vendor/github.com/docker/libcompose/yaml/types_yaml.go rename to pipeline/frontend/yaml/types/types_yaml.go index 5e75e5eca..1c1f5d26f 100644 --- a/vendor/github.com/docker/libcompose/yaml/types_yaml.go +++ b/pipeline/frontend/yaml/types/types_yaml.go @@ -1,4 +1,4 @@ -package yaml +package types import ( "errors" @@ -135,100 +135,6 @@ func (s *SliceorMap) UnmarshalYAML(unmarshal func(interface{}) error) error { return errors.New("Failed to unmarshal SliceorMap") } -// MaporEqualSlice represents a slice of strings that gets unmarshal from a -// YAML map into 'key=value' string. -type MaporEqualSlice []string - -// UnmarshalYAML implements the Unmarshaller interface. -func (s *MaporEqualSlice) UnmarshalYAML(unmarshal func(interface{}) error) error { - parts, err := unmarshalToStringOrSepMapParts(unmarshal, "=") - if err != nil { - return err - } - *s = parts - return nil -} - -// ToMap returns the list of string as a map splitting using = the key=value -func (s *MaporEqualSlice) ToMap() map[string]string { - return toMap(*s, "=") -} - -// MaporColonSlice represents a slice of strings that gets unmarshal from a -// YAML map into 'key:value' string. -type MaporColonSlice []string - -// UnmarshalYAML implements the Unmarshaller interface. -func (s *MaporColonSlice) UnmarshalYAML(unmarshal func(interface{}) error) error { - parts, err := unmarshalToStringOrSepMapParts(unmarshal, ":") - if err != nil { - return err - } - *s = parts - return nil -} - -// ToMap returns the list of string as a map splitting using = the key=value -func (s *MaporColonSlice) ToMap() map[string]string { - return toMap(*s, ":") -} - -// MaporSpaceSlice represents a slice of strings that gets unmarshal from a -// YAML map into 'key value' string. -type MaporSpaceSlice []string - -// UnmarshalYAML implements the Unmarshaller interface. -func (s *MaporSpaceSlice) UnmarshalYAML(unmarshal func(interface{}) error) error { - parts, err := unmarshalToStringOrSepMapParts(unmarshal, " ") - if err != nil { - return err - } - *s = parts - return nil -} - -// ToMap returns the list of string as a map splitting using = the key=value -func (s *MaporSpaceSlice) ToMap() map[string]string { - return toMap(*s, " ") -} - -func unmarshalToStringOrSepMapParts(unmarshal func(interface{}) error, key string) ([]string, error) { - var sliceType []interface{} - if err := unmarshal(&sliceType); err == nil { - return toStrings(sliceType) - } - var mapType map[interface{}]interface{} - if err := unmarshal(&mapType); err == nil { - return toSepMapParts(mapType, key) - } - return nil, errors.New("Failed to unmarshal MaporSlice") -} - -func toSepMapParts(value map[interface{}]interface{}, sep string) ([]string, error) { - if len(value) == 0 { - return nil, nil - } - parts := make([]string, 0, len(value)) - for k, v := range value { - if sk, ok := k.(string); ok { - if sv, ok := v.(string); ok { - parts = append(parts, sk+sep+sv) - } else if sv, ok := v.(int); ok { - parts = append(parts, sk+sep+strconv.Itoa(sv)) - } else if sv, ok := v.(int64); ok { - parts = append(parts, sk+sep+strconv.FormatInt(sv, 10)) - } else if v == nil { - parts = append(parts, sk) - } else { - return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v) - } - } else { - return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", k, k) - } - } - return parts, nil -} - func toStrings(s []interface{}) ([]string, error) { if len(s) == 0 { return nil, nil @@ -243,12 +149,3 @@ func toStrings(s []interface{}) ([]string, error) { } return r, nil } - -func toMap(s []string, sep string) map[string]string { - m := map[string]string{} - for _, v := range s { - values := strings.Split(v, sep) - m[values[0]] = values[1] - } - return m -} diff --git a/pipeline/frontend/yaml/types/types_yaml_test.go b/pipeline/frontend/yaml/types/types_yaml_test.go new file mode 100644 index 000000000..f56735d8c --- /dev/null +++ b/pipeline/frontend/yaml/types/types_yaml_test.go @@ -0,0 +1,101 @@ +package types + +import ( + "fmt" + "testing" + + "gopkg.in/yaml.v3" + + "github.com/stretchr/testify/assert" +) + +type StructStringorInt struct { + Foo StringorInt +} + +func TestStringorIntYaml(t *testing.T) { + for _, str := range []string{`{foo: 10}`, `{foo: "10"}`} { + s := StructStringorInt{} + yaml.Unmarshal([]byte(str), &s) + + assert.Equal(t, StringorInt(10), s.Foo) + + d, err := yaml.Marshal(&s) + assert.Nil(t, err) + + s2 := StructStringorInt{} + yaml.Unmarshal(d, &s2) + + assert.Equal(t, StringorInt(10), s2.Foo) + } +} + +type StructStringorslice struct { + Foo Stringorslice +} + +func TestStringorsliceYaml(t *testing.T) { + str := `{foo: [bar, baz]}` + + s := StructStringorslice{} + yaml.Unmarshal([]byte(str), &s) + + assert.Equal(t, Stringorslice{"bar", "baz"}, s.Foo) + + d, err := yaml.Marshal(&s) + assert.Nil(t, err) + + s2 := StructStringorslice{} + yaml.Unmarshal(d, &s2) + + assert.Equal(t, Stringorslice{"bar", "baz"}, s2.Foo) +} + +type StructSliceorMap struct { + Foos SliceorMap `yaml:"foos,omitempty"` + Bars []string `yaml:"bars"` +} + +func TestSliceOrMapYaml(t *testing.T) { + str := `{foos: [bar=baz, far=faz]}` + + s := StructSliceorMap{} + yaml.Unmarshal([]byte(str), &s) + + assert.Equal(t, SliceorMap{"bar": "baz", "far": "faz"}, s.Foos) + + d, err := yaml.Marshal(&s) + assert.Nil(t, err) + + s2 := StructSliceorMap{} + yaml.Unmarshal(d, &s2) + + assert.Equal(t, SliceorMap{"bar": "baz", "far": "faz"}, s2.Foos) +} + +var sampleStructSliceorMap = ` +foos: + io.rancher.os.bar: baz + io.rancher.os.far: true +bars: [] +` + +func TestUnmarshalSliceOrMap(t *testing.T) { + s := StructSliceorMap{} + err := yaml.Unmarshal([]byte(sampleStructSliceorMap), &s) + assert.Equal(t, fmt.Errorf("Cannot unmarshal 'true' of type bool into a string value"), err) +} + +func TestStr2SliceOrMapPtrMap(t *testing.T) { + s := map[string]*StructSliceorMap{"udav": { + Foos: SliceorMap{"io.rancher.os.bar": "baz", "io.rancher.os.far": "true"}, + Bars: []string{}, + }} + d, err := yaml.Marshal(&s) + assert.Nil(t, err) + + s2 := map[string]*StructSliceorMap{} + yaml.Unmarshal(d, &s2) + + assert.Equal(t, s, s2) +} diff --git a/vendor/github.com/docker/libcompose/yaml/ulimit.go b/pipeline/frontend/yaml/types/ulimit.go similarity index 90% rename from vendor/github.com/docker/libcompose/yaml/ulimit.go rename to pipeline/frontend/yaml/types/ulimit.go index c25c49364..9981cc295 100644 --- a/vendor/github.com/docker/libcompose/yaml/ulimit.go +++ b/pipeline/frontend/yaml/types/ulimit.go @@ -1,4 +1,4 @@ -package yaml +package types import ( "errors" @@ -95,14 +95,3 @@ func (u Ulimit) MarshalYAML() (interface{}, error) { } return u.ulimitValues, nil } - -// NewUlimit creates a Ulimit based on the specified parts. -func NewUlimit(name string, soft int64, hard int64) Ulimit { - return Ulimit{ - Name: name, - ulimitValues: ulimitValues{ - Soft: soft, - Hard: hard, - }, - } -} diff --git a/pipeline/frontend/yaml/types/ulimit_test.go b/pipeline/frontend/yaml/types/ulimit_test.go new file mode 100644 index 000000000..dee76e087 --- /dev/null +++ b/pipeline/frontend/yaml/types/ulimit_test.go @@ -0,0 +1,128 @@ +package types + +import ( + "testing" + + todo_yaml "gopkg.in/yaml.v2" + "gopkg.in/yaml.v3" + + "github.com/stretchr/testify/assert" +) + +func TestMarshalUlimit(t *testing.T) { + ulimits := []struct { + ulimits *Ulimits + expected string + }{ + { + ulimits: &Ulimits{ + Elements: []Ulimit{ + { + ulimitValues: ulimitValues{ + Soft: 65535, + Hard: 65535, + }, + Name: "nproc", + }, + }, + }, + expected: `nproc: 65535 +`, + }, + { + ulimits: &Ulimits{ + Elements: []Ulimit{ + { + Name: "nofile", + ulimitValues: ulimitValues{ + Soft: 20000, + Hard: 40000, + }, + }, + }, + }, + expected: `nofile: + soft: 20000 + hard: 40000 +`, + }, + } + + for _, ulimit := range ulimits { + + bytes, err := yaml.Marshal(ulimit.ulimits) + + assert.Nil(t, err) + assert.Equal(t, ulimit.expected, string(bytes), "should be equal") + } +} + +func TestUnmarshalUlimits(t *testing.T) { + ulimits := []struct { + yaml string + expected *Ulimits + }{ + { + yaml: "nproc: 65535", + expected: &Ulimits{ + Elements: []Ulimit{ + { + Name: "nproc", + ulimitValues: ulimitValues{ + Soft: 65535, + Hard: 65535, + }, + }, + }, + }, + }, + { + yaml: `nofile: + soft: 20000 + hard: 40000`, + expected: &Ulimits{ + Elements: []Ulimit{ + { + Name: "nofile", + ulimitValues: ulimitValues{ + Soft: 20000, + Hard: 40000, + }, + }, + }, + }, + }, + { + yaml: `nproc: 65535 +nofile: + soft: 20000 + hard: 40000`, + expected: &Ulimits{ + Elements: []Ulimit{ + { + Name: "nofile", + ulimitValues: ulimitValues{ + Soft: 20000, + Hard: 40000, + }, + }, + { + Name: "nproc", + ulimitValues: ulimitValues{ + Soft: 65535, + Hard: 65535, + }, + }, + }, + }, + }, + } + + for _, ulimit := range ulimits { + actual := &Ulimits{} + err := todo_yaml.Unmarshal([]byte(ulimit.yaml), actual) + + assert.Nil(t, err) + assert.Equal(t, ulimit.expected, actual, "should be equal") + } +} diff --git a/vendor/github.com/docker/libcompose/yaml/volume.go b/pipeline/frontend/yaml/types/volume.go similarity index 99% rename from vendor/github.com/docker/libcompose/yaml/volume.go rename to pipeline/frontend/yaml/types/volume.go index 530aa6179..3dad7b364 100644 --- a/vendor/github.com/docker/libcompose/yaml/volume.go +++ b/pipeline/frontend/yaml/types/volume.go @@ -1,4 +1,4 @@ -package yaml +package types import ( "errors" diff --git a/pipeline/frontend/yaml/types/volume_test.go b/pipeline/frontend/yaml/types/volume_test.go new file mode 100644 index 000000000..f3b21f15e --- /dev/null +++ b/pipeline/frontend/yaml/types/volume_test.go @@ -0,0 +1,143 @@ +package types + +import ( + "testing" + + "gopkg.in/yaml.v3" + + "github.com/stretchr/testify/assert" +) + +func TestMarshalVolumes(t *testing.T) { + volumes := []struct { + volumes Volumes + expected string + }{ + { + volumes: Volumes{}, + expected: `[] +`, + }, + { + volumes: Volumes{ + Volumes: []*Volume{ + { + Destination: "/in/the/container", + }, + }, + }, + expected: `- /in/the/container +`, + }, + { + volumes: Volumes{ + Volumes: []*Volume{ + { + Source: "./a/path", + Destination: "/in/the/container", + AccessMode: "ro", + }, + }, + }, + expected: `- ./a/path:/in/the/container:ro +`, + }, + { + volumes: Volumes{ + Volumes: []*Volume{ + { + Source: "./a/path", + Destination: "/in/the/container", + }, + }, + }, + expected: `- ./a/path:/in/the/container +`, + }, + { + volumes: Volumes{ + Volumes: []*Volume{ + { + Source: "./a/path", + Destination: "/in/the/container", + }, + { + Source: "named", + Destination: "/in/the/container", + }, + }, + }, + expected: `- ./a/path:/in/the/container +- named:/in/the/container +`, + }, + } + for _, volume := range volumes { + bytes, err := yaml.Marshal(volume.volumes) + assert.Nil(t, err) + assert.Equal(t, volume.expected, string(bytes), "should be equal") + } +} + +func TestUnmarshalVolumes(t *testing.T) { + volumes := []struct { + yaml string + expected *Volumes + }{ + { + yaml: `- ./a/path:/in/the/container`, + expected: &Volumes{ + Volumes: []*Volume{ + { + Source: "./a/path", + Destination: "/in/the/container", + }, + }, + }, + }, + { + yaml: `- /in/the/container`, + expected: &Volumes{ + Volumes: []*Volume{ + { + Destination: "/in/the/container", + }, + }, + }, + }, + { + yaml: `- /a/path:/in/the/container:ro`, + expected: &Volumes{ + Volumes: []*Volume{ + { + Source: "/a/path", + Destination: "/in/the/container", + AccessMode: "ro", + }, + }, + }, + }, + { + yaml: `- /a/path:/in/the/container +- named:/somewhere/in/the/container`, + expected: &Volumes{ + Volumes: []*Volume{ + { + Source: "/a/path", + Destination: "/in/the/container", + }, + { + Source: "named", + Destination: "/somewhere/in/the/container", + }, + }, + }, + }, + } + for _, volume := range volumes { + actual := &Volumes{} + err := yaml.Unmarshal([]byte(volume.yaml), actual) + assert.Nil(t, err) + assert.Equal(t, volume.expected, actual, "should be equal") + } +} diff --git a/vendor/github.com/docker/libcompose/LICENSE b/vendor/github.com/docker/libcompose/LICENSE deleted file mode 100644 index 9023c749e..000000000 --- a/vendor/github.com/docker/libcompose/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Docker, Inc. - - 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. diff --git a/vendor/github.com/docker/libcompose/yaml/build.go b/vendor/github.com/docker/libcompose/yaml/build.go deleted file mode 100644 index 95d6dd5fb..000000000 --- a/vendor/github.com/docker/libcompose/yaml/build.go +++ /dev/null @@ -1,116 +0,0 @@ -package yaml - -import ( - "errors" - "fmt" - "strconv" - "strings" -) - -// Build represents a build element in compose file. -// It can take multiple form in the compose file, hence this special type -type Build struct { - Context string - Dockerfile string - Args map[string]string -} - -// MarshalYAML implements the Marshaller interface. -func (b Build) MarshalYAML() (interface{}, error) { - m := map[string]interface{}{} - if b.Context != "" { - m["context"] = b.Context - } - if b.Dockerfile != "" { - m["dockerfile"] = b.Dockerfile - } - if len(b.Args) > 0 { - m["args"] = b.Args - } - return m, nil -} - -// UnmarshalYAML implements the Unmarshaller interface. -func (b *Build) UnmarshalYAML(unmarshal func(interface{}) error) error { - var stringType string - if err := unmarshal(&stringType); err == nil { - b.Context = stringType - return nil - } - - var mapType map[interface{}]interface{} - if err := unmarshal(&mapType); err == nil { - for mapKey, mapValue := range mapType { - switch mapKey { - case "context": - b.Context = mapValue.(string) - case "dockerfile": - b.Dockerfile = mapValue.(string) - case "args": - args, err := handleBuildArgs(mapValue) - if err != nil { - return err - } - b.Args = args - default: - // Ignore unknown keys - continue - } - } - return nil - } - - return errors.New("Failed to unmarshal Build") -} - -func handleBuildArgs(value interface{}) (map[string]string, error) { - var args map[string]string - switch v := value.(type) { - case map[interface{}]interface{}: - return handleBuildArgMap(v) - case []interface{}: - return handleBuildArgSlice(v) - default: - return args, fmt.Errorf("Failed to unmarshal Build args: %#v", value) - } -} - -func handleBuildArgSlice(s []interface{}) (map[string]string, error) { - var args = map[string]string{} - for _, arg := range s { - // check if a value is provided - switch v := strings.SplitN(arg.(string), "=", 2); len(v) { - case 1: - // if we have not specified a a value for this build arg, we assign it an ascii null value and query the environment - // later when we build the service - args[v[0]] = "\x00" - case 2: - // if we do have a value provided, we use it - args[v[0]] = v[1] - } - } - return args, nil -} - -func handleBuildArgMap(m map[interface{}]interface{}) (map[string]string, error) { - args := map[string]string{} - for mapKey, mapValue := range m { - var argValue string - name, ok := mapKey.(string) - if !ok { - return args, fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name) - } - switch a := mapValue.(type) { - case string: - argValue = a - case int: - argValue = strconv.Itoa(a) - case int64: - argValue = strconv.Itoa(int(a)) - default: - return args, fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", mapValue, mapValue) - } - args[name] = argValue - } - return args, nil -} diff --git a/vendor/github.com/docker/libcompose/yaml/external.go b/vendor/github.com/docker/libcompose/yaml/external.go deleted file mode 100644 index be7efca9f..000000000 --- a/vendor/github.com/docker/libcompose/yaml/external.go +++ /dev/null @@ -1,37 +0,0 @@ -package yaml - -// External represents an external network entry in compose file. -// It can be a boolean (true|false) or have a name -type External struct { - External bool - Name string -} - -// MarshalYAML implements the Marshaller interface. -func (n External) MarshalYAML() (interface{}, error) { - if n.Name == "" { - return n.External, nil - } - return map[string]interface{}{ - "name": n.Name, - }, nil -} - -// UnmarshalYAML implements the Unmarshaller interface. -func (n *External) UnmarshalYAML(unmarshal func(interface{}) error) error { - if err := unmarshal(&n.External); err == nil { - return nil - } - var dummyExternal struct { - Name string - } - - err := unmarshal(&dummyExternal) - if err != nil { - return err - } - n.Name = dummyExternal.Name - n.External = true - - return nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 71d315c1e..6fa8a8a5a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -64,10 +64,8 @@ github.com/docker/go-connections/nat github.com/docker/go-connections/sockets github.com/docker/go-connections/tlsconfig # github.com/docker/go-units v0.4.0 -github.com/docker/go-units -# github.com/docker/libcompose v0.4.0 ## explicit -github.com/docker/libcompose/yaml +github.com/docker/go-units # github.com/drone/envsubst v1.0.3 ## explicit github.com/drone/envsubst