Browse Source

Adapt cli/mobycli to avoid duplicating shellout code

Signed-off-by: Guillaume Tardif <[email protected]>
Guillaume Tardif 4 years ago
parent
commit
2b1158f4c2
3 changed files with 30 additions and 84 deletions
  1. 25 20
      cli/mobycli/exec.go
  2. 5 2
      local/compose/build_win.go
  3. 0 62
      local/moby/exec.go

+ 25 - 20
cli/mobycli/exec.go

@@ -62,18 +62,40 @@ func mustDelegateToMoby(ctxType string) bool {
 
 // Exec delegates to com.docker.cli if on moby context
 func Exec(root *cobra.Command) {
+	childExit := make(chan bool)
+	err := RunDocker(childExit, os.Args[1:]...)
+	childExit <- true
+	if err != nil {
+		metrics.Track(store.DefaultContextType, os.Args[1:], metrics.FailureStatus)
+
+		if exiterr, ok := err.(*exec.ExitError); ok {
+			os.Exit(exiterr.ExitCode())
+		}
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+	}
+	command := metrics.GetCommand(os.Args[1:])
+	if command == "build" {
+		utils.DisplayScanSuggestMsg()
+	}
+	metrics.Track(store.DefaultContextType, os.Args[1:], metrics.SuccessStatus)
+
+	os.Exit(0)
+}
+
+// RunDocker runs a docker command, and forward signals to the shellout command (stops listening to signals when an event is sent to childExit)
+func RunDocker(childExit chan bool, args ...string) error {
 	execBinary, err := resolvepath.LookPath(ComDockerCli)
 	if err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
-	cmd := exec.Command(execBinary, os.Args[1:]...)
+	cmd := exec.Command(execBinary, args...)
 	cmd.Stdin = os.Stdin
 	cmd.Stdout = os.Stdout
 	cmd.Stderr = os.Stderr
 
 	signals := make(chan os.Signal, 1)
-	childExit := make(chan bool)
 	signal.Notify(signals) // catch all signals
 	go func() {
 		for {
@@ -90,24 +112,7 @@ func Exec(root *cobra.Command) {
 		}
 	}()
 
-	err = cmd.Run()
-	childExit <- true
-	if err != nil {
-		metrics.Track(store.DefaultContextType, os.Args[1:], metrics.FailureStatus)
-
-		if exiterr, ok := err.(*exec.ExitError); ok {
-			os.Exit(exiterr.ExitCode())
-		}
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	command := metrics.GetCommand(os.Args[1:])
-	if command == "build" {
-		utils.DisplayScanSuggestMsg()
-	}
-	metrics.Track(store.DefaultContextType, os.Args[1:], metrics.SuccessStatus)
-
-	os.Exit(0)
+	return cmd.Run()
 }
 
 // IsDefaultContextCommand checks if the command exists in the classic cli (issues a shellout --help)

+ 5 - 2
local/compose/build_win.go

@@ -22,7 +22,7 @@ import (
 	"path/filepath"
 
 	"github.com/docker/compose-cli/api/compose"
-	"github.com/docker/compose-cli/local/moby"
+	"github.com/docker/compose-cli/cli/mobycli"
 
 	"github.com/compose-spec/compose-go/types"
 )
@@ -60,7 +60,10 @@ func (s *composeService) windowsBuild(project *types.Project, options compose.Bu
 
 			args := cmd.getArguments()
 			// shell out to moby cli
-			err := moby.Exec(args)
+			childExit := make(chan bool)
+			err := mobycli.RunDocker(childExit, args...)
+			childExit <- true
+
 			if err != nil {
 				return err
 			}

+ 0 - 62
local/moby/exec.go

@@ -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 moby
-
-import (
-	"os"
-	"os/exec"
-	"os/signal"
-
-	"github.com/docker/compose-cli/cli/mobycli/resolvepath"
-)
-
-// ComDockerCli name of the classic cli binary
-const ComDockerCli = "com.docker.cli"
-
-// Exec delegates to com.docker.cli
-func Exec(args []string) error {
-	// look up the path of the classic cli binary
-	execBinary, err := resolvepath.LookPath(ComDockerCli)
-	if err != nil {
-		return err
-	}
-	cmd := exec.Command(execBinary, args...)
-	cmd.Stdin = os.Stdin
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-
-	signals := make(chan os.Signal, 1)
-	childExit := make(chan bool)
-	signal.Notify(signals) // catch all signals
-	go func() {
-		for {
-			select {
-			case sig := <-signals:
-				if cmd.Process == nil {
-					continue // can happen if receiving signal before the process is actually started
-				}
-				// nolint errcheck
-				cmd.Process.Signal(sig)
-			case <-childExit:
-				return
-			}
-		}
-	}()
-	err = cmd.Run()
-	childExit <- true
-	return err
-}