mirror of
https://github.com/docker/compose.git
synced 2025-07-24 06:04:57 +02:00
Implement quiet flag for ps command
This commit is contained in:
parent
28299c099d
commit
688e7e5deb
6
Makefile
6
Makefile
@ -53,7 +53,7 @@ test: ## Run unit tests
|
|||||||
@docker build . \
|
@docker build . \
|
||||||
--target test
|
--target test
|
||||||
|
|
||||||
cache-clear: # Clear the builder cache
|
cache-clear: ## Clear the builder cache
|
||||||
@docker builder prune --force --filter type=exec.cachemount --filter=unused-for=24h
|
@docker builder prune --force --filter type=exec.cachemount --filter=unused-for=24h
|
||||||
|
|
||||||
lint: ## run linter(s)
|
lint: ## run linter(s)
|
||||||
@ -62,8 +62,8 @@ lint: ## run linter(s)
|
|||||||
|
|
||||||
help: ## Show help
|
help: ## Show help
|
||||||
@echo Please specify a build target. The choices are:
|
@echo Please specify a build target. The choices are:
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
.PHONY: all protos cli cross test cache-clear lint help
|
.PHONY: all protos cli e2e-local cross test cache-clear lint help
|
||||||
|
11
README.md
11
README.md
@ -23,3 +23,14 @@ $ make
|
|||||||
```
|
```
|
||||||
|
|
||||||
If you make changes to the `.proto` files, make sure to `make protos` to generate go code.
|
If you make changes to the `.proto` files, make sure to `make protos` to generate go code.
|
||||||
|
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
To run unit tests:
|
||||||
|
|
||||||
|
```
|
||||||
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need to update a golden file simply do `go test ./... -test.update-golden`.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
@ -11,29 +12,50 @@ import (
|
|||||||
"github.com/docker/api/client"
|
"github.com/docker/api/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PsCommand lists containers
|
type psOpts struct {
|
||||||
var PsCommand = cobra.Command{
|
quiet bool
|
||||||
Use: "ps",
|
}
|
||||||
Short: "List containers",
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
// PsCommand lists containers
|
||||||
ctx := cmd.Context()
|
func PsCommand() *cobra.Command {
|
||||||
|
var opts psOpts
|
||||||
c, err := client.New(ctx)
|
cmd := &cobra.Command{
|
||||||
if err != nil {
|
Use: "ps",
|
||||||
return errors.Wrap(err, "cannot connect to backend")
|
Short: "List containers",
|
||||||
}
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return runPs(cmd.Context(), opts)
|
||||||
containers, err := c.ContainerService().List(ctx)
|
},
|
||||||
if err != nil {
|
}
|
||||||
return errors.Wrap(err, "fetch containers")
|
|
||||||
}
|
cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Only display IDs")
|
||||||
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
return cmd
|
||||||
fmt.Fprintf(w, "NAME\tIMAGE\tSTATUS\tCOMMAND\n")
|
}
|
||||||
format := "%s\t%s\t%s\t%s\n"
|
|
||||||
for _, c := range containers {
|
func runPs(ctx context.Context, opts psOpts) error {
|
||||||
fmt.Fprintf(w, format, c.ID, c.Image, c.Status, c.Command)
|
c, err := client.New(ctx)
|
||||||
}
|
if err != nil {
|
||||||
return w.Flush()
|
return errors.Wrap(err, "cannot connect to backend")
|
||||||
},
|
}
|
||||||
|
|
||||||
|
containers, err := c.ContainerService().List(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "fetch containers")
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.quiet {
|
||||||
|
for _, c := range containers {
|
||||||
|
fmt.Println(c.ID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||||
|
fmt.Fprintf(w, "NAME\tIMAGE\tSTATUS\tCOMMAND\n")
|
||||||
|
format := "%s\t%s\t%s\t%s\n"
|
||||||
|
for _, c := range containers {
|
||||||
|
fmt.Fprintf(w, format, c.ID, c.Image, c.Status, c.Command)
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.Flush()
|
||||||
}
|
}
|
||||||
|
96
cli/cmd/ps_test.go
Normal file
96
cli/cmd/ps_test.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"gotest.tools/v3/assert"
|
||||||
|
"gotest.tools/v3/golden"
|
||||||
|
|
||||||
|
apicontext "github.com/docker/api/context"
|
||||||
|
"github.com/docker/api/context/store"
|
||||||
|
_ "github.com/docker/api/example"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PsSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
ctx context.Context
|
||||||
|
writer *os.File
|
||||||
|
reader *os.File
|
||||||
|
originalStdout *os.File
|
||||||
|
storeRoot string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sut *PsSuite) BeforeTest(suiteName, testName string) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx = apicontext.WithCurrentContext(ctx, "example")
|
||||||
|
dir, err := ioutil.TempDir("", "store")
|
||||||
|
require.Nil(sut.T(), err)
|
||||||
|
s, err := store.New(
|
||||||
|
store.WithRoot(dir),
|
||||||
|
)
|
||||||
|
require.Nil(sut.T(), err)
|
||||||
|
|
||||||
|
err = s.Create("example", store.TypedContext{
|
||||||
|
Type: "example",
|
||||||
|
})
|
||||||
|
require.Nil(sut.T(), err)
|
||||||
|
|
||||||
|
sut.storeRoot = dir
|
||||||
|
|
||||||
|
ctx = store.WithContextStore(ctx, s)
|
||||||
|
sut.ctx = ctx
|
||||||
|
|
||||||
|
sut.originalStdout = os.Stdout
|
||||||
|
r, w, err := os.Pipe()
|
||||||
|
require.Nil(sut.T(), err)
|
||||||
|
|
||||||
|
os.Stdout = w
|
||||||
|
sut.writer = w
|
||||||
|
sut.reader = r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sut *PsSuite) getStdOut() string {
|
||||||
|
err := sut.writer.Close()
|
||||||
|
require.Nil(sut.T(), err)
|
||||||
|
|
||||||
|
out, _ := ioutil.ReadAll(sut.reader)
|
||||||
|
|
||||||
|
return string(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sut *PsSuite) AfterTest(suiteName, testName string) {
|
||||||
|
os.Stdout = sut.originalStdout
|
||||||
|
err := os.RemoveAll(sut.storeRoot)
|
||||||
|
require.Nil(sut.T(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sut *PsSuite) TestPs() {
|
||||||
|
opts := psOpts{
|
||||||
|
quiet: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := runPs(sut.ctx, opts)
|
||||||
|
assert.NilError(sut.T(), err)
|
||||||
|
|
||||||
|
golden.Assert(sut.T(), sut.getStdOut(), "ps-out.golden")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sut *PsSuite) TestPsQuiet() {
|
||||||
|
opts := psOpts{
|
||||||
|
quiet: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := runPs(sut.ctx, opts)
|
||||||
|
assert.NilError(sut.T(), err)
|
||||||
|
|
||||||
|
golden.Assert(sut.T(), sut.getStdOut(), "ps-out-quiet.golden")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPs(t *testing.T) {
|
||||||
|
suite.Run(t, new(PsSuite))
|
||||||
|
}
|
2
cli/cmd/testdata/ps-out-quiet.golden
vendored
Normal file
2
cli/cmd/testdata/ps-out-quiet.golden
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
id
|
||||||
|
1234
|
3
cli/cmd/testdata/ps-out.golden
vendored
Normal file
3
cli/cmd/testdata/ps-out.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
NAME IMAGE STATUS COMMAND
|
||||||
|
id nginx
|
||||||
|
1234 alpine
|
@ -96,7 +96,7 @@ func main() {
|
|||||||
|
|
||||||
root.AddCommand(
|
root.AddCommand(
|
||||||
cmd.ContextCommand(),
|
cmd.ContextCommand(),
|
||||||
&cmd.PsCommand,
|
cmd.PsCommand(),
|
||||||
cmd.ServeCommand(),
|
cmd.ServeCommand(),
|
||||||
run.Command(),
|
run.Command(),
|
||||||
cmd.ExecCommand(),
|
cmd.ExecCommand(),
|
||||||
|
1
go.mod
1
go.mod
@ -31,4 +31,5 @@ require (
|
|||||||
golang.org/x/text v0.3.2 // indirect
|
golang.org/x/text v0.3.2 // indirect
|
||||||
google.golang.org/grpc v1.29.1
|
google.golang.org/grpc v1.29.1
|
||||||
google.golang.org/protobuf v1.21.0
|
google.golang.org/protobuf v1.21.0
|
||||||
|
gotest.tools/v3 v3.0.2
|
||||||
)
|
)
|
||||||
|
@ -7,8 +7,9 @@ import (
|
|||||||
|
|
||||||
"github.com/robpike/filter"
|
"github.com/robpike/filter"
|
||||||
|
|
||||||
f "github.com/docker/api/tests/framework"
|
|
||||||
g "github.com/onsi/gomega"
|
g "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
f "github.com/docker/api/tests/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -69,6 +70,14 @@ func main() {
|
|||||||
g.Expect(lines[2]).To(g.ContainSubstring("1234 alpine"))
|
g.Expect(lines[2]).To(g.ContainSubstring("1234 alpine"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("can run quiet ps command", func() {
|
||||||
|
output := f.NewDockerCommand("ps", "-q").ExecOrDie()
|
||||||
|
lines := lines(output)
|
||||||
|
g.Expect(len(lines)).To(g.Equal(2))
|
||||||
|
g.Expect(lines[0]).To(g.Equal("id"))
|
||||||
|
g.Expect(lines[1]).To(g.Equal("1234"))
|
||||||
|
})
|
||||||
|
|
||||||
It("can run 'run' command", func() {
|
It("can run 'run' command", func() {
|
||||||
output := f.NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
|
output := f.NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
|
||||||
g.Expect(output).To(g.ContainSubstring("Running container \"nginx\" with name"))
|
g.Expect(output).To(g.ContainSubstring("Running container \"nginx\" with name"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user