Move genflags tool to cmd/ and pin to previous release
to alleviate problems caused by the circular dependency of using the same code as a library that is potentially being generated to adhere to a different API.
This commit is contained in:
21
cmd/urfave-cli-genflags/Makefile
Normal file
21
cmd/urfave-cli-genflags/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
GOTEST_FLAGS ?= -v --coverprofile main.coverprofile --covermode count --cover github.com/urfave/cli/v2/cmd/urfave-cli-genflags
|
||||
GOBUILD_FLAGS ?= -x
|
||||
|
||||
.PHONY: all
|
||||
all: test build smoke-test
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test $(GOTEST_FLAGS) ./...
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go build $(GOBUILD_FLAGS) ./...
|
||||
|
||||
.PHONY: smoke-test
|
||||
smoke-test: build
|
||||
./urfave-cli-genflags --help
|
||||
|
||||
.PHONY: show-cover
|
||||
show-cover:
|
||||
go tool cover -func main.coverprofile
|
15
cmd/urfave-cli-genflags/README.md
Normal file
15
cmd/urfave-cli-genflags/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# urfave-cli-genflags
|
||||
|
||||
This is a tool that is used internally by [urfave/cli] to generate
|
||||
flag types and methods from a YAML input. It intentionally pins
|
||||
usage of `github.com/urfave/cli/v2` to a *release* rather than
|
||||
using the adjacent code so that changes don't result in *this* tool
|
||||
refusing to compile. It's almost like dogfooding?
|
||||
|
||||
## support warning
|
||||
|
||||
This tool is maintained as a sub-project and is not covered by the
|
||||
API and backward compatibility guaranteed by releases of
|
||||
[urfave/cli].
|
||||
|
||||
[urfave/cli]: https://github.com/urfave/cli
|
95
cmd/urfave-cli-genflags/generated.gotmpl
Normal file
95
cmd/urfave-cli-genflags/generated.gotmpl
Normal file
@@ -0,0 +1,95 @@
|
||||
// WARNING: this file is generated. DO NOT EDIT
|
||||
|
||||
package {{.PackageName}}
|
||||
|
||||
{{range .SortedFlagTypes}}
|
||||
// {{.TypeName}} is a flag with type {{if .ValuePointer}}*{{end}}{{.GoType}}
|
||||
type {{.TypeName}} struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value {{if .ValuePointer}}*{{end}}{{.GoType}}
|
||||
Destination *{{.GoType}}
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
{{range .StructFields}}
|
||||
{{.Name}} {{.Type}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
{{if .GenerateFmtStringerInterface}}
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *{{.TypeName}}) String() string {
|
||||
return {{$.UrfaveCLINamespace}}FlagStringer(f)
|
||||
}
|
||||
{{end}}{{/* /if .GenerateFmtStringerInterface */}}
|
||||
|
||||
{{if .GenerateFlagInterface}}
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *{{.TypeName}}) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *{{.TypeName}}) Names() []string {
|
||||
return {{$.UrfaveCLINamespace}}FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *{{.TypeName}}) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *{{.TypeName}}) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// GetCategory returns the category of the flag
|
||||
func (f *{{.TypeName}}) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *{{.TypeName}}) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *{{.TypeName}}) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
func (f *{{.TypeName}}) TakesValue() bool {
|
||||
return "{{.TypeName }}" != "BoolFlag"
|
||||
}
|
||||
|
||||
{{if .GenerateDefaultText}}
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *{{.TypeName}}) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{end}}{{/* /if .GenerateFlagInterface */}}
|
||||
|
||||
{{end}}{{/* /range .SortedFlagTypes */}}
|
||||
|
||||
// vim{{/* 👻 */}}:ro
|
||||
{{/*
|
||||
vim:filetype=gotexttmpl
|
||||
*/}}
|
42
cmd/urfave-cli-genflags/generated_test.gotmpl
Normal file
42
cmd/urfave-cli-genflags/generated_test.gotmpl
Normal file
@@ -0,0 +1,42 @@
|
||||
// WARNING: this file is generated. DO NOT EDIT
|
||||
|
||||
package {{.TestPackageName}}
|
||||
|
||||
{{range .SortedFlagTypes}}
|
||||
{{if .GenerateFlagInterface}}
|
||||
func Test{{.TypeName}}_SatisfiesFlagInterface(t *testing.T) {
|
||||
var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
|
||||
|
||||
_ = f.IsSet()
|
||||
_ = f.Names()
|
||||
}
|
||||
|
||||
func Test{{.TypeName}}_SatisfiesRequiredFlagInterface(t *testing.T) {
|
||||
var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
|
||||
|
||||
_ = f.IsRequired()
|
||||
}
|
||||
|
||||
func Test{{.TypeName}}_SatisfiesVisibleFlagInterface(t *testing.T) {
|
||||
var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
|
||||
|
||||
_ = f.IsVisible()
|
||||
}
|
||||
|
||||
{{end}}
|
||||
|
||||
{{if .GenerateFmtStringerInterface}}
|
||||
func Test{{.TypeName}}_SatisfiesFmtStringerInterface(t *testing.T) {
|
||||
var f fmt.Stringer = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
|
||||
|
||||
_ = f.String()
|
||||
}
|
||||
{{end}}
|
||||
|
||||
|
||||
{{end}}
|
||||
|
||||
// vim{{/* 👻 */}}:ro
|
||||
{{/*
|
||||
vim:filetype=gotexttmpl
|
||||
*/}}
|
15
cmd/urfave-cli-genflags/go.mod
Normal file
15
cmd/urfave-cli-genflags/go.mod
Normal file
@@ -0,0 +1,15 @@
|
||||
module github.com/urfave/cli/v2/cmd/urfave-cli-genflags
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/urfave/cli/v2 v2.11.2
|
||||
golang.org/x/text v0.3.7
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
)
|
14
cmd/urfave-cli-genflags/go.sum
Normal file
14
cmd/urfave-cli-genflags/go.sum
Normal file
@@ -0,0 +1,14 @@
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/urfave/cli/v2 v2.11.2 h1:FVfNg4m3vbjbBpLYxW//WjxUoHvJ9TlppXcqY9Q9ZfA=
|
||||
github.com/urfave/cli/v2 v2.11.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
292
cmd/urfave-cli-genflags/main.go
Normal file
292
cmd/urfave-cli-genflags/main.go
Normal file
@@ -0,0 +1,292 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
_ "embed"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"syscall"
|
||||
"text/template"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultPackageName = "cli"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed generated.gotmpl
|
||||
TemplateString string
|
||||
|
||||
//go:embed generated_test.gotmpl
|
||||
TestTemplateString string
|
||||
|
||||
titler = cases.Title(language.Und, cases.NoLower)
|
||||
)
|
||||
|
||||
func sh(ctx context.Context, exe string, args ...string) (string, error) {
|
||||
cmd := exec.CommandContext(ctx, exe, args...)
|
||||
cmd.Stderr = os.Stderr
|
||||
outBytes, err := cmd.Output()
|
||||
return string(outBytes), err
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
top := "../../"
|
||||
if v, err := sh(ctx, "git", "rev-parse", "--show-toplevel"); err == nil {
|
||||
top = strings.TrimSpace(v)
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
Name: "genflags",
|
||||
Usage: "Generate flag types for urfave/cli",
|
||||
Flags: []cli.Flag{
|
||||
&cli.PathFlag{
|
||||
Name: "flag-spec-yaml",
|
||||
Aliases: []string{"f"},
|
||||
Value: filepath.Join(top, "flag-spec.yaml"),
|
||||
},
|
||||
&cli.PathFlag{
|
||||
Name: "generated-output",
|
||||
Aliases: []string{"o"},
|
||||
Value: filepath.Join(top, "zz_generated.flags.go"),
|
||||
},
|
||||
&cli.PathFlag{
|
||||
Name: "generated-test-output",
|
||||
Aliases: []string{"t"},
|
||||
Value: filepath.Join(top, "zz_generated.flags_test.go"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "generated-package-name",
|
||||
Aliases: []string{"p"},
|
||||
Value: defaultPackageName,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "generated-test-package-name",
|
||||
Aliases: []string{"T"},
|
||||
Value: defaultPackageName + "_test",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "urfave-cli-namespace",
|
||||
Aliases: []string{"n"},
|
||||
Value: "",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "urfave-cli-test-namespace",
|
||||
Aliases: []string{"N"},
|
||||
Value: "cli.",
|
||||
},
|
||||
},
|
||||
Action: runGenFlags,
|
||||
}
|
||||
|
||||
if err := app.RunContext(ctx, os.Args); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func runGenFlags(cCtx *cli.Context) error {
|
||||
specBytes, err := os.ReadFile(cCtx.Path("flag-spec-yaml"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
spec := &Spec{}
|
||||
if err := yaml.Unmarshal(specBytes, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cCtx.IsSet("generated-package-name") {
|
||||
spec.PackageName = strings.TrimSpace(cCtx.String("generated-package-name"))
|
||||
}
|
||||
|
||||
if strings.TrimSpace(spec.PackageName) == "" {
|
||||
spec.PackageName = defaultPackageName
|
||||
}
|
||||
|
||||
if cCtx.IsSet("generated-test-package-name") {
|
||||
spec.TestPackageName = strings.TrimSpace(cCtx.String("generated-test-package-name"))
|
||||
}
|
||||
|
||||
if strings.TrimSpace(spec.TestPackageName) == "" {
|
||||
spec.TestPackageName = defaultPackageName + "_test"
|
||||
}
|
||||
|
||||
if cCtx.IsSet("urfave-cli-namespace") {
|
||||
spec.UrfaveCLINamespace = strings.TrimSpace(cCtx.String("urfave-cli-namespace"))
|
||||
}
|
||||
|
||||
if cCtx.IsSet("urfave-cli-test-namespace") {
|
||||
spec.UrfaveCLITestNamespace = strings.TrimSpace(cCtx.String("urfave-cli-test-namespace"))
|
||||
} else {
|
||||
spec.UrfaveCLITestNamespace = "cli."
|
||||
}
|
||||
|
||||
genTmpl, err := template.New("gen").Parse(TemplateString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genTestTmpl, err := template.New("gen_test").Parse(TestTemplateString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genBuf := &bytes.Buffer{}
|
||||
if err := genTmpl.Execute(genBuf, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genTestBuf := &bytes.Buffer{}
|
||||
if err := genTestTmpl.Execute(genTestBuf, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(cCtx.Path("generated-output"), genBuf.Bytes(), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(cCtx.Path("generated-test-output"), genTestBuf.Bytes(), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sh(cCtx.Context, "goimports", "-w", cCtx.Path("generated-output")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sh(cCtx.Context, "goimports", "-w", cCtx.Path("generated-test-output")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TypeName(goType string, fc *FlagTypeConfig) string {
|
||||
if fc != nil && strings.TrimSpace(fc.TypeName) != "" {
|
||||
return strings.TrimSpace(fc.TypeName)
|
||||
}
|
||||
|
||||
dotSplit := strings.Split(goType, ".")
|
||||
goType = dotSplit[len(dotSplit)-1]
|
||||
|
||||
if strings.HasPrefix(goType, "[]") {
|
||||
return titler.String(strings.TrimPrefix(goType, "[]")) + "SliceFlag"
|
||||
}
|
||||
|
||||
return titler.String(goType) + "Flag"
|
||||
}
|
||||
|
||||
type Spec struct {
|
||||
FlagTypes map[string]*FlagTypeConfig `yaml:"flag_types"`
|
||||
PackageName string `yaml:"package_name"`
|
||||
TestPackageName string `yaml:"test_package_name"`
|
||||
UrfaveCLINamespace string `yaml:"urfave_cli_namespace"`
|
||||
UrfaveCLITestNamespace string `yaml:"urfave_cli_test_namespace"`
|
||||
}
|
||||
|
||||
func (gfs *Spec) SortedFlagTypes() []*FlagType {
|
||||
typeNames := []string{}
|
||||
|
||||
for name := range gfs.FlagTypes {
|
||||
if strings.HasPrefix(name, "[]") {
|
||||
name = strings.TrimPrefix(name, "[]") + "Slice"
|
||||
}
|
||||
|
||||
typeNames = append(typeNames, name)
|
||||
}
|
||||
|
||||
sort.Strings(typeNames)
|
||||
|
||||
ret := make([]*FlagType, len(typeNames))
|
||||
|
||||
for i, typeName := range typeNames {
|
||||
ret[i] = &FlagType{
|
||||
GoType: typeName,
|
||||
Config: gfs.FlagTypes[typeName],
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
type FlagTypeConfig struct {
|
||||
SkipInterfaces []string `yaml:"skip_interfaces"`
|
||||
StructFields []*FlagStructField `yaml:"struct_fields"`
|
||||
TypeName string `yaml:"type_name"`
|
||||
ValuePointer bool `yaml:"value_pointer"`
|
||||
}
|
||||
|
||||
type FlagStructField struct {
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
type FlagType struct {
|
||||
GoType string
|
||||
Config *FlagTypeConfig
|
||||
}
|
||||
|
||||
func (ft *FlagType) StructFields() []*FlagStructField {
|
||||
if ft.Config == nil || ft.Config.StructFields == nil {
|
||||
return []*FlagStructField{}
|
||||
}
|
||||
|
||||
return ft.Config.StructFields
|
||||
}
|
||||
|
||||
func (ft *FlagType) ValuePointer() bool {
|
||||
if ft.Config == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return ft.Config.ValuePointer
|
||||
}
|
||||
|
||||
func (ft *FlagType) TypeName() string {
|
||||
return TypeName(ft.GoType, ft.Config)
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateFmtStringerInterface() bool {
|
||||
return ft.skipInterfaceNamed("fmt.Stringer")
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateFlagInterface() bool {
|
||||
return ft.skipInterfaceNamed("Flag")
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateRequiredFlagInterface() bool {
|
||||
return ft.skipInterfaceNamed("RequiredFlag")
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateVisibleFlagInterface() bool {
|
||||
return ft.skipInterfaceNamed("VisibleFlag")
|
||||
}
|
||||
|
||||
func (ft *FlagType) skipInterfaceNamed(name string) bool {
|
||||
if ft.Config == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
lowName := strings.ToLower(name)
|
||||
|
||||
for _, interfaceName := range ft.Config.SkipInterfaces {
|
||||
if strings.ToLower(interfaceName) == lowName {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
146
cmd/urfave-cli-genflags/main_test.go
Normal file
146
cmd/urfave-cli-genflags/main_test.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package main_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
main "github.com/urfave/cli/v2/cmd/urfave-cli-genflags"
|
||||
)
|
||||
|
||||
func TestTypeName(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
gt string
|
||||
fc *main.FlagTypeConfig
|
||||
expected string
|
||||
}{
|
||||
{gt: "int", fc: nil, expected: "IntFlag"},
|
||||
{gt: "int", fc: &main.FlagTypeConfig{}, expected: "IntFlag"},
|
||||
{gt: "int", fc: &main.FlagTypeConfig{TypeName: "VeryIntyFlag"}, expected: "VeryIntyFlag"},
|
||||
{gt: "[]bool", fc: nil, expected: "BoolSliceFlag"},
|
||||
{gt: "[]bool", fc: &main.FlagTypeConfig{}, expected: "BoolSliceFlag"},
|
||||
{gt: "[]bool", fc: &main.FlagTypeConfig{TypeName: "ManyTruthsFlag"}, expected: "ManyTruthsFlag"},
|
||||
{gt: "time.Rumination", fc: nil, expected: "RuminationFlag"},
|
||||
{gt: "time.Rumination", fc: &main.FlagTypeConfig{}, expected: "RuminationFlag"},
|
||||
{gt: "time.Rumination", fc: &main.FlagTypeConfig{TypeName: "PonderFlag"}, expected: "PonderFlag"},
|
||||
} {
|
||||
t.Run(
|
||||
fmt.Sprintf("type=%s,cfg=%v", tc.gt, func() string {
|
||||
if tc.fc != nil {
|
||||
return tc.fc.TypeName
|
||||
}
|
||||
return "nil"
|
||||
}()),
|
||||
func(ct *testing.T) {
|
||||
actual := main.TypeName(tc.gt, tc.fc)
|
||||
if tc.expected != actual {
|
||||
ct.Errorf("expected %q, got %q", tc.expected, actual)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpec_SortedFlagTypes(t *testing.T) {
|
||||
spec := &main.Spec{
|
||||
FlagTypes: map[string]*main.FlagTypeConfig{
|
||||
"nerf": &main.FlagTypeConfig{},
|
||||
"gerf": nil,
|
||||
},
|
||||
}
|
||||
|
||||
actual := spec.SortedFlagTypes()
|
||||
expected := []*main.FlagType{
|
||||
{
|
||||
GoType: "gerf",
|
||||
Config: nil,
|
||||
},
|
||||
{
|
||||
GoType: "nerf",
|
||||
Config: &main.FlagTypeConfig{},
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Errorf("expected %#v, got %#v", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func genFlagType() *main.FlagType {
|
||||
return &main.FlagType{
|
||||
GoType: "blerf",
|
||||
Config: &main.FlagTypeConfig{
|
||||
SkipInterfaces: []string{"fmt.Stringer"},
|
||||
StructFields: []*main.FlagStructField{
|
||||
{
|
||||
Name: "Foibles",
|
||||
Type: "int",
|
||||
},
|
||||
{
|
||||
Name: "Hoopled",
|
||||
Type: "bool",
|
||||
},
|
||||
},
|
||||
TypeName: "YeOldeBlerfFlag",
|
||||
ValuePointer: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_StructFields(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
sf := ft.StructFields()
|
||||
if 2 != len(sf) {
|
||||
t.Errorf("expected 2 struct fields, got %v", len(sf))
|
||||
return
|
||||
}
|
||||
|
||||
if "Foibles" != sf[0].Name {
|
||||
t.Errorf("expected struct field order to be retained")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_ValuePointer(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
if !ft.ValuePointer() {
|
||||
t.Errorf("expected ValuePointer to be true")
|
||||
return
|
||||
}
|
||||
|
||||
ft.Config = nil
|
||||
|
||||
if ft.ValuePointer() {
|
||||
t.Errorf("expected ValuePointer to be false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_GenerateFmtStringerInterface(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
if ft.GenerateFmtStringerInterface() {
|
||||
t.Errorf("expected GenerateFmtStringerInterface to be false")
|
||||
return
|
||||
}
|
||||
|
||||
ft.Config = nil
|
||||
|
||||
if !ft.GenerateFmtStringerInterface() {
|
||||
t.Errorf("expected GenerateFmtStringerInterface to be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_GenerateFlagInterface(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
if !ft.GenerateFlagInterface() {
|
||||
t.Errorf("expected GenerateFlagInterface to be true")
|
||||
return
|
||||
}
|
||||
|
||||
ft.Config = nil
|
||||
|
||||
if !ft.GenerateFlagInterface() {
|
||||
t.Errorf("expected GenerateFlagInterface to be true")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user