godog/cmd/godog/internal/cmd_run.go
James Cooper d52a4d3f4d
Fix version subcommand. Do not print usage if run subcommand fails. (#475)
* Fix version subcommand. Do not print usage if run subcommand fails.

* Remove newline to clean up PR diff
2022-05-20 14:18:09 +02:00

107 строки
2,2 КиБ
Go

package internal
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"syscall"
"github.com/spf13/cobra"
"github.com/cucumber/godog/internal/builder"
"github.com/cucumber/godog/internal/flags"
)
var opts flags.Options
// CreateRunCmd creates the run subcommand.
func CreateRunCmd() cobra.Command {
runCmd := cobra.Command{
Use: "run [features]",
Short: "Compiles and runs a test runner",
Long: `Compiles and runs test runner for the given feature files.
Command should be run from the directory of tested package and contain
buildable go source.`,
Example: ` godog run
godog run <feature>
godog run <feature> <feature>
Optional feature(s) to run:
dir (features/)
feature (*.feature)
scenario at specific line (*.feature:10)
If no feature arguments are supplied, godog will use "features/" by default.`,
RunE: runCmdRunFunc,
SilenceUsage: true,
}
flags.BindRunCmdFlags("", runCmd.Flags(), &opts)
return runCmd
}
func runCmdRunFunc(cmd *cobra.Command, args []string) error {
osArgs := os.Args[1:]
if len(osArgs) > 0 && osArgs[0] == "run" {
osArgs = osArgs[1:]
}
if err := buildAndRunGodog(osArgs); err != nil {
return err
}
return nil
}
func buildAndRunGodog(args []string) (err error) {
bin, err := filepath.Abs(buildOutputDefault)
if err != nil {
return err
}
if err = builder.Build(bin); err != nil {
return err
}
defer os.Remove(bin)
return runGodog(bin, args)
}
func runGodog(bin string, args []string) (err error) {
cmd := exec.Command(bin, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Env = os.Environ()
if err = cmd.Start(); err != nil {
return err
}
if err = cmd.Wait(); err == nil {
return nil
}
exiterr, ok := err.(*exec.ExitError)
if !ok {
return err
}
st, ok := exiterr.Sys().(syscall.WaitStatus)
if !ok {
return fmt.Errorf("failed to convert error to syscall wait status. original error: %w", exiterr)
}
// This works on both Unix and Windows. Although package
// syscall is generally platform dependent, WaitStatus is
// defined for both Unix and Windows and in both cases has
// an ExitStatus() method with the same signature.
if st.ExitStatus() > 0 {
return err
}
return nil
}