Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 55 additions & 6 deletions cmd/compose/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"sort"
"strings"

"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/docker/compose-cli/cli/formatter"
Expand All @@ -37,24 +38,52 @@ type psOptions struct {
All bool
Quiet bool
Services bool
Filter string
Status string
}

func (p *psOptions) parseFilter() error {
if p.Filter == "" {
return nil
}
parts := strings.SplitN(p.Filter, "=", 2)
if len(parts) != 2 {
return errors.New("arguments to --filter should be in form KEY=VAL")
}
switch parts[0] {
case "status":
p.Status = parts[1]
case "source":
return api.ErrNotImplemented
default:
return fmt.Errorf("unknow filter %s", parts[0])
}
return nil
}

func psCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := psOptions{
projectOptions: p,
}
psCmd := &cobra.Command{
cmd := &cobra.Command{
Use: "ps",
Short: "List containers",
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.parseFilter()
},
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPs(ctx, backend, args, opts)
}),
}
psCmd.Flags().StringVar(&opts.Format, "format", "pretty", "Format the output. Values: [pretty | json].")
psCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs")
psCmd.Flags().BoolVar(&opts.Services, "services", false, "Display services")
psCmd.Flags().BoolVarP(&opts.All, "all", "a", false, "Show all stopped containers (including those created by the run command)")
return psCmd
flags := cmd.Flags()
flags.StringVar(&opts.Format, "format", "pretty", "Format the output. Values: [pretty | json]")
flags.StringVar(&opts.Filter, "filter", "", "Filter services by a property")
flags.StringVar(&opts.Status, "status", "", "Filter services by status")
flags.BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs")
flags.BoolVar(&opts.Services, "services", false, "Display services")
flags.BoolVarP(&opts.All, "all", "a", false, "Show all stopped containers (including those created by the run command)")
flags.Lookup("filter").Hidden = true
return cmd
}

func runPs(ctx context.Context, backend api.Service, services []string, opts psOptions) error {
Expand Down Expand Up @@ -87,6 +116,10 @@ func runPs(ctx context.Context, backend api.Service, services []string, opts psO
return nil
}

if opts.Status != "" {
containers = filterByStatus(containers, opts.Status)
}

sort.Slice(containers, func(i, j int) bool {
return containers[i].Name < containers[j].Name
})
Expand All @@ -113,3 +146,19 @@ func runPs(ctx context.Context, backend api.Service, services []string, opts psO
},
"NAME", "SERVICE", "STATUS", "PORTS")
}

func filterByStatus(containers []api.ContainerSummary, status string) []api.ContainerSummary {
hasContainerWithState := map[string]struct{}{}
for _, c := range containers {
if c.State == status {
hasContainerWithState[c.Service] = struct{}{}
}
}
var filtered []api.ContainerSummary
for _, c := range containers {
if _, ok := hasContainerWithState[c.Service]; ok {
filtered = append(filtered, c)
}
}
return filtered
}