Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 1821143

Browse files
committed
Merge pull request #140 from vdemeester/carry-pr-116
Carry pr 116 Multiple -f
2 parents 0e83b2f + 64ad96b commit 1821143

File tree

16 files changed

+265
-50
lines changed

16 files changed

+265
-50
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import (
2020
func main() {
2121
project, err := docker.NewProject(&docker.Context{
2222
Context: project.Context{
23-
ComposeFile: "docker-compose.yml",
24-
ProjectName: "my-compose",
23+
ComposeFiles: []string{"docker-compose.yml"},
24+
ProjectName: "my-compose",
2525
},
2626
})
2727

cli/command/command.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package command
22

33
import (
4+
"os"
5+
46
"github.com/codegangsta/cli"
57
"github.com/docker/libcompose/cli/app"
68
"github.com/docker/libcompose/project"
@@ -239,10 +241,10 @@ func CommonFlags() []cli.Flag {
239241
cli.BoolFlag{
240242
Name: "verbose,debug",
241243
},
242-
cli.StringFlag{
244+
cli.StringSliceFlag{
243245
Name: "file,f",
244-
Usage: "Specify an alternate compose file (default: docker-compose.yml)",
245-
Value: "docker-compose.yml",
246+
Usage: "Specify one or more alternate compose files (default: docker-compose.yml)",
247+
Value: &cli.StringSlice{},
246248
EnvVar: "COMPOSE_FILE",
247249
},
248250
cli.StringFlag{
@@ -254,7 +256,15 @@ func CommonFlags() []cli.Flag {
254256

255257
// Populate updates the specified project context based on command line arguments and subcommands.
256258
func Populate(context *project.Context, c *cli.Context) {
257-
context.ComposeFile = c.GlobalString("file")
259+
context.ComposeFiles = c.GlobalStringSlice("file")
260+
261+
if len(context.ComposeFiles) == 0 {
262+
context.ComposeFiles = []string{"docker-compose.yml"}
263+
if _, err := os.Stat("docker-compose.override.yml"); err == nil {
264+
context.ComposeFiles = append(context.ComposeFiles, "docker-compose.override.yml")
265+
}
266+
}
267+
258268
context.ProjectName = c.GlobalString("project-name")
259269

260270
if c.Command.Name == "logs" {

docker/convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func ConvertToAPI(s *Service, name string) (*dockerclient.CreateContainerOptions
4848
func volumes(c *project.ServiceConfig, ctx *Context) map[string]struct{} {
4949
volumes := make(map[string]struct{}, len(c.Volumes))
5050
for k, v := range c.Volumes {
51-
vol := ctx.ResourceLookup.ResolvePath(v, ctx.ComposeFile)
51+
vol := ctx.ResourceLookup.ResolvePath(v, ctx.ComposeFiles[0])
5252

5353
c.Volumes[k] = vol
5454
if isVolume(vol) {

docker/convert_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestParseCommand(t *testing.T) {
1919

2020
func TestParseBindsAndVolumes(t *testing.T) {
2121
ctx := &Context{}
22-
ctx.ComposeFile = "foo/docker-compose.yml"
22+
ctx.ComposeFiles = []string{"foo/docker-compose.yml"}
2323
ctx.ResourceLookup = &lookup.FileConfigLookup{}
2424

2525
abs, err := filepath.Abs(".")
@@ -34,7 +34,7 @@ func TestParseBindsAndVolumes(t *testing.T) {
3434

3535
func TestParseLabels(t *testing.T) {
3636
ctx := &Context{}
37-
ctx.ComposeFile = "foo/docker-compose.yml"
37+
ctx.ComposeFiles = []string{"foo/docker-compose.yml"}
3838
ctx.ResourceLookup = &lookup.FileConfigLookup{}
3939
bashCmd := "bash"
4040
fooLabel := "foo.label"

example/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
func main() {
1111
project, err := docker.NewProject(&docker.Context{
1212
Context: project.Context{
13-
ComposeFile: "docker-compose.yml",
14-
ProjectName: "yeah-compose",
13+
ComposeFiles: []string{"docker-compose.yml"},
14+
ProjectName: "yeah-compose",
1515
},
1616
})
1717

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
yetanother:
2+
image: busybox:latest
3+
command: top
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
simple:
2+
image: busybox:latest
3+
command: top
4+
another:
5+
image: busybox:latest
6+
command: top

integration/assets/multiple/one.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
multiple:
2+
image: tianon/true
3+
environment:
4+
- KEY1=VAL1
5+
simple:
6+
image: busybox:latest
7+
command: top
8+
another:
9+
image: busybox:latest
10+
command: top

integration/assets/multiple/two.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
multiple:
2+
image: busybox
3+
command: echo two
4+
environment:
5+
- KEY2=VAL2
6+
yetanother:
7+
image: busybox:latest
8+
command: top

integration/create_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package integration
33
import (
44
"fmt"
55
"os"
6+
"os/exec"
67

78
. "gopkg.in/check.v1"
9+
"path/filepath"
810
)
911

1012
func (s *RunSuite) TestFields(c *C) {
@@ -170,3 +172,79 @@ func (s *RunSuite) TestFieldTypeConversions(c *C) {
170172

171173
os.Unsetenv("LIMIT")
172174
}
175+
176+
func (s *RunSuite) TestMultipleComposeFilesOneTwo(c *C) {
177+
p := "multiple"
178+
cmd := exec.Command(s.command, "-f", "./assets/multiple/one.yml", "-f", "./assets/multiple/two.yml", "create")
179+
cmd.Stdout = os.Stdout
180+
cmd.Stderr = os.Stderr
181+
cmd.Stdin = os.Stdin
182+
err := cmd.Run()
183+
184+
c.Assert(err, IsNil)
185+
186+
containerNames := []string{"multiple", "simple", "another", "yetanother"}
187+
188+
for _, containerName := range containerNames {
189+
name := fmt.Sprintf("%s_%s_1", p, containerName)
190+
container := s.GetContainerByName(c, name)
191+
192+
c.Assert(container, NotNil)
193+
}
194+
195+
name := fmt.Sprintf("%s_%s_1", p, "multiple")
196+
container := s.GetContainerByName(c, name)
197+
198+
c.Assert(container.Config.Image, Equals, "busybox")
199+
c.Assert(container.Config.Cmd, DeepEquals, []string{"echo", "two"})
200+
c.Assert(container.Config.Env, DeepEquals, []string{"KEY1=VAL1", "KEY2=VAL2"})
201+
}
202+
203+
func (s *RunSuite) TestMultipleComposeFilesTwoOne(c *C) {
204+
p := "multiple"
205+
cmd := exec.Command(s.command, "-f", "./assets/multiple/two.yml", "-f", "./assets/multiple/one.yml", "create")
206+
cmd.Stdout = os.Stdout
207+
cmd.Stderr = os.Stderr
208+
cmd.Stdin = os.Stdin
209+
err := cmd.Run()
210+
211+
c.Assert(err, IsNil)
212+
213+
containerNames := []string{"multiple", "simple", "another", "yetanother"}
214+
215+
for _, containerName := range containerNames {
216+
name := fmt.Sprintf("%s_%s_1", p, containerName)
217+
container := s.GetContainerByName(c, name)
218+
219+
c.Assert(container, NotNil)
220+
}
221+
222+
name := fmt.Sprintf("%s_%s_1", p, "multiple")
223+
container := s.GetContainerByName(c, name)
224+
225+
c.Assert(container.Config.Image, Equals, "tianon/true")
226+
c.Assert(container.Config.Cmd, DeepEquals, []string{"echo", "two"})
227+
c.Assert(container.Config.Env, DeepEquals, []string{"KEY2=VAL2", "KEY1=VAL1"})
228+
}
229+
230+
func (s *RunSuite) TestDefaultMultipleComposeFiles(c *C) {
231+
p := s.RandomProject()
232+
cmd := exec.Command(filepath.Join("../../", s.command), "-p", p, "create")
233+
cmd.Stdout = os.Stdout
234+
cmd.Stderr = os.Stderr
235+
cmd.Stdin = os.Stdin
236+
cmd.Dir = "./assets/multiple-composefiles-default/"
237+
err := cmd.Run()
238+
239+
c.Assert(err, IsNil)
240+
241+
containerNames := []string{"simple", "another", "yetanother"}
242+
243+
for _, containerName := range containerNames {
244+
name := fmt.Sprintf("%s_%s_1", p, containerName)
245+
container := s.GetContainerByName(c, name)
246+
247+
c.Assert(container, NotNil)
248+
}
249+
250+
}

0 commit comments

Comments
 (0)