Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2021-08-31 19:08:07 +02:00
Родитель c944c970ab
Коммит bd5def8454
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 9858809D6F8F6E7E
243 изменённых файлов: 164 добавлений и 16223 удалений

9
.github/workflows/ci.yml поставляемый
Просмотреть файл

@ -25,9 +25,6 @@ jobs:
- name: Validate go-mod is up-to-date and license headers
run: make validate
- name: Validate imports
run: make import-restrictions
- name: Run golangci-lint
env:
BUILD_TAGS: kube,e2e
@ -60,7 +57,7 @@ jobs:
# Ensure we don't discover cross platform build issues at release time.
# Time used to build linux here is gained back in the build for local E2E step
- name: Build packages
run: make -f builder.Makefile cross cross-compose-plugin
run: make -f builder.Makefile cross
build:
name: Build
@ -99,7 +96,7 @@ jobs:
- name: Build for local E2E
env:
BUILD_TAGS: e2e
run: make -f builder.Makefile cli compose-plugin
run: make -f builder.Makefile cli
- name: E2E Test
run: make e2e-compose
run: make e2e-local

42
.github/workflows/plugin-release.yaml поставляемый
Просмотреть файл

@ -1,42 +0,0 @@
name: Releaser
on:
push:
tags:
- "v2*"
jobs:
upload-release:
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.16
uses: actions/setup-go@v2
with:
go-version: 1.16
id: go
- name: Setup docker CLI
run: |
curl https://download.docker.com/linux/static/stable/x86_64/docker-20.10.3.tgz | tar xz
sudo cp ./docker/docker /usr/bin/ && rm -rf docker && docker version
- name: Checkout code into the Go module directory
uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Build
run: make -f builder.Makefile cross-compose-plugin
- name: License
run: cp packaging/* bin/
- uses: ncipollo/release-action@v1
with:
artifacts: "bin/*"
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}

Просмотреть файл

@ -77,21 +77,6 @@ RUN --mount=target=. \
GIT_TAG=${GIT_TAG} \
make BINARY=/out/docker -f builder.Makefile cli
FROM base AS make-compose-plugin
ENV CGO_ENABLED=0
ARG TARGETOS
ARG TARGETARCH
ARG BUILD_TAGS
ARG GIT_TAG
RUN --mount=target=. \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
GOOS=${TARGETOS} \
GOARCH=${TARGETARCH} \
BUILD_TAGS=${BUILD_TAGS} \
GIT_TAG=${GIT_TAG} \
make COMPOSE_BINARY=/out/docker-compose -f builder.Makefile compose-plugin
FROM base AS make-cross
ARG BUILD_TAGS
ARG GIT_TAG
@ -100,7 +85,7 @@ RUN --mount=target=. \
--mount=type=cache,target=/root/.cache/go-build \
BUILD_TAGS=${BUILD_TAGS} \
GIT_TAG=${GIT_TAG} \
make BINARY=/out/docker COMPOSE_BINARY=/out/docker-compose -f builder.Makefile cross
make BINARY=/out/docker -f builder.Makefile cross
FROM scratch AS protos
COPY --from=make-protos /compose-cli/cli/server/protos .
@ -108,9 +93,6 @@ COPY --from=make-protos /compose-cli/cli/server/protos .
FROM scratch AS cli
COPY --from=make-cli /out/* .
FROM scratch AS compose-plugin
COPY --from=make-compose-plugin /out/* .
FROM scratch AS cross
COPY --from=make-cross /out/* .

Просмотреть файл

@ -31,7 +31,7 @@ else
TEST_FLAGS=-run $(E2E_TEST)
endif
all: cli compose-plugin
all: cli
protos: ## Generate go code from .proto files
@docker build . --target protos \
@ -44,16 +44,6 @@ cli: ## Compile the cli
--build-arg GIT_TAG=$(GIT_TAG) \
--output ./bin
compose-plugin: ## Compile the compose cli-plugin
@docker build . --target compose-plugin \
--platform local \
--build-arg BUILD_TAGS=e2e,kube \
--build-arg GIT_TAG=$(GIT_TAG) \
--output ./bin
e2e-compose: ## Run End to end local tests. Set E2E_TEST=TestName to run a single test
gotestsum $(TEST_FLAGS) ./pkg/e2e -- -count=1
e2e-local: ## Run End to end local tests. Set E2E_TEST=TestName to run a single test
gotestsum $(TEST_FLAGS) ./local/e2e/container ./local/e2e/cli-only -- -count=1

Просмотреть файл

@ -29,6 +29,8 @@ import (
"github.com/Azure/go-autorest/autorest/to"
tm "github.com/buger/goterm"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
"github.com/morikuni/aec"
@ -39,8 +41,6 @@ import (
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/progress"
)
func createACIContainers(ctx context.Context, aciContext store.AciContext, groupDefinition containerinstance.ContainerGroup) error {

Просмотреть файл

@ -21,20 +21,19 @@ import (
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance"
"github.com/Azure/go-autorest/autorest/to"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/docker/compose-cli/aci/convert"
"github.com/docker/compose-cli/aci/login"
"github.com/docker/compose-cli/api/backend"
"github.com/docker/compose-cli/api/cloud"
"github.com/docker/compose-cli/api/containers"
apicontext "github.com/docker/compose-cli/api/context"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/api/volumes"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/api/cloud"
apicontext "github.com/docker/compose-cli/api/context"
"github.com/docker/compose-cli/api/context/store"
)
const (

Просмотреть файл

@ -22,14 +22,14 @@ import (
"net/http"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/docker/compose-cli/aci/convert"
"github.com/docker/compose-cli/aci/login"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/progress"
"github.com/docker/compose-cli/utils/formatter"
)

Просмотреть файл

@ -26,6 +26,7 @@ import (
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -33,7 +34,6 @@ import (
"github.com/docker/compose-cli/aci/login"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
)
type aciContainerService struct {

Просмотреть файл

@ -24,12 +24,12 @@ import (
"github.com/AlecAivazis/survey/v2/terminal"
"github.com/Azure/azure-sdk-for-go/profiles/preview/preview/subscription/mgmt/subscription"
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-05-01/resources"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/prompt"
"github.com/hashicorp/go-uuid"
"github.com/pkg/errors"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/prompt"
)
// ContextParams options for creating ACI context

Просмотреть файл

@ -28,12 +28,12 @@ import (
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance"
"github.com/Azure/go-autorest/autorest/to"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/docker/compose-cli/aci/login"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/utils/formatter"
)

Просмотреть файл

@ -25,12 +25,12 @@ import (
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance"
"github.com/Azure/go-autorest/autorest/to"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
)
var (

Просмотреть файл

@ -22,13 +22,13 @@ import (
"strconv"
"strings"
"github.com/docker/compose-cli/aci/login"
"github.com/docker/compose-cli/pkg/api"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance"
"github.com/Azure/go-autorest/autorest/to"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/docker/compose-cli/aci/login"
)
const (

Просмотреть файл

@ -38,6 +38,7 @@ import (
"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
"github.com/Azure/azure-storage-file-go/azfile"
"github.com/Azure/go-autorest/autorest/to"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/docker/pkg/fileutils"
"github.com/prometheus/tsdb/fileutil"
"gotest.tools/v3/assert"
@ -51,7 +52,6 @@ import (
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/cli/cmd"
"github.com/docker/compose-cli/pkg/api"
. "github.com/docker/compose-cli/utils/e2e"
)

Просмотреть файл

@ -30,8 +30,9 @@ import (
"github.com/Azure/go-autorest/autorest/date"
"github.com/pkg/errors"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/internal"
"github.com/docker/compose-cli/pkg/api"
)
// UserAgentName is the default user agent used by the cli

Просмотреть файл

@ -25,7 +25,7 @@ import (
"os"
"time"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"github.com/Azure/go-autorest/autorest/adal"
"github.com/Azure/go-autorest/autorest/azure/auth"

Просмотреть файл

@ -22,17 +22,16 @@ import (
"net/http"
"strings"
"github.com/pkg/errors"
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2019-12-01/containerinstance"
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-06-01/storage"
"github.com/Azure/go-autorest/autorest/to"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
"github.com/pkg/errors"
"github.com/docker/compose-cli/aci/login"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/api/volumes"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/progress"
)
type aciVolumeService struct {

Просмотреть файл

@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"github.com/docker/compose/v2/pkg/api"
"github.com/sirupsen/logrus"
"github.com/docker/compose-cli/api/cloud"
@ -27,7 +28,6 @@ import (
"github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/api/volumes"
"github.com/docker/compose-cli/pkg/api"
)
var (

Просмотреть файл

@ -19,6 +19,8 @@ package client
import (
"context"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/backend"
"github.com/docker/compose-cli/api/cloud"
"github.com/docker/compose-cli/api/containers"
@ -27,7 +29,6 @@ import (
"github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/api/volumes"
"github.com/docker/compose-cli/pkg/api"
)
// New returns a backend client associated with current context

Просмотреть файл

@ -20,7 +20,7 @@ import (
"context"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
)
type composeService struct {

Просмотреть файл

@ -19,8 +19,9 @@ package client
import (
"context"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/pkg/api"
)
type containerService struct {

Просмотреть файл

@ -19,8 +19,9 @@ package client
import (
"context"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/pkg/api"
)
type resourceService struct {

Просмотреть файл

@ -19,8 +19,9 @@ package client
import (
"context"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/pkg/api"
)
type secretsService struct {

Просмотреть файл

@ -19,8 +19,9 @@ package client
import (
"context"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/volumes"
"github.com/docker/compose-cli/pkg/api"
)
type volumeService struct {

Просмотреть файл

@ -19,7 +19,7 @@ package cloud
import (
"context"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
)
// Service cloud specific services

Просмотреть файл

@ -24,8 +24,7 @@ import (
"path/filepath"
"reflect"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
)

Просмотреть файл

@ -22,7 +22,7 @@ import (
"os"
"testing"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"gotest.tools/v3/assert"
"gotest.tools/v3/assert/cmp"

Просмотреть файл

@ -53,10 +53,6 @@ protos:
cli:
GOOS=${GOOS} GOARCH=${GOARCH} $(GO_BUILD) $(TAGS) -o $(BINARY_WITH_EXTENSION) ./cli
.PHONY: compose-plugin
compose-plugin:
GOOS=${GOOS} GOARCH=${GOARCH} $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY_WITH_EXTENSION) ./cmd
.PHONY: cross
cross:
GOOS=linux GOARCH=amd64 $(GO_BUILD) $(TAGS) -o $(BINARY)-linux-amd64 ./cli
@ -68,17 +64,6 @@ cross:
GOOS=darwin GOARCH=arm64 $(GO_BUILD) $(TAGS) -o $(BINARY)-darwin-arm64 ./cli
GOOS=windows GOARCH=amd64 $(GO_BUILD) $(TAGS) -o $(BINARY)-windows-amd64.exe ./cli
.PHONY: cross-compose-plugin
cross-compose-plugin:
GOOS=linux GOARCH=amd64 $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-linux-amd64 ./cmd
GOOS=linux GOARCH=arm64 $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-linux-arm64 ./cmd
GOOS=linux GOARM=6 GOARCH=arm $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-linux-armv6 ./cmd
GOOS=linux GOARM=7 GOARCH=arm $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-linux-armv7 ./cmd
GOOS=linux GOARCH=s390x $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-linux-s390x ./cmd
GOOS=darwin GOARCH=amd64 $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-darwin-amd64 ./cmd
GOOS=darwin GOARCH=arm64 $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-darwin-arm64 ./cmd
GOOS=windows GOARCH=amd64 $(GO_BUILD) $(TAGS) -o $(COMPOSE_BINARY)-windows-amd64.exe ./cmd
.PHONY: test
test:
go test $(TAGS) -cover $(shell go list $(TAGS) ./... | grep -vE 'e2e')

Просмотреть файл

@ -19,13 +19,13 @@ package context
import (
"context"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/aci"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
)
func init() {

Просмотреть файл

@ -23,13 +23,13 @@ import (
"os"
"strings"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/ecs"
"github.com/docker/compose-cli/pkg/api"
)
func init() {

Просмотреть файл

@ -19,7 +19,7 @@
package context
import (
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/spf13/cobra"

Просмотреть файл

@ -23,8 +23,7 @@ import (
"sort"
"strings"
formatter2 "github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@ -69,7 +68,7 @@ func runList(cmd *cobra.Command, opts lsOpts) error {
return err
}
format := strings.ToLower(strings.ReplaceAll(opts.format, " ", ""))
if format != "" && format != formatter2.JSON && format != formatter2.PRETTY && format != formatter2.TemplateLegacyJSON {
if format != "" && format != formatter.JSON && format != formatter.PRETTY && format != formatter.TemplateLegacyJSON {
mobycli.Exec(cmd.Root())
return nil
}
@ -92,15 +91,15 @@ func runList(cmd *cobra.Command, opts lsOpts) error {
return nil
}
if opts.json || format == formatter2.JSON {
opts.format = formatter2.JSON
if opts.json || format == formatter.JSON {
opts.format = formatter.JSON
}
if format == formatter2.TemplateLegacyJSON {
opts.format = formatter2.TemplateLegacyJSON
if format == formatter.TemplateLegacyJSON {
opts.format = formatter.TemplateLegacyJSON
}
view := viewFromContextList(contexts, currentContext)
return formatter2.Print(view, opts.format, os.Stdout,
return formatter.Print(view, opts.format, os.Stdout,
func(w io.Writer) {
for _, c := range view {
contextName := c.Name

Просмотреть файл

@ -20,8 +20,7 @@ import (
"errors"
"fmt"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/hashicorp/go-multierror"
"github.com/spf13/cobra"

Просмотреть файл

@ -17,7 +17,7 @@
package context
import (
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/spf13/cobra"

Просмотреть файл

@ -20,10 +20,9 @@ import (
"context"
"fmt"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/Azure/go-autorest/autorest/to"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/pkg/errors"
"github.com/spf13/cobra"

Просмотреть файл

@ -20,14 +20,14 @@ import (
"context"
"fmt"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/pkg/api"
)
type killOpts struct {

Просмотреть файл

@ -23,9 +23,10 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/cli/mobycli"
"github.com/docker/compose-cli/pkg/api"
)
// Command returns the login command

Просмотреть файл

@ -23,8 +23,9 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/pkg/api"
)
// AzureLogoutCommand returns the azure logout command

Просмотреть файл

@ -23,12 +23,12 @@ import (
"os"
"strings"
format "github.com/docker/compose/v2/cmd/formatter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/containers"
format "github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose-cli/utils/formatter"
)

Просмотреть файл

@ -20,15 +20,15 @@ import (
"context"
"fmt"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/pkg/api"
)
type rmOpts struct {

Просмотреть файл

@ -26,11 +26,12 @@ import (
"github.com/containerd/console"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/cli/options/run"
"github.com/docker/compose-cli/pkg/progress"
)
// Command runs a container

Просмотреть файл

@ -22,8 +22,7 @@ import (
"io/ioutil"
"os"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/api/client"

Просмотреть файл

@ -20,14 +20,13 @@ import (
"context"
"fmt"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/api"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/pkg/api"
)
// StartCommand starts containers

Просмотреть файл

@ -20,14 +20,14 @@ import (
"context"
"fmt"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/pkg/api"
)
type stopOpts struct {

Просмотреть файл

@ -21,11 +21,9 @@ import (
"os"
"strings"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/spf13/cobra"
"github.com/docker/cli/cli"
"github.com/docker/compose/v2/cmd/formatter"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/cli/mobycli"
"github.com/docker/compose-cli/internal"

Просмотреть файл

@ -20,13 +20,14 @@ import (
"context"
"fmt"
format "github.com/docker/compose-cli/cmd/formatter"
format "github.com/docker/compose/v2/cmd/formatter"
"github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose-cli/aci"
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/ecs"
"github.com/docker/compose-cli/pkg/progress"
"github.com/hashicorp/go-multierror"
"github.com/spf13/cobra"

Просмотреть файл

@ -21,7 +21,7 @@ import (
"io"
"os"
formatter2 "github.com/docker/compose-cli/cmd/formatter"
formatter2 "github.com/docker/compose/v2/cmd/formatter"
"github.com/spf13/cobra"

Просмотреть файл

@ -30,6 +30,9 @@ import (
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli"
compose2 "github.com/docker/compose/v2/cmd/compose"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@ -48,10 +51,7 @@ import (
"github.com/docker/compose-cli/cli/metrics"
"github.com/docker/compose-cli/cli/mobycli"
cliopts "github.com/docker/compose-cli/cli/options"
compose2 "github.com/docker/compose-cli/cmd/compose"
"github.com/docker/compose-cli/local"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/compose"
// Backend registrations
_ "github.com/docker/compose-cli/aci"

Просмотреть файл

@ -21,7 +21,7 @@ import (
"os/exec"
"strings"
"github.com/docker/compose-cli/pkg/utils"
"github.com/docker/compose/v2/pkg/utils"
)
var managementCommands = []string{"ecs", "scan"}

Просмотреть файл

@ -20,7 +20,7 @@ import (
"os"
"strings"
"github.com/docker/compose-cli/pkg/utils"
"github.com/docker/compose/v2/pkg/utils"
)
// Track sends the tracking analytics to Docker Desktop

Просмотреть файл

@ -25,14 +25,14 @@ import (
"path/filepath"
"regexp"
"github.com/docker/compose/v2/pkg/compose"
"github.com/docker/compose/v2/pkg/utils"
"github.com/spf13/cobra"
apicontext "github.com/docker/compose-cli/api/context"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/cli/metrics"
"github.com/docker/compose-cli/cli/mobycli/resolvepath"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/compose"
"github.com/docker/compose-cli/pkg/utils"
)
var delegatedContextTypes = []string{store.DefaultContextType}

Просмотреть файл

@ -19,11 +19,11 @@ package server
import (
"context"
"github.com/docker/compose/v2/pkg/compose"
"google.golang.org/grpc"
"github.com/docker/compose-cli/cli/metrics"
"github.com/docker/compose-cli/cli/server/proxy"
"github.com/docker/compose-cli/pkg/compose"
)
var (

Просмотреть файл

@ -21,8 +21,7 @@ import (
"strings"
"testing"
"github.com/docker/compose-cli/api/resources"
"github.com/docker/compose/v2/pkg/api"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
@ -30,6 +29,7 @@ import (
"github.com/docker/compose-cli/api/client"
"github.com/docker/compose-cli/api/containers"
"github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/api/volumes"
"github.com/docker/compose-cli/cli/metrics"
@ -38,7 +38,6 @@ import (
streamsv1 "github.com/docker/compose-cli/cli/server/protos/streams/v1"
volumesv1 "github.com/docker/compose-cli/cli/server/protos/volumes/v1"
"github.com/docker/compose-cli/cli/server/proxy"
"github.com/docker/compose-cli/pkg/api"
)
func TestAllMethodsHaveCorrespondingCliCommand(t *testing.T) {

Просмотреть файл

@ -1,99 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"os"
"github.com/compose-spec/compose-go/types"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type buildOptions struct {
*projectOptions
composeOptions
quiet bool
pull bool
progress string
args []string
noCache bool
memory string
}
func buildCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := buildOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Use: "build [SERVICE...]",
Short: "Build or rebuild services",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if opts.memory != "" {
fmt.Println("WARNING --memory is ignored as not supported in buildkit.")
}
if opts.quiet {
devnull, err := os.Open(os.DevNull)
if err != nil {
return err
}
os.Stdout = devnull
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runBuild(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
cmd.Flags().BoolVarP(&opts.quiet, "quiet", "q", false, "Don't print anything to STDOUT")
cmd.Flags().BoolVar(&opts.pull, "pull", false, "Always attempt to pull a newer version of the image.")
cmd.Flags().StringVar(&opts.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "noTty")`)
cmd.Flags().StringArrayVar(&opts.args, "build-arg", []string{}, "Set build-time variables for services.")
cmd.Flags().Bool("parallel", true, "Build images in parallel. DEPRECATED")
cmd.Flags().MarkHidden("parallel") //nolint:errcheck
cmd.Flags().Bool("compress", true, "Compress the build context using gzip. DEPRECATED")
cmd.Flags().MarkHidden("compress") //nolint:errcheck
cmd.Flags().Bool("force-rm", true, "Always remove intermediate containers. DEPRECATED")
cmd.Flags().MarkHidden("force-rm") //nolint:errcheck
cmd.Flags().BoolVar(&opts.noCache, "no-cache", false, "Do not use cache when building the image")
cmd.Flags().Bool("no-rm", false, "Do not remove intermediate containers after a successful build. DEPRECATED")
cmd.Flags().MarkHidden("no-rm") //nolint:errcheck
cmd.Flags().StringVarP(&opts.memory, "memory", "m", "", "Set memory limit for the build container. Not supported on buildkit yet.")
cmd.Flags().MarkHidden("memory") //nolint:errcheck
return cmd
}
func runBuild(ctx context.Context, backend api.Service, opts buildOptions, services []string) error {
project, err := opts.toProject(services)
if err != nil {
return err
}
return backend.Build(ctx, project, api.BuildOptions{
Pull: opts.pull,
Progress: opts.progress,
Args: types.NewMappingWithEquals(opts.args),
NoCache: opts.noCache,
Quiet: opts.quiet,
Services: services,
})
}

Просмотреть файл

@ -1,48 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"strings"
"github.com/spf13/cobra"
)
// validArgsFn defines a completion func to be returned to fetch completion options
type validArgsFn func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective)
func noCompletion() validArgsFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
}
func serviceCompletion(p *projectOptions) validArgsFn {
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
project, err := p.toProject(nil)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
var serviceNames []string
for _, s := range project.ServiceNames() {
if toComplete == "" || strings.HasPrefix(s, toComplete) {
serviceNames = append(serviceNames, s)
}
}
return serviceNames, cobra.ShellCompDirectiveNoFileComp
}
}

Просмотреть файл

@ -1,289 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/sirupsen/logrus"
"github.com/compose-spec/compose-go/cli"
"github.com/compose-spec/compose-go/types"
dockercli "github.com/docker/cli/cli"
"github.com/morikuni/aec"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/compose"
)
// Command defines a compose CLI command as a func with args
type Command func(context.Context, []string) error
// Adapt a Command func to cobra library
func Adapt(fn Command) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
contextString := fmt.Sprintf("%s", ctx)
if !strings.HasSuffix(contextString, ".WithCancel") { // need to handle cancel
cancellableCtx, cancel := context.WithCancel(cmd.Context())
ctx = cancellableCtx
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGTERM, syscall.SIGINT)
go func() {
<-s
cancel()
}()
}
err := fn(ctx, args)
var composeErr compose.Error
if api.IsErrCanceled(err) || errors.Is(ctx.Err(), context.Canceled) {
err = dockercli.StatusError{
StatusCode: 130,
Status: compose.CanceledStatus,
}
}
if errors.As(err, &composeErr) {
err = dockercli.StatusError{
StatusCode: composeErr.GetMetricsFailureCategory().ExitCode,
Status: err.Error(),
}
}
return err
}
}
// Warning is a global warning to be displayed to user on command failure
var Warning string
type projectOptions struct {
ProjectName string
Profiles []string
ConfigPaths []string
WorkDir string
ProjectDir string
EnvFile string
}
// ProjectFunc does stuff within a types.Project
type ProjectFunc func(ctx context.Context, project *types.Project) error
// ProjectServicesFunc does stuff within a types.Project and a selection of services
type ProjectServicesFunc func(ctx context.Context, project *types.Project, services []string) error
// WithServices creates a cobra run command from a ProjectFunc based on configured project options and selected services
func (o *projectOptions) WithProject(fn ProjectFunc) func(cmd *cobra.Command, args []string) error {
return o.WithServices(func(ctx context.Context, project *types.Project, services []string) error {
return fn(ctx, project)
})
}
// WithServices creates a cobra run command from a ProjectFunc based on configured project options and selected services
func (o *projectOptions) WithServices(fn ProjectServicesFunc) func(cmd *cobra.Command, args []string) error {
return Adapt(func(ctx context.Context, args []string) error {
project, err := o.toProject(args)
if err != nil {
return err
}
if o.EnvFile != "" {
var services types.Services
for _, s := range project.Services {
ef := o.EnvFile
if ef != "" {
if !filepath.IsAbs(ef) {
ef = filepath.Join(project.WorkingDir, o.EnvFile)
}
if s.Labels == nil {
s.Labels = make(map[string]string)
}
s.Labels[api.EnvironmentFileLabel] = ef
services = append(services, s)
}
}
project.Services = services
}
return fn(ctx, project, args)
})
}
func (o *projectOptions) addProjectFlags(f *pflag.FlagSet) {
f.StringArrayVar(&o.Profiles, "profile", []string{}, "Specify a profile to enable")
f.StringVarP(&o.ProjectName, "project-name", "p", "", "Project name")
f.StringArrayVarP(&o.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
f.StringVar(&o.EnvFile, "env-file", "", "Specify an alternate environment file.")
f.StringVar(&o.ProjectDir, "project-directory", "", "Specify an alternate working directory\n(default: the path of the Compose file)")
f.StringVar(&o.WorkDir, "workdir", "", "DEPRECATED! USE --project-directory INSTEAD.\nSpecify an alternate working directory\n(default: the path of the Compose file)")
_ = f.MarkHidden("workdir")
}
func (o *projectOptions) toProjectName() (string, error) {
if o.ProjectName != "" {
return o.ProjectName, nil
}
project, err := o.toProject(nil)
if err != nil {
return "", err
}
return project.Name, nil
}
func (o *projectOptions) toProject(services []string, po ...cli.ProjectOptionsFn) (*types.Project, error) {
options, err := o.toProjectOptions(po...)
if err != nil {
return nil, compose.WrapComposeError(err)
}
project, err := cli.ProjectFromOptions(options)
if err != nil {
return nil, compose.WrapComposeError(err)
}
if len(services) > 0 {
s, err := project.GetServices(services...)
if err != nil {
return nil, err
}
o.Profiles = append(o.Profiles, s.GetProfiles()...)
}
if profiles, ok := options.Environment["COMPOSE_PROFILES"]; ok {
o.Profiles = append(o.Profiles, strings.Split(profiles, ",")...)
}
project.ApplyProfiles(o.Profiles)
project.WithoutUnnecessaryResources()
err = project.ForServices(services)
return project, err
}
func (o *projectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.ProjectOptions, error) {
return cli.NewProjectOptions(o.ConfigPaths,
append(po,
cli.WithEnvFile(o.EnvFile),
cli.WithDotEnv,
cli.WithOsEnv,
cli.WithWorkingDirectory(o.ProjectDir),
cli.WithConfigFileEnv,
cli.WithDefaultConfigPath,
cli.WithName(o.ProjectName))...)
}
// RootCommand returns the compose command with its child commands
func RootCommand(backend api.Service) *cobra.Command {
opts := projectOptions{}
var (
ansi string
noAnsi bool
verbose bool
)
command := &cobra.Command{
Short: "Docker Compose",
Use: "compose",
TraverseChildren: true,
// By default (no Run/RunE in parent command) for typos in subcommands, cobra displays the help of parent command but exit(0) !
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return cmd.Help()
}
_ = cmd.Help()
return dockercli.StatusError{
StatusCode: compose.CommandSyntaxFailure.ExitCode,
Status: fmt.Sprintf("unknown docker command: %q", "compose "+args[0]),
}
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
parent := cmd.Root()
parentPrerun := parent.PersistentPreRunE
if parentPrerun != nil {
err := parentPrerun(cmd, args)
if err != nil {
return err
}
}
if noAnsi {
if ansi != "auto" {
return errors.New(`cannot specify DEPRECATED "--no-ansi" and "--ansi". Please use only "--ansi"`)
}
ansi = "never"
fmt.Fprint(os.Stderr, aec.Apply("option '--no-ansi' is DEPRECATED ! Please use '--ansi' instead.\n", aec.RedF))
}
if verbose {
logrus.SetLevel(logrus.TraceLevel)
}
formatter.SetANSIMode(ansi)
if opts.WorkDir != "" {
if opts.ProjectDir != "" {
return errors.New(`cannot specify DEPRECATED "--workdir" and "--project-directory". Please use only "--project-directory" instead`)
}
opts.ProjectDir = opts.WorkDir
fmt.Fprint(os.Stderr, aec.Apply("option '--workdir' is DEPRECATED at root level! Please use '--project-directory' instead.\n", aec.RedF))
}
return nil
},
}
command.AddCommand(
upCommand(&opts, backend),
downCommand(&opts, backend),
startCommand(&opts, backend),
restartCommand(&opts, backend),
stopCommand(&opts, backend),
psCommand(&opts, backend),
listCommand(backend),
logsCommand(&opts, backend),
convertCommand(&opts, backend),
killCommand(&opts, backend),
runCommand(&opts, backend),
removeCommand(&opts, backend),
execCommand(&opts, backend),
pauseCommand(&opts, backend),
unpauseCommand(&opts, backend),
topCommand(&opts, backend),
eventsCommand(&opts, backend),
portCommand(&opts, backend),
imagesCommand(&opts, backend),
versionCommand(),
buildCommand(&opts, backend),
pushCommand(&opts, backend),
pullCommand(&opts, backend),
createCommand(&opts, backend),
copyCommand(&opts, backend),
)
command.Flags().SetInterspersed(false)
opts.addProjectFlags(command.Flags())
command.Flags().StringVar(&ansi, "ansi", "auto", `Control when to print ANSI control characters ("never"|"always"|"auto")`)
command.Flags().BoolVar(&noAnsi, "no-ansi", false, `Do not print ANSI control characters (DEPRECATED)`)
command.Flags().MarkHidden("no-ansi") //nolint:errcheck
command.Flags().BoolVar(&verbose, "verbose", false, "Show more output")
command.Flags().MarkHidden("verbose") //nolint:errcheck
return command
}

Просмотреть файл

@ -1,53 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"testing"
"github.com/compose-spec/compose-go/types"
"gotest.tools/v3/assert"
)
func TestFilterServices(t *testing.T) {
p := &types.Project{
Services: []types.ServiceConfig{
{
Name: "foo",
Links: []string{"bar"},
},
{
Name: "bar",
NetworkMode: types.NetworkModeServicePrefix + "zot",
},
{
Name: "zot",
},
{
Name: "qix",
},
},
}
err := p.ForServices([]string{"bar"})
assert.NilError(t, err)
assert.Equal(t, len(p.Services), 2)
_, err = p.GetService("bar")
assert.NilError(t, err)
_, err = p.GetService("zot")
assert.NilError(t, err)
}

Просмотреть файл

@ -1,214 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"bufio"
"context"
"fmt"
"io"
"os"
"sort"
"strings"
"github.com/cnabio/cnab-to-oci/remotes"
"github.com/compose-spec/compose-go/cli"
"github.com/compose-spec/compose-go/types"
"github.com/distribution/distribution/v3/reference"
cliconfig "github.com/docker/cli/cli/config"
"github.com/opencontainers/go-digest"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/compose"
)
type convertOptions struct {
*projectOptions
Format string
Output string
quiet bool
resolve bool
noInterpolate bool
services bool
volumes bool
profiles bool
hash string
}
var addFlagsFuncs []func(cmd *cobra.Command, opts *convertOptions)
func convertCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := convertOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Aliases: []string{"config"},
Use: "convert SERVICES",
Short: "Converts the compose file to platform's canonical format",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if opts.quiet {
devnull, err := os.Open(os.DevNull)
if err != nil {
return err
}
os.Stdout = devnull
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
if opts.services {
return runServices(opts)
}
if opts.volumes {
return runVolumes(opts)
}
if opts.hash != "" {
return runHash(opts)
}
if opts.profiles {
return runProfiles(opts, args)
}
return runConvert(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := cmd.Flags()
flags.StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]")
flags.BoolVar(&opts.resolve, "resolve-image-digests", false, "Pin image tags to digests.")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything.")
flags.BoolVar(&opts.noInterpolate, "no-interpolate", false, "Don't interpolate environment variables.")
flags.BoolVar(&opts.services, "services", false, "Print the service names, one per line.")
flags.BoolVar(&opts.volumes, "volumes", false, "Print the volume names, one per line.")
flags.BoolVar(&opts.profiles, "profiles", false, "Print the profile names, one per line.")
flags.StringVar(&opts.hash, "hash", "", "Print the service config hash, one per line.")
// add flags for hidden backends
for _, f := range addFlagsFuncs {
f(cmd, &opts)
}
return cmd
}
func runConvert(ctx context.Context, backend api.Service, opts convertOptions, services []string) error {
var json []byte
project, err := opts.toProject(services, cli.WithInterpolation(!opts.noInterpolate))
if err != nil {
return err
}
if opts.resolve {
configFile := cliconfig.LoadDefaultConfigFile(os.Stderr)
resolver := remotes.CreateResolver(configFile)
err = project.ResolveImages(func(named reference.Named) (digest.Digest, error) {
_, desc, err := resolver.Resolve(ctx, named.String())
return desc.Digest, err
})
if err != nil {
return err
}
}
json, err = backend.Convert(ctx, project, api.ConvertOptions{
Format: opts.Format,
Output: opts.Output,
})
if err != nil {
return err
}
if opts.quiet {
return nil
}
var out io.Writer = os.Stdout
if opts.Output != "" && len(json) > 0 {
file, err := os.Create(opts.Output)
if err != nil {
return err
}
out = bufio.NewWriter(file)
}
_, err = fmt.Fprint(out, string(json))
return err
}
func runServices(opts convertOptions) error {
project, err := opts.toProject(nil)
if err != nil {
return err
}
return project.WithServices(project.ServiceNames(), func(s types.ServiceConfig) error {
fmt.Println(s.Name)
return nil
})
}
func runVolumes(opts convertOptions) error {
project, err := opts.toProject(nil)
if err != nil {
return err
}
for n := range project.Volumes {
fmt.Println(n)
}
return nil
}
func runHash(opts convertOptions) error {
var services []string
if opts.hash != "*" {
services = append(services, strings.Split(opts.hash, ",")...)
}
project, err := opts.toProject(services)
if err != nil {
return err
}
for _, s := range project.Services {
hash, err := compose.ServiceHash(s)
if err != nil {
return err
}
fmt.Printf("%s %s\n", s.Name, hash)
}
return nil
}
func runProfiles(opts convertOptions, services []string) error {
set := map[string]struct{}{}
project, err := opts.toProject(services)
if err != nil {
return err
}
for _, s := range project.AllServices() {
for _, p := range s.Profiles {
set[p] = struct{}{}
}
}
profiles := make([]string, 0, len(set))
for p := range set {
profiles = append(profiles, p)
}
sort.Strings(profiles)
for _, p := range profiles {
fmt.Println(p)
}
return nil
}

Просмотреть файл

@ -1,31 +0,0 @@
// +build kube
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"github.com/spf13/cobra"
)
func init() {
addFlagsFuncs = append(addFlagsFuncs, func(cmd *cobra.Command, opts *convertOptions) {
flags := cmd.Flags()
flags.StringVar(&opts.Output, "output", "", "Save to directory")
})
}

Просмотреть файл

@ -1,89 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"errors"
"github.com/docker/cli/cli"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type copyOptions struct {
*projectOptions
source string
destination string
index int
all bool
followLink bool
copyUIDGID bool
}
func copyCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := copyOptions{
projectOptions: p,
}
copyCmd := &cobra.Command{
Use: `cp [OPTIONS] SERVICE:SRC_PATH DEST_PATH|-
docker compose cp [OPTIONS] SRC_PATH|- SERVICE:DEST_PATH`,
Short: "Copy files/folders between a service container and the local filesystem",
Args: cli.ExactArgs(2),
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if args[0] == "" {
return errors.New("source can not be empty")
}
if args[1] == "" {
return errors.New("destination can not be empty")
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
opts.source = args[0]
opts.destination = args[1]
return runCopy(ctx, backend, opts)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := copyCmd.Flags()
flags.IntVar(&opts.index, "index", 1, "Index of the container if there are multiple instances of a service [default: 1].")
flags.BoolVar(&opts.all, "all", false, "Copy to all the containers of the service.")
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")
return copyCmd
}
func runCopy(ctx context.Context, backend api.Service, opts copyOptions) error {
projects, err := opts.toProject(nil)
if err != nil {
return err
}
return backend.Copy(ctx, projects, api.CopyOptions{
Source: opts.source,
Destination: opts.destination,
All: opts.all,
Index: opts.index,
FollowLink: opts.followLink,
CopyUIDGID: opts.copyUIDGID,
})
}

Просмотреть файл

@ -1,121 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"time"
"github.com/compose-spec/compose-go/types"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type createOptions struct {
Build bool
noBuild bool
removeOrphans bool
forceRecreate bool
noRecreate bool
recreateDeps bool
noInherit bool
timeChanged bool
timeout int
quietPull bool
}
func createCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := createOptions{}
cmd := &cobra.Command{
Use: "create [SERVICE...]",
Short: "Creates containers for a service.",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if opts.Build && opts.noBuild {
return fmt.Errorf("--build and --no-build are incompatible")
}
if opts.forceRecreate && opts.noRecreate {
return fmt.Errorf("--force-recreate and --no-recreate are incompatible")
}
return nil
}),
RunE: p.WithProject(func(ctx context.Context, project *types.Project) error {
return backend.Create(ctx, project, api.CreateOptions{
RemoveOrphans: opts.removeOrphans,
Recreate: opts.recreateStrategy(),
RecreateDependencies: opts.dependenciesRecreateStrategy(),
Inherit: !opts.noInherit,
Timeout: opts.GetTimeout(),
QuietPull: false,
})
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := cmd.Flags()
flags.BoolVar(&opts.Build, "build", false, "Build images before starting containers.")
flags.BoolVar(&opts.noBuild, "no-build", false, "Don't build an image, even if it's missing.")
flags.BoolVar(&opts.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
flags.BoolVar(&opts.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
return cmd
}
func (opts createOptions) recreateStrategy() string {
if opts.noRecreate {
return api.RecreateNever
}
if opts.forceRecreate {
return api.RecreateForce
}
return api.RecreateDiverged
}
func (opts createOptions) dependenciesRecreateStrategy() string {
if opts.noRecreate {
return api.RecreateNever
}
if opts.recreateDeps {
return api.RecreateForce
}
return api.RecreateDiverged
}
func (opts createOptions) GetTimeout() *time.Duration {
if opts.timeChanged {
t := time.Duration(opts.timeout) * time.Second
return &t
}
return nil
}
func (opts createOptions) Apply(project *types.Project) {
if opts.Build {
for i, service := range project.Services {
if service.Build == nil {
continue
}
service.PullPolicy = types.PullPolicyBuild
project.Services[i] = service
}
}
if opts.noBuild {
for i, service := range project.Services {
service.Build = nil
project.Services[i] = service
}
}
}

Просмотреть файл

@ -1,94 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"time"
"github.com/compose-spec/compose-go/types"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type downOptions struct {
*projectOptions
removeOrphans bool
timeChanged bool
timeout int
volumes bool
images string
}
func downCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := downOptions{
projectOptions: p,
}
downCmd := &cobra.Command{
Use: "down",
Short: "Stop and remove containers, networks",
PreRun: func(cmd *cobra.Command, args []string) {
opts.timeChanged = cmd.Flags().Changed("timeout")
},
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if opts.images != "" {
if opts.images != "all" && opts.images != "local" {
return fmt.Errorf("invalid value for --rmi: %q", opts.images)
}
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runDown(ctx, backend, opts)
}),
ValidArgsFunction: noCompletion(),
}
flags := downCmd.Flags()
flags.BoolVar(&opts.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
flags.BoolVarP(&opts.volumes, "volumes", "v", false, " Remove named volumes declared in the `volumes` section of the Compose file and anonymous volumes attached to containers.")
flags.StringVar(&opts.images, "rmi", "", `Remove images used by services. "local" remove only images that don't have a custom tag ("local"|"all")`)
return downCmd
}
func runDown(ctx context.Context, backend api.Service, opts downOptions) error {
name := opts.ProjectName
var project *types.Project
if opts.ProjectName == "" {
p, err := opts.toProject(nil)
if err != nil {
return err
}
project = p
name = p.Name
}
var timeout *time.Duration
if opts.timeChanged {
timeoutValue := time.Duration(opts.timeout) * time.Second
timeout = &timeoutValue
}
return backend.Down(ctx, name, api.DownOptions{
RemoveOrphans: opts.removeOrphans,
Project: project,
Timeout: timeout,
Images: opts.images,
Volumes: opts.volumes,
})
}

Просмотреть файл

@ -1,81 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"encoding/json"
"fmt"
"github.com/docker/compose-cli/pkg/api"
"github.com/spf13/cobra"
)
type eventsOpts struct {
*composeOptions
json bool
}
func eventsCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := eventsOpts{
composeOptions: &composeOptions{
projectOptions: p,
},
}
cmd := &cobra.Command{
Use: "events [options] [--] [SERVICE...]",
Short: "Receive real time events from containers.",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runEvents(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
cmd.Flags().BoolVar(&opts.json, "json", false, "Output events as a stream of json objects")
return cmd
}
func runEvents(ctx context.Context, backend api.Service, opts eventsOpts, services []string) error {
project, err := opts.toProjectName()
if err != nil {
return err
}
return backend.Events(ctx, project, api.EventsOptions{
Services: services,
Consumer: func(event api.Event) error {
if opts.json {
marshal, err := json.Marshal(map[string]interface{}{
"time": event.Timestamp,
"type": "container",
"service": event.Service,
"id": event.Container,
"action": event.Status,
"attributes": event.Attributes,
})
if err != nil {
return err
}
fmt.Println(string(marshal))
} else {
fmt.Println(event)
}
return nil
},
})
}

Просмотреть файл

@ -1,125 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"os"
"github.com/containerd/console"
"github.com/docker/cli/cli"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type execOpts struct {
*composeOptions
service string
command []string
environment []string
workingDir string
noTty bool
user string
detach bool
index int
privileged bool
}
func execCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := execOpts{
composeOptions: &composeOptions{
projectOptions: p,
},
}
runCmd := &cobra.Command{
Use: "exec [options] [-e KEY=VAL...] [--] SERVICE COMMAND [ARGS...]",
Short: "Execute a command in a running container.",
Args: cobra.MinimumNArgs(2),
PreRunE: Adapt(func(ctx context.Context, args []string) error {
opts.service = args[0]
opts.command = args[1:]
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runExec(ctx, backend, opts)
}),
ValidArgsFunction: serviceCompletion(p),
}
runCmd.Flags().BoolVarP(&opts.detach, "detach", "d", false, "Detached mode: Run command in the background.")
runCmd.Flags().StringArrayVarP(&opts.environment, "env", "e", []string{}, "Set environment variables")
runCmd.Flags().IntVar(&opts.index, "index", 1, "index of the container if there are multiple instances of a service [default: 1].")
runCmd.Flags().BoolVarP(&opts.privileged, "privileged", "", false, "Give extended privileges to the process.")
runCmd.Flags().StringVarP(&opts.user, "user", "u", "", "Run the command as this user.")
runCmd.Flags().BoolVarP(&opts.noTty, "no-TTY", "T", notAtTTY(), "Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY.")
runCmd.Flags().StringVarP(&opts.workingDir, "workdir", "w", "", "Path to workdir directory for this command.")
runCmd.Flags().SetInterspersed(false)
return runCmd
}
func runExec(ctx context.Context, backend api.Service, opts execOpts) error {
project, err := opts.toProject(nil)
if err != nil {
return err
}
execOpts := api.RunOptions{
Service: opts.service,
Command: opts.command,
Environment: opts.environment,
Tty: !opts.noTty,
User: opts.user,
Privileged: opts.privileged,
Index: opts.index,
Detach: opts.detach,
WorkingDir: opts.workingDir,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
if execOpts.Tty {
con := console.Current()
if err := con.SetRaw(); err != nil {
return err
}
defer func() {
if err := con.Reset(); err != nil {
fmt.Println("Unable to close the console")
}
}()
execOpts.Stdin = con
execOpts.Stdout = con
execOpts.Stderr = con
}
exitCode, err := backend.Exec(ctx, project, execOpts)
if exitCode != 0 {
errMsg := ""
if err != nil {
errMsg = err.Error()
}
return cli.StatusError{StatusCode: exitCode, Status: errMsg}
}
return err
}

Просмотреть файл

@ -1,108 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"io"
"os"
"sort"
"strings"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/utils"
)
type imageOptions struct {
*projectOptions
Quiet bool
}
func imagesCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := imageOptions{
projectOptions: p,
}
imgCmd := &cobra.Command{
Use: "images [SERVICE...]",
Short: "List images used by the created containers",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runImages(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
imgCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs")
return imgCmd
}
func runImages(ctx context.Context, backend api.Service, opts imageOptions, services []string) error {
projectName, err := opts.toProjectName()
if err != nil {
return err
}
images, err := backend.Images(ctx, projectName, api.ImagesOptions{
Services: services,
})
if err != nil {
return err
}
if opts.Quiet {
ids := []string{}
for _, img := range images {
id := img.ID
if i := strings.IndexRune(img.ID, ':'); i >= 0 {
id = id[i+1:]
}
if !utils.StringContains(ids, id) {
ids = append(ids, id)
}
}
for _, img := range ids {
fmt.Println(img)
}
return nil
}
sort.Slice(images, func(i, j int) bool {
return images[i].ContainerName < images[j].ContainerName
})
return formatter.Print(images, formatter.PRETTY, os.Stdout,
func(w io.Writer) {
for _, img := range images {
id := stringid.TruncateID(img.ID)
size := units.HumanSizeWithPrecision(float64(img.Size), 3)
repo := img.Repository
if repo == "" {
repo = "<none>"
}
tag := img.Tag
if tag == "" {
tag = "<none>"
}
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", img.ContainerName, repo, tag, id, size)
}
},
"Container", "Repository", "Tag", "Image Id", "Size")
}

Просмотреть файл

@ -1,43 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"github.com/compose-spec/compose-go/types"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
func killCommand(p *projectOptions, backend api.Service) *cobra.Command {
var opts api.KillOptions
cmd := &cobra.Command{
Use: "kill [options] [SERVICE...]",
Short: "Force stop service containers.",
RunE: p.WithProject(func(ctx context.Context, project *types.Project) error {
return backend.Kill(ctx, project, opts)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := cmd.Flags()
flags.StringVarP(&opts.Signal, "signal", "s", "SIGKILL", "SIGNAL to send to the container.")
return cmd
}

Просмотреть файл

@ -1,114 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"io"
"os"
"strings"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/docker/cli/opts"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type lsOptions struct {
Format string
Quiet bool
All bool
Filter opts.FilterOpt
}
func listCommand(backend api.Service) *cobra.Command {
opts := lsOptions{Filter: opts.NewFilterOpt()}
lsCmd := &cobra.Command{
Use: "ls",
Short: "List running compose projects",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runList(ctx, backend, opts)
}),
ValidArgsFunction: noCompletion(),
}
lsCmd.Flags().StringVar(&opts.Format, "format", "pretty", "Format the output. Values: [pretty | json].")
lsCmd.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "Only display IDs.")
lsCmd.Flags().Var(&opts.Filter, "filter", "Filter output based on conditions provided.")
lsCmd.Flags().BoolVarP(&opts.All, "all", "a", false, "Show all stopped Compose projects")
return lsCmd
}
var acceptedListFilters = map[string]bool{
"name": true,
}
func runList(ctx context.Context, backend api.Service, opts lsOptions) error {
filters := opts.Filter.Value()
err := filters.Validate(acceptedListFilters)
if err != nil {
return err
}
stackList, err := backend.List(ctx, api.ListOptions{All: opts.All})
if err != nil {
return err
}
if opts.Quiet {
for _, s := range stackList {
fmt.Println(s.Name)
}
return nil
}
if filters.Len() > 0 {
var filtered []api.Stack
for _, s := range stackList {
if filters.Contains("name") && !filters.Match("name", s.Name) {
continue
}
filtered = append(filtered, s)
}
stackList = filtered
}
view := viewFromStackList(stackList)
return formatter.Print(view, opts.Format, os.Stdout, func(w io.Writer) {
for _, stack := range view {
_, _ = fmt.Fprintf(w, "%s\t%s\n", stack.Name, stack.Status)
}
}, "NAME", "STATUS")
}
type stackView struct {
Name string
Status string
}
func viewFromStackList(stackList []api.Stack) []stackView {
retList := make([]stackView, len(stackList))
for i, s := range stackList {
retList[i] = stackView{
Name: s.Name,
Status: strings.TrimSpace(fmt.Sprintf("%s %s", s.Status, s.Reason)),
}
}
return retList
}

Просмотреть файл

@ -1,79 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"os"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type logsOptions struct {
*projectOptions
composeOptions
follow bool
tail string
since string
until string
noColor bool
noPrefix bool
timestamps bool
}
func logsCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := logsOptions{
projectOptions: p,
}
logsCmd := &cobra.Command{
Use: "logs [SERVICE...]",
Short: "View output from containers",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runLogs(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := logsCmd.Flags()
flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output.")
flags.StringVar(&opts.since, "since", "", "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
flags.StringVar(&opts.until, "until", "", "Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
flags.BoolVar(&opts.noColor, "no-color", false, "Produce monochrome output.")
flags.BoolVar(&opts.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")
flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps.")
flags.StringVar(&opts.tail, "tail", "all", "Number of lines to show from the end of the logs for each container.")
return logsCmd
}
func runLogs(ctx context.Context, backend api.Service, opts logsOptions, services []string) error {
projectName, err := opts.toProjectName()
if err != nil {
return err
}
consumer := formatter.NewLogConsumer(ctx, os.Stdout, !opts.noColor, !opts.noPrefix)
return backend.Logs(ctx, projectName, consumer, api.LogOptions{
Services: services,
Follow: opts.follow,
Tail: opts.tail,
Since: opts.since,
Until: opts.until,
Timestamps: opts.timestamps,
})
}

Просмотреть файл

@ -1,85 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type pauseOptions struct {
*projectOptions
}
func pauseCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := pauseOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Use: "pause [SERVICE...]",
Short: "pause services",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPause(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
return cmd
}
func runPause(ctx context.Context, backend api.Service, opts pauseOptions, services []string) error {
project, err := opts.toProjectName()
if err != nil {
return err
}
return backend.Pause(ctx, project, api.PauseOptions{
Services: services,
})
}
type unpauseOptions struct {
*projectOptions
}
func unpauseCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := unpauseOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Use: "unpause [SERVICE...]",
Short: "unpause services",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runUnPause(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
return cmd
}
func runUnPause(ctx context.Context, backend api.Service, opts unpauseOptions, services []string) error {
project, err := opts.toProjectName()
if err != nil {
return err
}
return backend.UnPause(ctx, project, api.PauseOptions{
Services: services,
})
}

Просмотреть файл

@ -1,77 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"strconv"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type portOptions struct {
*projectOptions
port int
protocol string
index int
}
func portCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := portOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Use: "port [options] [--] SERVICE PRIVATE_PORT",
Short: "Print the public port for a port binding.",
Args: cobra.MinimumNArgs(2),
PreRunE: Adapt(func(ctx context.Context, args []string) error {
port, err := strconv.Atoi(args[1])
if err != nil {
return err
}
opts.port = port
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPort(ctx, backend, opts, args[0])
}),
ValidArgsFunction: serviceCompletion(p),
}
cmd.Flags().StringVar(&opts.protocol, "protocol", "tcp", "tcp or udp")
cmd.Flags().IntVar(&opts.index, "index", 1, "index of the container if service has multiple replicas")
return cmd
}
func runPort(ctx context.Context, backend api.Service, opts portOptions, service string) error {
projectName, err := opts.toProjectName()
if err != nil {
return err
}
ip, port, err := backend.Port(ctx, projectName, service, opts.port, api.PortOptions{
Protocol: opts.protocol,
Index: opts.index,
})
if err != nil {
return err
}
fmt.Printf("%s:%d\n", ip, port)
return nil
}

Просмотреть файл

@ -1,188 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
"github.com/docker/compose-cli/cmd/formatter"
formatter2 "github.com/docker/cli/cli/command/formatter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/utils"
)
type psOptions struct {
*projectOptions
Format string
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{
Use: "ps [SERVICE...]",
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)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := psCmd.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 psCmd
}
func runPs(ctx context.Context, backend api.Service, services []string, opts psOptions) error {
projectName, err := opts.toProjectName()
if err != nil {
return err
}
containers, err := backend.Ps(ctx, projectName, api.PsOptions{
All: opts.All,
Services: services,
})
if err != nil {
return err
}
if opts.Services {
services := []string{}
for _, s := range containers {
if !utils.StringContains(services, s.Service) {
services = append(services, s.Service)
}
}
fmt.Println(strings.Join(services, "\n"))
return nil
}
SERVICES:
for _, s := range services {
for _, c := range containers {
if c.Service == s {
continue SERVICES
}
}
return fmt.Errorf("no such service: %s", s)
}
if len(containers) == 0 {
return api.ErrNotFound
}
if opts.Status != "" {
containers = filterByStatus(containers, opts.Status)
}
sort.Slice(containers, func(i, j int) bool {
return containers[i].Name < containers[j].Name
})
if opts.Quiet {
for _, c := range containers {
fmt.Println(c.ID)
}
return nil
}
return formatter.Print(containers, opts.Format, os.Stdout,
writter(containers),
"NAME", "COMMAND", "SERVICE", "STATUS", "PORTS")
}
func writter(containers []api.ContainerSummary) func(w io.Writer) {
return func(w io.Writer) {
for _, container := range containers {
var ports []string
for _, p := range container.Publishers {
if p.URL == "" {
ports = append(ports, fmt.Sprintf("%d/%s", p.TargetPort, p.Protocol))
} else {
ports = append(ports, fmt.Sprintf("%s->%d/%s", p.URL, p.TargetPort, p.Protocol))
}
}
status := container.State
if status == "running" && container.Health != "" {
status = fmt.Sprintf("%s (%s)", container.State, container.Health)
} else if status == "exited" || status == "dead" {
status = fmt.Sprintf("%s (%d)", container.State, container.ExitCode)
}
command := formatter2.Ellipsis(container.Command, 20)
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", container.Name, strconv.Quote(command), container.Service, status, strings.Join(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
}

Просмотреть файл

@ -1,93 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"os"
"github.com/morikuni/aec"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/utils"
)
type pullOptions struct {
*projectOptions
composeOptions
quiet bool
parallel bool
noParallel bool
includeDeps bool
ignorePullFailures bool
}
func pullCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := pullOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Use: "pull [SERVICE...]",
Short: "Pull service images",
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if opts.noParallel {
fmt.Fprint(os.Stderr, aec.Apply("option '--no-parallel' is DEPRECATED and will be ignored.\n", aec.RedF))
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPull(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := cmd.Flags()
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Pull without printing progress information")
cmd.Flags().BoolVar(&opts.includeDeps, "include-deps", false, "Also pull services declared as dependencies")
cmd.Flags().BoolVar(&opts.parallel, "parallel", true, "DEPRECATED pull multiple images in parallel.")
flags.MarkHidden("parallel") //nolint:errcheck
cmd.Flags().BoolVar(&opts.parallel, "no-parallel", true, "DEPRECATED disable parallel pulling.")
flags.MarkHidden("no-parallel") //nolint:errcheck
cmd.Flags().BoolVar(&opts.ignorePullFailures, "ignore-pull-failures", false, "Pull what it can and ignores images with pull failures")
return cmd
}
func runPull(ctx context.Context, backend api.Service, opts pullOptions, services []string) error {
project, err := opts.toProject(services)
if err != nil {
return err
}
if !opts.includeDeps {
enabled, err := project.GetServices(services...)
if err != nil {
return err
}
for _, s := range project.Services {
if !utils.StringContains(services, s.Name) {
project.DisabledServices = append(project.DisabledServices, s)
}
}
project.Services = enabled
}
return backend.Pull(ctx, project, api.PullOptions{
Quiet: opts.quiet,
IgnoreFailures: opts.ignorePullFailures,
})
}

Просмотреть файл

@ -1,60 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type pushOptions struct {
*projectOptions
composeOptions
Ignorefailures bool
}
func pushCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := pushOptions{
projectOptions: p,
}
pushCmd := &cobra.Command{
Use: "push [SERVICE...]",
Short: "Push service images",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runPush(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
pushCmd.Flags().BoolVar(&opts.Ignorefailures, "ignore-push-failures", false, "Push what it can and ignores images with push failures")
return pushCmd
}
func runPush(ctx context.Context, backend api.Service, opts pushOptions, services []string) error {
project, err := opts.toProject(services)
if err != nil {
return err
}
return backend.Push(ctx, project, api.PushOptions{
IgnoreFailures: opts.Ignorefailures,
})
}

Просмотреть файл

@ -1,81 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"github.com/docker/compose-cli/pkg/api"
"github.com/spf13/cobra"
)
type removeOptions struct {
*projectOptions
force bool
stop bool
volumes bool
}
func removeCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := removeOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Use: "rm [SERVICE...]",
Short: "Removes stopped service containers",
Long: `Removes stopped service containers
By default, anonymous volumes attached to containers will not be removed. You
can override this with -v. To list all volumes, use "docker volume ls".
Any data which is not in a volume will be lost.`,
RunE: Adapt(func(ctx context.Context, args []string) error {
return runRemove(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
f := cmd.Flags()
f.BoolVarP(&opts.force, "force", "f", false, "Don't ask to confirm removal")
f.BoolVarP(&opts.stop, "stop", "s", false, "Stop the containers, if required, before removing")
f.BoolVarP(&opts.volumes, "volumes", "v", false, "Remove any anonymous volumes attached to containers")
f.BoolP("all", "a", false, "Deprecated - no effect")
f.MarkHidden("all") //nolint:errcheck
return cmd
}
func runRemove(ctx context.Context, backend api.Service, opts removeOptions, services []string) error {
project, err := opts.toProject(services)
if err != nil {
return err
}
if opts.stop {
err := backend.Stop(ctx, project, api.StopOptions{
Services: services,
})
if err != nil {
return err
}
}
return backend.Remove(ctx, project, api.RemoveOptions{
Services: services,
Force: opts.force,
Volumes: opts.volumes,
})
}

Просмотреть файл

@ -1,62 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"time"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type restartOptions struct {
*projectOptions
timeout int
}
func restartCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := restartOptions{
projectOptions: p,
}
restartCmd := &cobra.Command{
Use: "restart",
Short: "Restart containers",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runRestart(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := restartCmd.Flags()
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
return restartCmd
}
func runRestart(ctx context.Context, backend api.Service, opts restartOptions, services []string) error {
project, err := opts.toProject(services)
if err != nil {
return err
}
timeout := time.Duration(opts.timeout) * time.Second
return backend.Restart(ctx, project, api.RestartOptions{
Timeout: &timeout,
Services: services,
})
}

Просмотреть файл

@ -1,232 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"os"
"strings"
"github.com/compose-spec/compose-go/loader"
"github.com/compose-spec/compose-go/types"
"github.com/mattn/go-isatty"
"github.com/mattn/go-shellwords"
"github.com/spf13/cobra"
"github.com/docker/cli/cli"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/progress"
)
type runOptions struct {
*composeOptions
Service string
Command []string
environment []string
Detach bool
Remove bool
noTty bool
user string
workdir string
entrypoint string
labels []string
volumes []string
publish []string
useAliases bool
servicePorts bool
name string
noDeps bool
}
func (opts runOptions) apply(project *types.Project) error {
target, err := project.GetService(opts.Service)
if err != nil {
return err
}
if !opts.servicePorts {
target.Ports = []types.ServicePortConfig{}
}
if len(opts.publish) > 0 {
target.Ports = []types.ServicePortConfig{}
for _, p := range opts.publish {
config, err := types.ParsePortConfig(p)
if err != nil {
return err
}
target.Ports = append(target.Ports, config...)
}
}
if len(opts.volumes) > 0 {
for _, v := range opts.volumes {
volume, err := loader.ParseVolume(v)
if err != nil {
return err
}
target.Volumes = append(target.Volumes, volume)
}
}
if opts.noDeps {
for _, s := range project.Services {
if s.Name != opts.Service {
project.DisabledServices = append(project.DisabledServices, s)
}
}
project.Services = types.Services{target}
}
for i, s := range project.Services {
if s.Name == opts.Service {
project.Services[i] = target
break
}
}
return nil
}
func runCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := runOptions{
composeOptions: &composeOptions{
projectOptions: p,
},
}
cmd := &cobra.Command{
Use: "run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...] SERVICE [COMMAND] [ARGS...]",
Short: "Run a one-off command on a service.",
Args: cobra.MinimumNArgs(1),
PreRunE: Adapt(func(ctx context.Context, args []string) error {
opts.Service = args[0]
if len(args) > 1 {
opts.Command = args[1:]
}
if len(opts.publish) > 0 && opts.servicePorts {
return fmt.Errorf("--service-ports and --publish are incompatible")
}
return nil
}),
RunE: Adapt(func(ctx context.Context, args []string) error {
project, err := p.toProject([]string{opts.Service})
if err != nil {
return err
}
return runRun(ctx, backend, project, opts)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := cmd.Flags()
flags.BoolVarP(&opts.Detach, "detach", "d", false, "Run container in background and print container ID")
flags.StringArrayVarP(&opts.environment, "env", "e", []string{}, "Set environment variables")
flags.StringArrayVarP(&opts.labels, "labels", "l", []string{}, "Add or override a label")
flags.BoolVar(&opts.Remove, "rm", false, "Automatically remove the container when it exits")
flags.BoolVarP(&opts.noTty, "no-TTY", "T", notAtTTY(), "Disable pseudo-noTty allocation. By default docker compose run allocates a TTY")
flags.StringVar(&opts.name, "name", "", " Assign a name to the container")
flags.StringVarP(&opts.user, "user", "u", "", "Run as specified username or uid")
flags.StringVarP(&opts.workdir, "workdir", "w", "", "Working directory inside the container")
flags.StringVar(&opts.entrypoint, "entrypoint", "", "Override the entrypoint of the image")
flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't start linked services.")
flags.StringArrayVarP(&opts.volumes, "volumes", "v", []string{}, "Bind mount a volume.")
flags.StringArrayVarP(&opts.publish, "publish", "p", []string{}, "Publish a container's port(s) to the host.")
flags.BoolVar(&opts.useAliases, "use-aliases", false, "Use the service's network useAliases in the network(s) the container connects to.")
flags.BoolVar(&opts.servicePorts, "service-ports", false, "Run command with the service's ports enabled and mapped to the host.")
flags.SetInterspersed(false)
return cmd
}
func notAtTTY() bool {
return !isatty.IsTerminal(os.Stdout.Fd())
}
func runRun(ctx context.Context, backend api.Service, project *types.Project, opts runOptions) error {
err := opts.apply(project)
if err != nil {
return err
}
err = progress.Run(ctx, func(ctx context.Context) error {
return startDependencies(ctx, backend, *project, opts.Service)
})
if err != nil {
return err
}
var entrypoint []string
if opts.entrypoint != "" {
entrypoint, err = shellwords.Parse(opts.entrypoint)
if err != nil {
return err
}
}
labels := types.Labels{}
for _, s := range opts.labels {
parts := strings.SplitN(s, "=", 2)
if len(parts) != 2 {
return fmt.Errorf("label must be set as KEY=VALUE")
}
labels[parts[0]] = parts[1]
}
// start container and attach to container streams
runOpts := api.RunOptions{
Name: opts.name,
Service: opts.Service,
Command: opts.Command,
Detach: opts.Detach,
AutoRemove: opts.Remove,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
Tty: !opts.noTty,
WorkingDir: opts.workdir,
User: opts.user,
Environment: opts.environment,
Entrypoint: entrypoint,
Labels: labels,
UseNetworkAliases: opts.useAliases,
Index: 0,
}
exitCode, err := backend.RunOneOffContainer(ctx, project, runOpts)
if exitCode != 0 {
errMsg := ""
if err != nil {
errMsg = err.Error()
}
return cli.StatusError{StatusCode: exitCode, Status: errMsg}
}
return err
}
func startDependencies(ctx context.Context, backend api.Service, project types.Project, requestedServiceName string) error {
dependencies := types.Services{}
var requestedService types.ServiceConfig
for _, service := range project.Services {
if service.Name != requestedServiceName {
dependencies = append(dependencies, service)
} else {
requestedService = service
}
}
project.Services = dependencies
project.DisabledServices = append(project.DisabledServices, requestedService)
if err := backend.Create(ctx, &project, api.CreateOptions{}); err != nil {
return err
}
return backend.Start(ctx, &project, api.StartOptions{})
}

Просмотреть файл

@ -1,52 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"github.com/docker/compose-cli/pkg/api"
"github.com/spf13/cobra"
)
type startOptions struct {
*projectOptions
}
func startCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := startOptions{
projectOptions: p,
}
startCmd := &cobra.Command{
Use: "start [SERVICE...]",
Short: "Start services",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runStart(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
return startCmd
}
func runStart(ctx context.Context, backend api.Service, opts startOptions, services []string) error {
project, err := opts.toProject(services)
if err != nil {
return err
}
return backend.Start(ctx, project, api.StartOptions{})
}

Просмотреть файл

@ -1,70 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"time"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type stopOptions struct {
*projectOptions
timeChanged bool
timeout int
}
func stopCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := stopOptions{
projectOptions: p,
}
cmd := &cobra.Command{
Use: "stop [SERVICE...]",
Short: "Stop services",
PreRun: func(cmd *cobra.Command, args []string) {
opts.timeChanged = cmd.Flags().Changed("timeout")
},
RunE: Adapt(func(ctx context.Context, args []string) error {
return runStop(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := cmd.Flags()
flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Specify a shutdown timeout in seconds")
return cmd
}
func runStop(ctx context.Context, backend api.Service, opts stopOptions, services []string) error {
project, err := opts.toProject(services)
if err != nil {
return err
}
var timeout *time.Duration
if opts.timeChanged {
timeoutValue := time.Duration(opts.timeout) * time.Second
timeout = &timeoutValue
}
return backend.Stop(ctx, project, api.StopOptions{
Timeout: timeout,
Services: services,
})
}

Просмотреть файл

@ -1,92 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"io"
"os"
"sort"
"strings"
"text/tabwriter"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
)
type topOptions struct {
*projectOptions
}
func topCommand(p *projectOptions, backend api.Service) *cobra.Command {
opts := topOptions{
projectOptions: p,
}
topCmd := &cobra.Command{
Use: "top [SERVICES...]",
Short: "Display the running processes",
RunE: Adapt(func(ctx context.Context, args []string) error {
return runTop(ctx, backend, opts, args)
}),
ValidArgsFunction: serviceCompletion(p),
}
return topCmd
}
func runTop(ctx context.Context, backend api.Service, opts topOptions, services []string) error {
projectName, err := opts.toProjectName()
if err != nil {
return err
}
containers, err := backend.Top(ctx, projectName, services)
if err != nil {
return err
}
sort.Slice(containers, func(i, j int) bool {
return containers[i].Name < containers[j].Name
})
for _, container := range containers {
fmt.Printf("%s\n", container.Name)
err := psPrinter(os.Stdout, func(w io.Writer) {
for _, proc := range container.Processes {
info := []interface{}{}
for _, p := range proc {
info = append(info, p)
}
_, _ = fmt.Fprintf(w, strings.Repeat("%s\t", len(info))+"\n", info...)
}
fmt.Fprintln(w)
},
container.Titles...)
if err != nil {
return err
}
}
return nil
}
func psPrinter(out io.Writer, printer func(writer io.Writer), headers ...string) error {
w := tabwriter.NewWriter(out, 5, 1, 3, ' ', 0)
_, _ = fmt.Fprintln(w, strings.Join(headers, "\t"))
printer(w)
return w.Flush()
}

Просмотреть файл

@ -1,209 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"context"
"fmt"
"os"
"strconv"
"strings"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/compose-spec/compose-go/types"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/utils"
)
// composeOptions hold options common to `up` and `run` to run compose project
type composeOptions struct {
*projectOptions
}
type upOptions struct {
*composeOptions
Detach bool
Environment []string
noStart bool
noDeps bool
cascadeStop bool
exitCodeFrom string
scale []string
noColor bool
noPrefix bool
attachDependencies bool
}
func (opts upOptions) apply(project *types.Project, services []string) error {
if opts.noDeps {
enabled, err := project.GetServices(services...)
if err != nil {
return err
}
for _, s := range project.Services {
if !utils.StringContains(services, s.Name) {
project.DisabledServices = append(project.DisabledServices, s)
}
}
project.Services = enabled
}
if opts.exitCodeFrom != "" {
_, err := project.GetService(opts.exitCodeFrom)
if err != nil {
return err
}
}
for _, scale := range opts.scale {
split := strings.Split(scale, "=")
if len(split) != 2 {
return fmt.Errorf("invalid --scale option %q. Should be SERVICE=NUM", scale)
}
name := split[0]
replicas, err := strconv.Atoi(split[1])
if err != nil {
return err
}
err = setServiceScale(project, name, replicas)
if err != nil {
return err
}
}
return nil
}
func upCommand(p *projectOptions, backend api.Service) *cobra.Command {
up := upOptions{}
create := createOptions{}
upCmd := &cobra.Command{
Use: "up [SERVICE...]",
Short: "Create and start containers",
PreRun: func(cmd *cobra.Command, args []string) {
create.timeChanged = cmd.Flags().Changed("timeout")
},
PreRunE: Adapt(func(ctx context.Context, args []string) error {
if up.exitCodeFrom != "" {
up.cascadeStop = true
}
if create.Build && create.noBuild {
return fmt.Errorf("--build and --no-build are incompatible")
}
if up.Detach && (up.attachDependencies || up.cascadeStop) {
return fmt.Errorf("--detach cannot be combined with --abort-on-container-exit or --attach-dependencies")
}
if create.forceRecreate && create.noRecreate {
return fmt.Errorf("--force-recreate and --no-recreate are incompatible")
}
if create.recreateDeps && create.noRecreate {
return fmt.Errorf("--always-recreate-deps and --no-recreate are incompatible")
}
return nil
}),
RunE: p.WithServices(func(ctx context.Context, project *types.Project, services []string) error {
return runUp(ctx, backend, create, up, project, services)
}),
ValidArgsFunction: serviceCompletion(p),
}
flags := upCmd.Flags()
flags.StringArrayVarP(&up.Environment, "environment", "e", []string{}, "Environment variables")
flags.BoolVarP(&up.Detach, "detach", "d", false, "Detached mode: Run containers in the background")
flags.BoolVar(&create.Build, "build", false, "Build images before starting containers.")
flags.BoolVar(&create.noBuild, "no-build", false, "Don't build an image, even if it's missing.")
flags.BoolVar(&create.removeOrphans, "remove-orphans", false, "Remove containers for services not defined in the Compose file.")
flags.StringArrayVar(&up.scale, "scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
flags.BoolVar(&up.noColor, "no-color", false, "Produce monochrome output.")
flags.BoolVar(&up.noPrefix, "no-log-prefix", false, "Don't print prefix in logs.")
flags.BoolVar(&create.forceRecreate, "force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
flags.BoolVar(&create.noRecreate, "no-recreate", false, "If containers already exist, don't recreate them. Incompatible with --force-recreate.")
flags.BoolVar(&up.noStart, "no-start", false, "Don't start the services after creating them.")
flags.BoolVar(&up.cascadeStop, "abort-on-container-exit", false, "Stops all containers if any container was stopped. Incompatible with -d")
flags.StringVar(&up.exitCodeFrom, "exit-code-from", "", "Return the exit code of the selected service container. Implies --abort-on-container-exit")
flags.IntVarP(&create.timeout, "timeout", "t", 10, "Use this timeout in seconds for container shutdown when attached or when containers are already running.")
flags.BoolVar(&up.noDeps, "no-deps", false, "Don't start linked services.")
flags.BoolVar(&create.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.")
flags.BoolVarP(&create.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers.")
flags.BoolVar(&up.attachDependencies, "attach-dependencies", false, "Attach to dependent containers.")
flags.BoolVar(&create.quietPull, "quiet-pull", false, "Pull without printing progress information.")
return upCmd
}
func runUp(ctx context.Context, backend api.Service, createOptions createOptions, upOptions upOptions, project *types.Project, services []string) error {
if len(project.Services) == 0 {
return fmt.Errorf("no service selected")
}
createOptions.Apply(project)
err := upOptions.apply(project, services)
if err != nil {
return err
}
var consumer api.LogConsumer
if !upOptions.Detach {
consumer = formatter.NewLogConsumer(ctx, os.Stdout, !upOptions.noColor, !upOptions.noPrefix)
}
attachTo := services
if upOptions.attachDependencies {
attachTo = project.ServiceNames()
}
create := api.CreateOptions{
RemoveOrphans: createOptions.removeOrphans,
Recreate: createOptions.recreateStrategy(),
RecreateDependencies: createOptions.dependenciesRecreateStrategy(),
Inherit: !createOptions.noInherit,
Timeout: createOptions.GetTimeout(),
QuietPull: createOptions.quietPull,
}
if upOptions.noStart {
return backend.Create(ctx, project, create)
}
return backend.Up(ctx, project, api.UpOptions{
Create: create,
Start: api.StartOptions{
Attach: consumer,
AttachTo: attachTo,
ExitCodeFrom: upOptions.exitCodeFrom,
CascadeStop: upOptions.cascadeStop,
},
})
}
func setServiceScale(project *types.Project, name string, replicas int) error {
for i, s := range project.Services {
if s.Name == name {
service, err := project.GetService(name)
if err != nil {
return err
}
service.Scale = replicas
project.Services[i] = service
return nil
}
}
return fmt.Errorf("unknown service %q", name)
}

Просмотреть файл

@ -1,43 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"testing"
"github.com/compose-spec/compose-go/types"
"gotest.tools/v3/assert"
)
func TestApplyScaleOpt(t *testing.T) {
p := types.Project{
Services: []types.ServiceConfig{
{
Name: "foo",
},
{
Name: "bar",
},
},
}
opt := upOptions{scale: []string{"foo=2"}}
err := opt.apply(&p, nil)
assert.NilError(t, err)
foo, err := p.GetService("foo")
assert.NilError(t, err)
assert.Equal(t, foo.Scale, 2)
}

Просмотреть файл

@ -1,64 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package compose
import (
"fmt"
"github.com/docker/compose-cli/cmd/formatter"
"github.com/spf13/cobra"
"github.com/docker/compose-cli/internal"
)
type versionOptions struct {
format string
short bool
}
func versionCommand() *cobra.Command {
opts := versionOptions{}
cmd := &cobra.Command{
Use: "version",
Short: "Show the Docker Compose version information",
Args: cobra.MaximumNArgs(0),
Hidden: true,
RunE: func(cmd *cobra.Command, _ []string) error {
runVersion(opts)
return nil
},
}
// define flags for backward compatibility with com.docker.cli
flags := cmd.Flags()
flags.StringVarP(&opts.format, "format", "f", "", "Format the output. Values: [pretty | json]. (Default: pretty)")
flags.BoolVar(&opts.short, "short", false, "Shows only Compose's version number.")
return cmd
}
func runVersion(opts versionOptions) {
if opts.short {
fmt.Println(internal.Version)
return
}
if opts.format == formatter.JSON {
fmt.Printf(`{"version":%q}\n`, internal.Version)
return
}
fmt.Println("Docker Compose version", internal.Version)
}

Просмотреть файл

@ -1,124 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
import (
"fmt"
"os"
"strconv"
"github.com/mattn/go-isatty"
)
var names = []string{
"grey",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"white",
}
const (
// Never use ANSI codes
Never = "never"
// Always use ANSI codes
Always = "always"
// Auto detect terminal is a tty and can use ANSI codes
Auto = "auto"
)
// SetANSIMode configure formatter for colored output on ANSI-compliant console
func SetANSIMode(ansi string) {
if !useAnsi(ansi) {
nextColor = func() colorFunc {
return monochrome
}
}
}
func useAnsi(ansi string) bool {
switch ansi {
case Always:
return true
case Auto:
return isatty.IsTerminal(os.Stdout.Fd())
}
return false
}
// colorFunc use ANSI codes to render colored text on console
type colorFunc func(s string) string
var monochrome = func(s string) string {
return s
}
func ansiColor(code, s string) string {
return fmt.Sprintf("%s%s%s", ansi(code), s, ansi("0"))
}
func ansi(code string) string {
return fmt.Sprintf("\033[%sm", code)
}
func makeColorFunc(code string) colorFunc {
return func(s string) string {
return ansiColor(code, s)
}
}
var nextColor = rainbowColor
func rainbowColor() colorFunc {
return <-loop
}
var loop = make(chan colorFunc)
func init() {
colors := map[string]colorFunc{}
for i, name := range names {
colors[name] = makeColorFunc(strconv.Itoa(30 + i))
colors["intense_"+name] = makeColorFunc(strconv.Itoa(30+i) + ";1")
}
go func() {
i := 0
rainbow := []colorFunc{
colors["cyan"],
colors["yellow"],
colors["green"],
colors["magenta"],
colors["blue"],
colors["intense_cyan"],
colors["intense_yellow"],
colors["intense_green"],
colors["intense_magenta"],
colors["intense_blue"],
}
for {
loop <- rainbow[i]
i = (i + 1) % len(rainbow)
}
}()
}

Просмотреть файл

@ -1,26 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
const (
// JSON is the constant for Json formats on list commands
JSON = "json"
// TemplateLegacyJSON the legacy json formatting value using go template
TemplateLegacyJSON = "{{json.}}"
// PRETTY is the constant for default formats on list commands
PRETTY = "pretty"
)

Просмотреть файл

@ -1,73 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
import (
"fmt"
"io"
"reflect"
"strings"
"github.com/docker/compose-cli/pkg/api"
"github.com/pkg/errors"
)
// Print prints formatted lists in different formats
func Print(toJSON interface{}, format string, outWriter io.Writer, writerFn func(w io.Writer), headers ...string) error {
switch strings.ToLower(format) {
case PRETTY, "":
return PrintPrettySection(outWriter, writerFn, headers...)
case TemplateLegacyJSON:
switch reflect.TypeOf(toJSON).Kind() {
case reflect.Slice:
s := reflect.ValueOf(toJSON)
for i := 0; i < s.Len(); i++ {
obj := s.Index(i).Interface()
outJSON, err := ToJSON(obj, "", "")
if err != nil {
return err
}
_, _ = fmt.Fprint(outWriter, outJSON)
}
default:
outJSON, err := ToStandardJSON(toJSON)
if err != nil {
return err
}
_, _ = fmt.Fprintln(outWriter, outJSON)
}
case JSON:
switch reflect.TypeOf(toJSON).Kind() {
case reflect.Slice:
outJSON, err := ToJSON(toJSON, "", "")
if err != nil {
return err
}
_, _ = fmt.Fprint(outWriter, outJSON)
default:
outJSON, err := ToStandardJSON(toJSON)
if err != nil {
return err
}
_, _ = fmt.Fprintln(outWriter, outJSON)
}
default:
return errors.Wrapf(api.ErrParsingFailed, "format value %q could not be parsed", format)
}
return nil
}

Просмотреть файл

@ -1,73 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
import (
"bytes"
"fmt"
"io"
"testing"
"gotest.tools/assert"
)
type testStruct struct {
Name string
Status string
}
// Print prints formatted lists in different formats
func TestPrint(t *testing.T) {
testList := []testStruct{
{
Name: "myName1",
Status: "myStatus1",
},
{
Name: "myName2",
Status: "myStatus2",
},
}
b := &bytes.Buffer{}
assert.NilError(t, Print(testList, PRETTY, b, func(w io.Writer) {
for _, t := range testList {
_, _ = fmt.Fprintf(w, "%s\t%s\n", t.Name, t.Status)
}
}, "NAME", "STATUS"))
assert.Equal(t, b.String(), "NAME STATUS\nmyName1 myStatus1\nmyName2 myStatus2\n")
b.Reset()
assert.NilError(t, Print(testList, JSON, b, func(w io.Writer) {
for _, t := range testList {
_, _ = fmt.Fprintf(w, "%s\t%s\n", t.Name, t.Status)
}
}, "NAME", "STATUS"))
assert.Equal(t, b.String(), `[{"Name":"myName1","Status":"myStatus1"},{"Name":"myName2","Status":"myStatus2"}]
`)
b.Reset()
assert.NilError(t, Print(testList, TemplateLegacyJSON, b, func(w io.Writer) {
for _, t := range testList {
_, _ = fmt.Fprintf(w, "%s\t%s\n", t.Name, t.Status)
}
}, "NAME", "STATUS"))
json := b.String()
assert.Equal(t, json, `{"Name":"myName1","Status":"myStatus1"}
{"Name":"myName2","Status":"myStatus2"}
`)
}

Просмотреть файл

@ -1,39 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
import (
"bytes"
"encoding/json"
)
const standardIndentation = " "
// ToStandardJSON return a string with the JSON representation of the interface{}
func ToStandardJSON(i interface{}) (string, error) {
return ToJSON(i, "", standardIndentation)
}
// ToJSON return a string with the JSON representation of the interface{}
func ToJSON(i interface{}, prefix string, indentation string) (string, error) {
buffer := &bytes.Buffer{}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
encoder.SetIndent(prefix, indentation)
err := encoder.Encode(i)
return buffer.String(), err
}

Просмотреть файл

@ -1,115 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
import (
"context"
"fmt"
"io"
"strconv"
"strings"
"github.com/docker/compose-cli/pkg/api"
)
// NewLogConsumer creates a new LogConsumer
func NewLogConsumer(ctx context.Context, w io.Writer, color bool, prefix bool) api.LogConsumer {
return &logConsumer{
ctx: ctx,
presenters: map[string]*presenter{},
width: 0,
writer: w,
color: color,
prefix: prefix,
}
}
func (l *logConsumer) Register(name string) {
l.register(name)
}
func (l *logConsumer) register(name string) *presenter {
cf := monochrome
if l.color {
cf = nextColor()
}
p := &presenter{
colors: cf,
name: name,
}
l.presenters[name] = p
if l.prefix {
l.computeWidth()
for _, p := range l.presenters {
p.setPrefix(l.width)
}
}
return p
}
// Log formats a log message as received from name/container
func (l *logConsumer) Log(container, service, message string) {
if l.ctx.Err() != nil {
return
}
p, ok := l.presenters[container]
if !ok { // should have been registered, but ¯\_(ツ)_/¯
p = l.register(container)
}
for _, line := range strings.Split(message, "\n") {
fmt.Fprintf(l.writer, "%s %s\n", p.prefix, line) // nolint:errcheck
}
}
func (l *logConsumer) Status(container, msg string) {
p, ok := l.presenters[container]
if !ok {
p = l.register(container)
}
s := p.colors(fmt.Sprintf("%s %s\n", container, msg))
l.writer.Write([]byte(s)) // nolint:errcheck
}
func (l *logConsumer) computeWidth() {
width := 0
for _, p := range l.presenters {
if len(p.name) > width {
width = len(p.name)
}
}
l.width = width + 1
}
// LogConsumer consume logs from services and format them
type logConsumer struct {
ctx context.Context
presenters map[string]*presenter
width int
writer io.Writer
color bool
prefix bool
}
type presenter struct {
colors colorFunc
name string
prefix string
}
func (p *presenter) setPrefix(width int) {
p.prefix = p.colors(fmt.Sprintf("%-"+strconv.Itoa(width)+"s |", p.name))
}

Просмотреть файл

@ -1,38 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
import (
"strings"
"github.com/hashicorp/go-multierror"
)
// SetMultiErrorFormat set cli default format for multi-errors
func SetMultiErrorFormat(errs *multierror.Error) {
if errs != nil {
errs.ErrorFormat = formatErrors
}
}
func formatErrors(errs []error) string {
messages := make([]string, len(errs))
for i, err := range errs {
messages[i] = "Error: " + err.Error()
}
return strings.Join(messages, "\n")
}

Просмотреть файл

@ -1,32 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package formatter
import (
"fmt"
"io"
"strings"
"text/tabwriter"
)
// PrintPrettySection prints a tabbed section on the writer parameter
func PrintPrettySection(out io.Writer, printer func(writer io.Writer), headers ...string) error {
w := tabwriter.NewWriter(out, 20, 1, 3, ' ', 0)
_, _ = fmt.Fprintln(w, strings.Join(headers, "\t"))
printer(w)
return w.Flush()
}

Просмотреть файл

@ -1,65 +0,0 @@
/*
Copyright 2020 Docker Compose CLI authors
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.
*/
package main
import (
dockercli "github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
commands "github.com/docker/compose-cli/cmd/compose"
"github.com/docker/compose-cli/internal"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/compose"
)
func init() {
commands.Warning = "The new 'docker compose' command is currently experimental. " +
"To provide feedback or request new features please open issues at https://github.com/docker/compose-cli"
}
func main() {
plugin.Run(func(dockerCli command.Cli) *cobra.Command {
lazyInit := api.NewServiceProxy()
cmd := commands.RootCommand(lazyInit)
originalPreRun := cmd.PersistentPreRunE
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
if err := plugin.PersistentPreRunE(cmd, args); err != nil {
return err
}
lazyInit.WithService(compose.NewComposeService(dockerCli.Client(), dockerCli.ConfigFile()))
if originalPreRun != nil {
return originalPreRun(cmd, args)
}
return nil
}
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
return dockercli.StatusError{
StatusCode: compose.CommandSyntaxFailure.ExitCode,
Status: err.Error(),
}
})
return cmd
},
manager.Metadata{
SchemaVersion: "0.1.0",
Vendor: "Docker Inc.",
Version: internal.Version,
})
}

Просмотреть файл

@ -27,7 +27,8 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/docker/compose-cli/cmd/compose"
"github.com/docker/compose/v2/cmd/compose"
. "github.com/docker/compose-cli/docs/yaml"
)

Просмотреть файл

@ -21,9 +21,9 @@ import (
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/pkg/api"
)
const (

Просмотреть файл

@ -30,7 +30,7 @@ import (
"github.com/awslabs/goformation/v4/cloudformation/efs"
"github.com/awslabs/goformation/v4/cloudformation/elasticloadbalancingv2"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

Просмотреть файл

@ -6,12 +6,14 @@ package ecs
import (
context "context"
reflect "reflect"
cloudformation "github.com/aws/aws-sdk-go/service/cloudformation"
ecs "github.com/aws/aws-sdk-go/service/ecs"
secrets "github.com/docker/compose-cli/api/secrets"
compose "github.com/docker/compose-cli/pkg/api"
compose "github.com/docker/compose/v2/pkg/api"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
secrets "github.com/docker/compose-cli/api/secrets"
)
// MockAPI is a mock of API interface

Просмотреть файл

@ -21,7 +21,6 @@ import (
"fmt"
"github.com/docker/compose-cli/api/backend"
"github.com/docker/compose-cli/api/cloud"
"github.com/docker/compose-cli/api/containers"
apicontext "github.com/docker/compose-cli/api/context"
@ -29,10 +28,10 @@ import (
"github.com/docker/compose-cli/api/resources"
"github.com/docker/compose-cli/api/secrets"
"github.com/docker/compose-cli/api/volumes"
"github.com/docker/compose-cli/pkg/api"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/docker/compose/v2/pkg/api"
)
const backendType = store.EcsContextType

Просмотреть файл

@ -38,11 +38,12 @@ import (
"github.com/compose-spec/compose-go/types"
"github.com/distribution/distribution/v3/reference"
cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/compose-cli/api/config"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"github.com/opencontainers/go-digest"
"sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/kustomize/kyaml/yaml/merge2"
"github.com/docker/compose-cli/api/config"
)
func (b *ecsAPIService) Kill(ctx context.Context, project *types.Project, options api.KillOptions) error {

Просмотреть файл

@ -23,8 +23,6 @@ import (
"reflect"
"testing"
"github.com/docker/compose-cli/pkg/api"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/awslabs/goformation/v4/cloudformation"
"github.com/awslabs/goformation/v4/cloudformation/ec2"
@ -35,6 +33,7 @@ import (
"github.com/awslabs/goformation/v4/cloudformation/logs"
"github.com/compose-spec/compose-go/loader"
"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"github.com/golang/mock/gomock"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"

Просмотреть файл

@ -24,18 +24,18 @@ import (
"sort"
"strings"
"github.com/docker/compose-cli/pkg/prompt"
"github.com/AlecAivazis/survey/v2/terminal"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/prompt"
"github.com/pkg/errors"
"gopkg.in/ini.v1"
"github.com/docker/compose-cli/api/context/store"
)
func getEnvVars() ContextParams {

Просмотреть файл

@ -21,13 +21,13 @@ import (
"os"
"testing"
"github.com/docker/compose-cli/api/context/store"
"github.com/docker/compose-cli/pkg/prompt"
"github.com/docker/compose/v2/pkg/prompt"
"github.com/golang/mock/gomock"
"gotest.tools/v3/assert"
"gotest.tools/v3/fs"
"gotest.tools/v3/golden"
"github.com/docker/compose-cli/api/context/store"
)
func TestCreateContextDataFromEnv(t *testing.T) {

Просмотреть файл

@ -19,10 +19,9 @@ package ecs
import (
"context"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/progress"
"github.com/pkg/errors"
"github.com/docker/compose-cli/pkg/api"
"github.com/docker/compose-cli/pkg/progress"
)
func (b *ecsAPIService) Down(ctx context.Context, projectName string, options api.DownOptions) error {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше