introduce ability to select service to be stopped by `compose down`

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2023-05-10 15:21:34 +02:00 committed by Nicolas De loof
parent 68c462e607
commit 93bd27a0cc
6 changed files with 28 additions and 6 deletions

View File

@ -44,7 +44,7 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
ProjectOptions: p,
}
downCmd := &cobra.Command{
Use: "down [OPTIONS]",
Use: "down [OPTIONS] [SERVICES]",
Short: "Stop and remove containers, networks",
PreRunE: AdaptCmd(func(ctx context.Context, cmd *cobra.Command, args []string) error {
opts.timeChanged = cmd.Flags().Changed("timeout")
@ -56,9 +56,8 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runDown(ctx, backend, opts)
return runDown(ctx, backend, opts, args)
}),
Args: cobra.NoArgs,
ValidArgsFunction: noCompletion(),
}
flags := downCmd.Flags()
@ -77,7 +76,7 @@ func downCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
return downCmd
}
func runDown(ctx context.Context, backend api.Service, opts downOptions) error {
func runDown(ctx context.Context, backend api.Service, opts downOptions, services []string) error {
project, name, err := opts.projectOrName()
if err != nil {
return err
@ -94,5 +93,6 @@ func runDown(ctx context.Context, backend api.Service, opts downOptions) error {
Timeout: timeout,
Images: opts.images,
Volumes: opts.volumes,
Services: services,
})
}

View File

@ -14,7 +14,7 @@ long: |-
Anonymous volumes are not removed by default. However, as they dont have a stable name, they will not be automatically
mounted by a subsequent `up`. For data that needs to persist between updates, use explicit paths as bind mounts or
named volumes.
usage: docker compose down [OPTIONS]
usage: docker compose down [OPTIONS] [SERVICES]
pname: docker compose
plink: docker_compose.yaml
options:

View File

@ -232,6 +232,8 @@ type DownOptions struct {
Images string
// Volumes remove volumes, both declared in the `volumes` section and anonymous ones
Volumes bool
// Services passed in the command line to be stopped
Services []string
}
// ConfigOptions group options of the Config API

View File

@ -44,7 +44,7 @@ func (s *composeService) Down(ctx context.Context, projectName string, options a
}, s.stdinfo())
}
func (s *composeService) down(ctx context.Context, projectName string, options api.DownOptions) error {
func (s *composeService) down(ctx context.Context, projectName string, options api.DownOptions) error { //golint:nocyclo
w := progress.ContextWriter(ctx)
resourceToRemove := false
@ -70,6 +70,9 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
}
err = InReverseDependencyOrder(ctx, project, func(c context.Context, service string) error {
if len(options.Services) > 0 && !utils.StringContains(options.Services, service) {
return nil
}
serviceContainers := containers.filter(isService(service))
err := s.removeContainers(ctx, w, serviceContainers, options.Timeout, options.Volumes)
return err

View File

@ -102,6 +102,14 @@ func TestLocalComposeUp(t *testing.T) {
res.Assert(t, icmd.Expected{Out: `compose-e2e-demo-words-1 gtardif/sentences-api latest`})
})
t.Run("down SERVICE", func(t *testing.T) {
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "web")
res := c.RunDockerComposeCmd(t, "--project-name", projectName, "ps")
assert.Assert(t, !strings.Contains(res.Combined(), "compose-e2e-demo-web-1"), res.Combined())
assert.Assert(t, strings.Contains(res.Combined(), "compose-e2e-demo-db-1"), res.Combined())
})
t.Run("down", func(t *testing.T) {
_ = c.RunDockerComposeCmd(t, "--project-name", projectName, "down")
})

View File

@ -153,6 +153,15 @@ func RemovedEvent(id string) Event {
return NewEvent(id, Done, "Removed")
}
// SkippedEvent creates a new Skipped Event
func SkippedEvent(id string, reason string) Event {
return Event{
ID: id,
Status: Warning,
StatusText: "Skipped: " + reason,
}
}
// NewEvent new event
func NewEvent(id string, status EventStatus, statusText string) Event {
return Event{