Added Cobra for the Command Line Interface

Этот коммит содержится в:
Fredrik Lönnblad 2020-06-27 13:31:45 +02:00
родитель e6223baaff
коммит 722d97bc48
20 изменённых файлов: 612 добавлений и 158 удалений

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

@ -240,7 +240,11 @@ var opts = godog.Options{
} }
func init() { func init() {
// godog v0.10.0 (latest) and earlier
godog.BindFlags("godog.", flag.CommandLine, &opts) godog.BindFlags("godog.", flag.CommandLine, &opts)
// godog v0.11.0
godog.BindCommandLineFlags("godog.", &opts)
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {

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

@ -14,7 +14,7 @@ import (
var opts = godog.Options{Output: colors.Colored(os.Stdout)} var opts = godog.Options{Output: colors.Colored(os.Stdout)}
func init() { func init() {
godog.BindFlags("godog.", flag.CommandLine, &opts) godog.BindCommandLineFlags("godog.", &opts)
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {

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

@ -13,7 +13,7 @@ import (
var opts = godog.Options{Output: colors.Colored(os.Stdout)} var opts = godog.Options{Output: colors.Colored(os.Stdout)}
func init() { func init() {
godog.BindFlags("godog.", flag.CommandLine, &opts) godog.BindCommandLineFlags("godog.", &opts)
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {

53
cmd/godog/internal/cmd_build.go Обычный файл
Просмотреть файл

@ -0,0 +1,53 @@
package internal
import (
"fmt"
"go/build"
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/cucumber/godog/internal/builder"
)
var buildOutput string
var buildOutputDefault = "godog.test"
// CreateBuildCmd creates the build subcommand.
func CreateBuildCmd() cobra.Command {
if build.Default.GOOS == "windows" {
buildOutputDefault += ".exe"
}
buildCmd := cobra.Command{
Use: "build",
Short: "Compiles a test runner",
Long: `Compiles a test runner. Command should be run from the directory of tested
package and contain buildable go source.
The test runner can be executed with the same flags as when using godog run.`,
Example: ` godog build
godog build -o ` + buildOutputDefault,
Run: buildCmdRunFunc,
}
buildCmd.Flags().StringVarP(&buildOutput, "output", "o", buildOutputDefault, "compiles the test runner to the named file")
return buildCmd
}
func buildCmdRunFunc(cmd *cobra.Command, args []string) {
bin, err := filepath.Abs(buildOutput)
if err != nil {
fmt.Fprintln(os.Stderr, "could not locate absolute path for:", buildOutput, err)
os.Exit(1)
}
if err = builder.Build(bin); err != nil {
fmt.Fprintln(os.Stderr, "could not build binary at:", buildOutput, err)
os.Exit(1)
}
os.Exit(0)
}

61
cmd/godog/internal/cmd_root.go Обычный файл
Просмотреть файл

@ -0,0 +1,61 @@
package internal
import (
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
"github.com/cucumber/godog/internal/flags"
)
var version bool
var output string
// CreateRootCmd creates the root command.
func CreateRootCmd() cobra.Command {
rootCmd := cobra.Command{
Use: "godog",
Long: `Creates and runs test runner for the given feature files.
Command should be run from the directory of tested package
and contain buildable go source.`,
Args: cobra.ArbitraryArgs,
// Deprecated: Use godog build, godog run or godog version.
// This is to support the legacy direct usage of the root command.
Run: func(cmd *cobra.Command, args []string) {
if version {
versionCmdRunFunc(cmd, args)
}
if len(output) > 0 {
buildOutput = output
buildCmdRunFunc(cmd, args)
}
runCmdRunFunc(cmd, args)
},
}
bindRootCmdFlags(rootCmd.Flags())
return rootCmd
}
func bindRootCmdFlags(flagSet *flag.FlagSet) {
flagSet.StringVarP(&output, "output", "o", "", "compiles the test runner to the named file")
flagSet.BoolVar(&version, "version", false, "show current version")
flags.BindRunCmdFlags("", flagSet, &opts)
// Since using the root command directly is deprecated.
// All flags will be hidden
flagSet.MarkHidden("output")
flagSet.MarkHidden("version")
flagSet.MarkHidden("no-colors")
flagSet.MarkHidden("concurrency")
flagSet.MarkHidden("tags")
flagSet.MarkHidden("format")
flagSet.MarkHidden("definitions")
flagSet.MarkHidden("stop-on-failure")
flagSet.MarkHidden("strict")
flagSet.MarkHidden("random")
}

103
cmd/godog/internal/cmd_run.go Обычный файл
Просмотреть файл

@ -0,0 +1,103 @@
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.`,
Run: runCmdRunFunc,
}
flags.BindRunCmdFlags("", runCmd.Flags(), &opts)
return runCmd
}
func runCmdRunFunc(cmd *cobra.Command, args []string) {
osArgs := os.Args[1:]
if len(osArgs) > 0 && osArgs[0] == "run" {
osArgs = osArgs[1:]
}
status, err := buildAndRunGodog(osArgs)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
os.Exit(status)
}
func buildAndRunGodog(args []string) (_ int, err error) {
bin, err := filepath.Abs(buildOutputDefault)
if err != nil {
return 1, err
}
if err = builder.Build(bin); err != nil {
return 1, err
}
defer os.Remove(bin)
return runGodog(bin, args)
}
func runGodog(bin string, args []string) (_ int, 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 0, err
}
if err = cmd.Wait(); err == nil {
return 0, nil
}
exiterr, ok := err.(*exec.ExitError)
if !ok {
return 0, err
}
// 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, ok := exiterr.Sys().(syscall.WaitStatus); ok {
return st.ExitStatus(), nil
}
return 1, nil
}

27
cmd/godog/internal/cmd_version.go Обычный файл
Просмотреть файл

@ -0,0 +1,27 @@
package internal
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/cucumber/godog"
)
// CreateVersionCmd creates the version subcommand.
func CreateVersionCmd() cobra.Command {
versionCmd := cobra.Command{
Use: "version",
Short: "Show current version",
Run: versionCmdRunFunc,
DisableFlagsInUseLine: true,
}
return versionCmd
}
func versionCmdRunFunc(cmd *cobra.Command, args []string) {
fmt.Fprintln(os.Stdout, "Godog version is:", godog.Version)
os.Exit(0)
}

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

@ -1,106 +1,15 @@
package main package main
import ( import (
"fmt" "github.com/cucumber/godog/cmd/godog/internal"
"go/build"
"os"
"os/exec"
"path/filepath"
"syscall"
"github.com/cucumber/godog"
"github.com/cucumber/godog/colors"
"github.com/cucumber/godog/internal/builder"
) )
var parsedStatus int
func buildAndRun() (int, error) {
var status int
bin, err := filepath.Abs("godog.test")
if err != nil {
return 1, err
}
if build.Default.GOOS == "windows" {
bin += ".exe"
}
if err = builder.Build(bin); err != nil {
return 1, err
}
defer os.Remove(bin)
cmd := exec.Command(bin, os.Args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Env = os.Environ()
if err = cmd.Start(); err != nil {
return status, err
}
if err = cmd.Wait(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
// The program has exited with an exit code != 0
status = 1
// 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, ok := exiterr.Sys().(syscall.WaitStatus); ok {
status = st.ExitStatus()
}
return status, nil
}
return status, err
}
return status, nil
}
func main() { func main() {
var vers bool rootCmd := internal.CreateRootCmd()
var output string buildCmd := internal.CreateBuildCmd()
runCmd := internal.CreateRunCmd()
versionCmd := internal.CreateVersionCmd()
opt := godog.Options{Output: colors.Colored(os.Stdout)} rootCmd.AddCommand(&buildCmd, &runCmd, &versionCmd)
flagSet := godog.FlagSet(&opt) rootCmd.Execute()
flagSet.BoolVar(&vers, "version", false, "Show current version.")
flagSet.StringVar(&output, "o", "", "Build and output test runner executable to given target path.")
flagSet.StringVar(&output, "output", "", "Build and output test runner executable to given target path.")
if err := flagSet.Parse(os.Args[1:]); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if len(output) > 0 {
bin, err := filepath.Abs(output)
if err != nil {
fmt.Fprintln(os.Stderr, "could not locate absolute path for:", output, err)
os.Exit(1)
}
if err = builder.Build(bin); err != nil {
fmt.Fprintln(os.Stderr, "could not build binary at:", output, err)
os.Exit(1)
}
os.Exit(0)
}
if vers {
fmt.Fprintln(os.Stdout, "Godog version is:", godog.Version)
os.Exit(0) // should it be 0?
}
status, err := buildAndRun()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// it might be a case, that status might not be resolved
// in some OSes. this is attempt to parse it from stderr
if parsedStatus > status {
status = parsedStatus
}
os.Exit(status)
} }

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

@ -4,10 +4,8 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"math/rand"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/cucumber/godog/colors" "github.com/cucumber/godog/colors"
"github.com/cucumber/godog/internal/utils" "github.com/cucumber/godog/internal/utils"
@ -39,6 +37,8 @@ var descRandomOption = "Randomly shuffle the scenario execution order.\n" +
// FlagSet allows to manage flags by external suite runner // FlagSet allows to manage flags by external suite runner
// builds flag.FlagSet with godog flags binded // builds flag.FlagSet with godog flags binded
//
// Deprecated:
func FlagSet(opt *Options) *flag.FlagSet { func FlagSet(opt *Options) *flag.FlagSet {
set := flag.NewFlagSet("godog", flag.ExitOnError) set := flag.NewFlagSet("godog", flag.ExitOnError)
BindFlags("", set, opt) BindFlags("", set, opt)
@ -48,6 +48,8 @@ func FlagSet(opt *Options) *flag.FlagSet {
// BindFlags binds godog flags to given flag set prefixed // BindFlags binds godog flags to given flag set prefixed
// by given prefix, without overriding usage // by given prefix, without overriding usage
//
// Deprecated: Use BindCommandLineFlags(prefix, &opts) instead of BindFlags(prefix, flag.CommandLine, &opts)
func BindFlags(prefix string, set *flag.FlagSet, opt *Options) { func BindFlags(prefix string, set *flag.FlagSet, opt *Options) {
descFormatOption := "How to format tests output. Built-in formats:\n" descFormatOption := "How to format tests output. Built-in formats:\n"
// @TODO: sort by name // @TODO: sort by name
@ -61,26 +63,32 @@ func BindFlags(prefix string, set *flag.FlagSet, opt *Options) {
if opt.Format != "" { if opt.Format != "" {
defFormatOption = opt.Format defFormatOption = opt.Format
} }
defTagsOption := "" defTagsOption := ""
if opt.Tags != "" { if opt.Tags != "" {
defTagsOption = opt.Tags defTagsOption = opt.Tags
} }
defConcurrencyOption := 1 defConcurrencyOption := 1
if opt.Concurrency != 0 { if opt.Concurrency != 0 {
defConcurrencyOption = opt.Concurrency defConcurrencyOption = opt.Concurrency
} }
defShowStepDefinitions := false defShowStepDefinitions := false
if opt.ShowStepDefinitions { if opt.ShowStepDefinitions {
defShowStepDefinitions = opt.ShowStepDefinitions defShowStepDefinitions = opt.ShowStepDefinitions
} }
defStopOnFailure := false defStopOnFailure := false
if opt.StopOnFailure { if opt.StopOnFailure {
defStopOnFailure = opt.StopOnFailure defStopOnFailure = opt.StopOnFailure
} }
defStrict := false defStrict := false
if opt.Strict { if opt.Strict {
defStrict = opt.Strict defStrict = opt.Strict
} }
defNoColors := false defNoColors := false
if opt.NoColors { if opt.NoColors {
defNoColors = opt.NoColors defNoColors = opt.NoColors
@ -198,12 +206,6 @@ type randomSeed struct {
ref *int64 ref *int64
} }
// Choose randomly assigns a convenient pseudo-random seed value.
// The resulting seed will be between `1-99999` for later ease of specification.
func makeRandomSeed() int64 {
return rand.New(rand.NewSource(time.Now().UTC().UnixNano())).Int63n(99998) + 1
}
func (rs *randomSeed) Set(s string) error { func (rs *randomSeed) Set(s string) error {
if s == "true" { if s == "true" {
*rs.ref = makeRandomSeed() *rs.ref = makeRandomSeed()

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

31
flags_v0110.go Обычный файл
Просмотреть файл

@ -0,0 +1,31 @@
package godog
import (
"errors"
"math/rand"
"time"
"github.com/spf13/pflag"
"github.com/cucumber/godog/internal/flags"
)
// Choose randomly assigns a convenient pseudo-random seed value.
// The resulting seed will be between `1-99999` for later ease of specification.
func makeRandomSeed() int64 {
return rand.New(rand.NewSource(time.Now().UTC().UnixNano())).Int63n(99998) + 1
}
func flagSet(opt *Options) *pflag.FlagSet {
set := pflag.NewFlagSet("godog", pflag.ExitOnError)
flags.BindRunCmdFlags("", set, opt)
pflag.ErrHelp = errors.New("godog: help requested")
return set
}
// BindCommandLineFlags binds godog flags to given flag set prefixed
// by given prefix, without overriding usage
func BindCommandLineFlags(prefix string, opts *Options) {
flagSet := pflag.CommandLine
flags.BindRunCmdFlags(prefix, flagSet, opts)
}

23
flags_v0110_test.go Обычный файл
Просмотреть файл

@ -0,0 +1,23 @@
package godog
import (
"testing"
"github.com/cucumber/godog/internal/flags"
"github.com/stretchr/testify/assert"
)
func Test_BindFlagsShouldRespectFlagDefaults(t *testing.T) {
opts := flags.Options{}
BindCommandLineFlags("flagDefaults.", &opts)
assert.Equal(t, "pretty", opts.Format)
assert.Equal(t, "", opts.Tags)
assert.Equal(t, 1, opts.Concurrency)
assert.False(t, opts.ShowStepDefinitions)
assert.False(t, opts.StopOnFailure)
assert.False(t, opts.Strict)
assert.False(t, opts.NoColors)
assert.Equal(t, int64(0), opts.Randomize)
}

2
go.mod
Просмотреть файл

@ -6,5 +6,7 @@ require (
github.com/cucumber/gherkin-go/v11 v11.0.0 github.com/cucumber/gherkin-go/v11 v11.0.0
github.com/cucumber/messages-go/v10 v10.0.3 github.com/cucumber/messages-go/v10 v10.0.3
github.com/hashicorp/go-memdb v1.2.1 github.com/hashicorp/go-memdb v1.2.1
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.3
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
) )

120
go.sum
Просмотреть файл

@ -1,4 +1,20 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/aslakhellesoy/gox v1.0.100/go.mod h1:AJl542QsKKG96COVsv0N74HHzVQgDIQPceVUh1aeU2M= github.com/aslakhellesoy/gox v1.0.100/go.mod h1:AJl542QsKKG96COVsv0N74HHzVQgDIQPceVUh1aeU2M=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cucumber/gherkin-go/v11 v11.0.0 h1:cwVwN1Qn2VRSfHZNLEh5x00tPBmZcjATBWDpxsR5Xug= github.com/cucumber/gherkin-go/v11 v11.0.0 h1:cwVwN1Qn2VRSfHZNLEh5x00tPBmZcjATBWDpxsR5Xug=
github.com/cucumber/gherkin-go/v11 v11.0.0/go.mod h1:CX33k2XU2qog4e+TFjOValoq6mIUq0DmVccZs238R9w= github.com/cucumber/gherkin-go/v11 v11.0.0/go.mod h1:CX33k2XU2qog4e+TFjOValoq6mIUq0DmVccZs238R9w=
@ -8,10 +24,31 @@ github.com/cucumber/messages-go/v10 v10.0.3/go.mod h1:9jMZ2Y8ZxjLY6TG2+x344nt5rX
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/go-immutable-radix v1.2.0 h1:l6UW37iCXwZkZoAbEYnptSHVE/cQ5bOTPYG5W3vf9+8= github.com/hashicorp/go-immutable-radix v1.2.0 h1:l6UW37iCXwZkZoAbEYnptSHVE/cQ5bOTPYG5W3vf9+8=
github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-memdb v1.2.1 h1:wI9btDjYUOJJHTCnRlAG/TkRyD/ij7meJMrLK9X31Cc= github.com/hashicorp/go-memdb v1.2.1 h1:wI9btDjYUOJJHTCnRlAG/TkRyD/ij7meJMrLK9X31Cc=
@ -22,8 +59,17 @@ github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -31,27 +77,101 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

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

@ -341,6 +341,7 @@ func buildTestMain(pkg *build.Package) ([]byte, error) {
} else { } else {
name = "main" name = "main"
} }
data := struct { data := struct {
Name string Name string
ImportPath string ImportPath string

42
internal/flags/flags.go Обычный файл
Просмотреть файл

@ -0,0 +1,42 @@
package flags
import (
"github.com/spf13/pflag"
)
// BindRunCmdFlags is an internal func to bind run subcommand flags.
func BindRunCmdFlags(prefix string, flagSet *pflag.FlagSet, opts *Options) {
if opts.Concurrency == 0 {
opts.Concurrency = 1
}
if opts.Format == "" {
opts.Format = "pretty"
}
flagSet.BoolVar(&opts.NoColors, prefix+"no-colors", opts.NoColors, "disable ansi colors")
flagSet.IntVarP(&opts.Concurrency, prefix+"concurrency", "c", opts.Concurrency, "run the test suite with concurrency")
flagSet.StringVarP(&opts.Tags, prefix+"tags", "t", opts.Tags, `filter scenarios by tags, expression can be:
- "@wip": run all scenarios with wip tag
- "~@wip": exclude all scenarios with wip tag
- "@wip && ~@new": run wip scenarios, but exclude new
- "@wip,@undone": run wip or undone scenarios`)
flagSet.StringVarP(&opts.Format, prefix+"format", "f", opts.Format, `writes the formatted output to stdout
built-in formatters:
- progress: prints a character per step
- cucumber: produces cucumber JSON format output
- events: produces JSON event stream, based on spec: 0.1.0
- junit: prints junit compatible xml to stdout
- pretty: prints every feature with runtime statuses
`)
flagSet.BoolVarP(&opts.ShowStepDefinitions, prefix+"definitions", "d", opts.ShowStepDefinitions, "print all available step definitions")
flagSet.BoolVar(&opts.StopOnFailure, prefix+"stop-on-failure", opts.StopOnFailure, "stop processing on first failed scenario")
flagSet.BoolVar(&opts.Strict, prefix+"strict", opts.Strict, "fail suite when there are pending or undefined steps")
flagSet.Int64Var(&opts.Randomize, prefix+"random", opts.Randomize, `randomly shuffle the scenario execution order
--random
specify SEED to reproduce the shuffling from a previous run
--random=5738`)
flagSet.Lookup(prefix + "random").NoOptDefVal = "-1"
}

64
internal/flags/flags_test.go Обычный файл
Просмотреть файл

@ -0,0 +1,64 @@
package flags_test
import (
"testing"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/cucumber/godog/internal/flags"
)
func Test_BindFlagsShouldRespectFlagDefaults(t *testing.T) {
opts := flags.Options{}
flagSet := pflag.FlagSet{}
flags.BindRunCmdFlags("optDefaults.", &flagSet, &opts)
flagSet.Parse([]string{})
assert.Equal(t, "pretty", opts.Format)
assert.Equal(t, "", opts.Tags)
assert.Equal(t, 1, opts.Concurrency)
assert.False(t, opts.ShowStepDefinitions)
assert.False(t, opts.StopOnFailure)
assert.False(t, opts.Strict)
assert.False(t, opts.NoColors)
assert.Equal(t, int64(0), opts.Randomize)
}
func Test_BindFlagsShouldRespectFlagOverrides(t *testing.T) {
opts := flags.Options{
Format: "progress",
Tags: "test",
Concurrency: 2,
ShowStepDefinitions: true,
StopOnFailure: true,
Strict: true,
NoColors: true,
Randomize: 11,
}
flagSet := pflag.FlagSet{}
flags.BindRunCmdFlags("optOverrides.", &flagSet, &opts)
flagSet.Parse([]string{
"--optOverrides.format=junit",
"--optOverrides.tags=test2",
"--optOverrides.concurrency=3",
"--optOverrides.definitions=false",
"--optOverrides.stop-on-failure=false",
"--optOverrides.strict=false",
"--optOverrides.no-colors=false",
"--optOverrides.random=2",
})
assert.Equal(t, "junit", opts.Format)
assert.Equal(t, "test2", opts.Tags)
assert.Equal(t, 3, opts.Concurrency)
assert.False(t, opts.ShowStepDefinitions)
assert.False(t, opts.StopOnFailure)
assert.False(t, opts.Strict)
assert.False(t, opts.NoColors)
assert.Equal(t, int64(2), opts.Randomize)
}

59
internal/flags/options.go Обычный файл
Просмотреть файл

@ -0,0 +1,59 @@
package flags
import (
"io"
)
// Options are suite run options
// flags are mapped to these options.
//
// It can also be used together with godog.RunWithOptions
// to run test suite from go source directly
//
// See the flags for more details
type Options struct {
// Print step definitions found and exit
ShowStepDefinitions bool
// Randomize, if not `0`, will be used to run scenarios in a random order.
//
// Randomizing scenario order is especially helpful for detecting
// situations where you have state leaking between scenarios, which can
// cause flickering or fragile tests.
//
// The default value of `0` means "do not randomize".
//
// The magic value of `-1` means "pick a random seed for me", and godog will
// assign a seed on it's own during the `RunWithOptions` phase, similar to if
// you specified `--random` on the command line.
//
// Any other value will be used as the random seed for shuffling. Re-using the
// same seed will allow you to reproduce the shuffle order of a previous run
// to isolate an error condition.
Randomize int64
// Stops on the first failure
StopOnFailure bool
// Fail suite when there are pending or undefined steps
Strict bool
// Forces ansi color stripping
NoColors bool
// Various filters for scenarios parsed
// from feature files
Tags string
// The formatter name
Format string
// Concurrency rate, not all formatters accepts this
Concurrency int
// All feature file paths
Paths []string
// Where it should print formatter output
Output io.Writer
}

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

@ -1,8 +1,6 @@
package godog package godog
import ( import "github.com/cucumber/godog/internal/flags"
"io"
)
// Options are suite run options // Options are suite run options
// flags are mapped to these options. // flags are mapped to these options.
@ -11,49 +9,4 @@ import (
// to run test suite from go source directly // to run test suite from go source directly
// //
// See the flags for more details // See the flags for more details
type Options struct { type Options = flags.Options
// Print step definitions found and exit
ShowStepDefinitions bool
// Randomize, if not `0`, will be used to run scenarios in a random order.
//
// Randomizing scenario order is especially helpful for detecting
// situations where you have state leaking between scenarios, which can
// cause flickering or fragile tests.
//
// The default value of `0` means "do not randomize".
//
// The magic value of `-1` means "pick a random seed for me", and godog will
// assign a seed on it's own during the `RunWithOptions` phase, similar to if
// you specified `--random` on the command line.
//
// Any other value will be used as the random seed for shuffling. Re-using the
// same seed will allow you to reproduce the shuffle order of a previous run
// to isolate an error condition.
Randomize int64
// Stops on the first failure
StopOnFailure bool
// Fail suite when there are pending or undefined steps
Strict bool
// Forces ansi color stripping
NoColors bool
// Various filters for scenarios parsed
// from feature files
Tags string
// The formatter name
Format string
// Concurrency rate, not all formatters accepts this
Concurrency int
// All feature file paths
Paths []string
// Where it should print formatter output
Output io.Writer
}

2
run.go
Просмотреть файл

@ -260,7 +260,7 @@ func (ts TestSuite) Run() int {
ts.Options = &Options{} ts.Options = &Options{}
ts.Options.Output = colors.Colored(os.Stdout) ts.Options.Output = colors.Colored(os.Stdout)
flagSet := FlagSet(ts.Options) flagSet := flagSet(ts.Options)
if err := flagSet.Parse(os.Args[1:]); err != nil { if err := flagSet.Parse(os.Args[1:]); err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
return exitOptionError return exitOptionError