Browse Source

Add standalone capacility

Signed-off-by: Ulysses Souza <[email protected]>
Ulysses Souza 4 years ago
parent
commit
17354fcc99
3 changed files with 56 additions and 12 deletions
  1. 24 11
      cmd/compose/compose.go
  2. 31 1
      cmd/main.go
  3. 1 0
      pkg/compose/compose.go

+ 24 - 11
cmd/compose/compose.go

@@ -25,15 +25,14 @@ import (
 	"strings"
 	"syscall"
 
-	"github.com/docker/compose/v2/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/docker/cli/cli-plugins/manager"
+	"github.com/docker/compose/v2/cmd/formatter"
 	"github.com/morikuni/aec"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 
@@ -106,7 +105,7 @@ 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
+// WithProject 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)
@@ -209,6 +208,13 @@ func (o *projectOptions) toProjectOptions(po ...cli.ProjectOptionsFn) (*cli.Proj
 			cli.WithName(o.ProjectName))...)
 }
 
+const pluginName = "compose"
+
+// RunningAsStandalone detects when running as a standalone program
+func RunningAsStandalone() bool {
+	return len(os.Args) < 2 || os.Args[1] != manager.MetadataSubcommandName && os.Args[1] != pluginName
+}
+
 // RootCommand returns the compose command with its child commands
 func RootCommand(backend api.Service) *cobra.Command {
 	opts := projectOptions{}
@@ -217,9 +223,14 @@ func RootCommand(backend api.Service) *cobra.Command {
 		noAnsi  bool
 		verbose bool
 	)
+	commandName := pluginName
+	if RunningAsStandalone() {
+		commandName = os.Args[0]
+	}
+
 	command := &cobra.Command{
 		Short:            "Docker Compose",
-		Use:              "compose",
+		Use:              commandName,
 		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 {
@@ -234,11 +245,13 @@ func RootCommand(backend api.Service) *cobra.Command {
 		},
 		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 parent != nil && parent.Name() != commandName {
+				parentPrerun := parent.PersistentPreRunE
+				if parentPrerun != nil {
+					err := parentPrerun(cmd, args)
+					if err != nil {
+						return err
+					}
 				}
 			}
 			if noAnsi {

+ 31 - 1
cmd/main.go

@@ -17,12 +17,16 @@
 package main
 
 import (
+	"fmt"
+	"os"
+
 	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"
 
+	cliFlags "github.com/docker/cli/cli/flags"
 	commands "github.com/docker/compose/v2/cmd/compose"
 	"github.com/docker/compose/v2/internal"
 	"github.com/docker/compose/v2/pkg/api"
@@ -34,7 +38,26 @@ func init() {
 		"To provide feedback or request new features please open issues at https://github.com/docker/compose"
 }
 
-func main() {
+func standaloneMain() int {
+	dockerCli, err := command.NewDockerCli()
+	if err != nil {
+		_, _ = fmt.Fprintln(os.Stderr, err)
+		return 1
+	}
+	opts := cliFlags.NewClientOptions()
+	err = dockerCli.Initialize(opts)
+	if err != nil {
+		return 1
+	}
+	lazyInit := api.NewServiceProxy().WithService(compose.NewComposeService(dockerCli.Client(), dockerCli.ConfigFile()))
+	rootCmd := commands.RootCommand(lazyInit)
+	if err := rootCmd.Execute(); err != nil {
+		return 1
+	}
+	return 0
+}
+
+func pluginMain() {
 	plugin.Run(func(dockerCli command.Cli) *cobra.Command {
 		lazyInit := api.NewServiceProxy()
 		cmd := commands.RootCommand(lazyInit)
@@ -63,3 +86,10 @@ func main() {
 			Version:       internal.Version,
 		})
 }
+
+func main() {
+	if commands.RunningAsStandalone() {
+		os.Exit(standaloneMain())
+	}
+	pluginMain()
+}

+ 1 - 0
pkg/compose/compose.go

@@ -32,6 +32,7 @@ import (
 	"github.com/sanathkr/go-yaml"
 )
 
+// Separator is used for naming components
 var Separator = "-"
 
 // NewComposeService create a local implementation of the compose.Service API