github.com/agilebits/godog@v0.7.9/cmd/godog/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"go/build"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"syscall"
    10  
    11  	"github.com/DATA-DOG/godog"
    12  	"github.com/DATA-DOG/godog/colors"
    13  )
    14  
    15  var parsedStatus int
    16  
    17  func buildAndRun() (int, error) {
    18  	var status int
    19  
    20  	bin, err := filepath.Abs("godog.test")
    21  	if err != nil {
    22  		return 1, err
    23  	}
    24  	if build.Default.GOOS == "windows" {
    25  		bin += ".exe"
    26  	}
    27  	if err = godog.Build(bin); err != nil {
    28  		return 1, err
    29  	}
    30  	defer os.Remove(bin)
    31  
    32  	cmd := exec.Command(bin, os.Args[1:]...)
    33  	cmd.Stdout = os.Stdout
    34  	cmd.Stderr = os.Stderr
    35  	cmd.Stdin = os.Stdin
    36  	cmd.Env = os.Environ()
    37  
    38  	if err = cmd.Start(); err != nil {
    39  		return status, err
    40  	}
    41  
    42  	if err = cmd.Wait(); err != nil {
    43  		if exiterr, ok := err.(*exec.ExitError); ok {
    44  			// The program has exited with an exit code != 0
    45  			status = 1
    46  
    47  			// This works on both Unix and Windows. Although package
    48  			// syscall is generally platform dependent, WaitStatus is
    49  			// defined for both Unix and Windows and in both cases has
    50  			// an ExitStatus() method with the same signature.
    51  			if st, ok := exiterr.Sys().(syscall.WaitStatus); ok {
    52  				status = st.ExitStatus()
    53  			}
    54  			return status, nil
    55  		}
    56  		return status, err
    57  	}
    58  	return status, nil
    59  }
    60  
    61  func main() {
    62  	var vers bool
    63  	var output string
    64  
    65  	opt := godog.Options{Output: colors.Colored(os.Stdout)}
    66  	flagSet := godog.FlagSet(&opt)
    67  	flagSet.BoolVar(&vers, "version", false, "Show current version.")
    68  	flagSet.StringVar(&output, "o", "", "Build and output test runner executable to given target path.")
    69  	flagSet.StringVar(&output, "output", "", "Build and output test runner executable to given target path.")
    70  
    71  	if err := flagSet.Parse(os.Args[1:]); err != nil {
    72  		fmt.Fprintln(os.Stderr, err)
    73  		os.Exit(1)
    74  	}
    75  
    76  	if len(output) > 0 {
    77  		bin, err := filepath.Abs(output)
    78  		if err != nil {
    79  			fmt.Fprintln(os.Stderr, "could not locate absolute path for:", output, err)
    80  			os.Exit(1)
    81  		}
    82  		if err = godog.Build(bin); err != nil {
    83  			fmt.Fprintln(os.Stderr, "could not build binary at:", output, err)
    84  			os.Exit(1)
    85  		}
    86  		os.Exit(0)
    87  	}
    88  
    89  	if vers {
    90  		fmt.Fprintln(os.Stdout, "Godog version is:", godog.Version)
    91  		os.Exit(0) // should it be 0?
    92  	}
    93  
    94  	status, err := buildAndRun()
    95  	if err != nil {
    96  		fmt.Fprintln(os.Stderr, err)
    97  		os.Exit(1)
    98  	}
    99  	// it might be a case, that status might not be resolved
   100  	// in some OSes. this is attempt to parse it from stderr
   101  	if parsedStatus > status {
   102  		status = parsedStatus
   103  	}
   104  	os.Exit(status)
   105  }